Merge mac80211 driver from tree at bu3sch.de, pulled 24/6
[librecmc/librecmc.git] / package / mac80211 / src / 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
31 static int ieee80211_ioctl_set_beacon(struct net_device *dev,
32                                       struct prism2_hostapd_param *param,
33                                       int param_len,
34                                       int flag)
35 {
36         struct ieee80211_sub_if_data *sdata;
37         struct ieee80211_if_ap *ap;
38         u8 **b_head, **b_tail;
39         int *b_head_len, *b_tail_len;
40         int len;
41
42         len = ((char *) param->u.beacon.data - (char *) param) +
43                 param->u.beacon.head_len + param->u.beacon.tail_len;
44
45         if (param_len > len)
46                 param_len = len;
47         else if (param_len != len)
48                 return -EINVAL;
49
50         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
51         if (sdata->type != IEEE80211_IF_TYPE_AP)
52                 return -EINVAL;
53         ap = &sdata->u.ap;
54
55         switch (flag) {
56         case 0:
57                 b_head = &ap->beacon_head;
58                 b_tail = &ap->beacon_tail;
59                 b_head_len = &ap->beacon_head_len;
60                 b_tail_len = &ap->beacon_tail_len;
61                 break;
62         default:
63                 printk(KERN_DEBUG "%s: unknown beacon flag %d\n",
64                        dev->name, flag);
65                 return -EINVAL;
66         }
67
68         kfree(*b_head);
69         kfree(*b_tail);
70         *b_head = NULL;
71         *b_tail = NULL;
72
73         *b_head_len = param->u.beacon.head_len;
74         *b_tail_len = param->u.beacon.tail_len;
75
76         *b_head = kmalloc(*b_head_len, GFP_KERNEL);
77         if (*b_head)
78                 memcpy(*b_head, param->u.beacon.data, *b_head_len);
79         else {
80                 printk(KERN_DEBUG "%s: failed to allocate beacon_head\n",
81                        dev->name);
82                 return -ENOMEM;
83         }
84
85         if (*b_tail_len > 0) {
86                 *b_tail = kmalloc(*b_tail_len, GFP_KERNEL);
87                 if (*b_tail)
88                         memcpy(*b_tail, param->u.beacon.data + (*b_head_len),
89                                (*b_tail_len));
90                 else {
91                         printk(KERN_DEBUG "%s: failed to allocate "
92                                "beacon_tail\n", dev->name);
93                         return -ENOMEM;
94                 }
95         }
96
97         return ieee80211_if_config_beacon(dev);
98 }
99
100
101 static int ieee80211_ioctl_get_hw_features(struct net_device *dev,
102                                            struct prism2_hostapd_param *param,
103                                            int param_len)
104 {
105         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
106         u8 *pos = param->u.hw_features.data;
107         int left = param_len - (pos - (u8 *) param);
108         int i;
109         struct hostapd_ioctl_hw_modes_hdr *hdr;
110         struct ieee80211_rate_data *rate;
111         struct ieee80211_channel_data *chan;
112         struct ieee80211_hw_mode *mode;
113
114         param->u.hw_features.flags = 0;
115         if (local->hw.flags & IEEE80211_HW_DATA_NULLFUNC_ACK)
116                 param->u.hw_features.flags |= HOSTAP_HW_FLAG_NULLFUNC_OK;
117
118         param->u.hw_features.num_modes = 0;
119         list_for_each_entry(mode, &local->modes_list, list) {
120                 int clen, rlen;
121
122                 param->u.hw_features.num_modes++;
123                 clen = mode->num_channels * sizeof(struct ieee80211_channel_data);
124                 rlen = mode->num_rates * sizeof(struct ieee80211_rate_data);
125                 if (left < sizeof(*hdr) + clen + rlen)
126                         return -E2BIG;
127                 left -= sizeof(*hdr) + clen + rlen;
128
129                 hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos;
130                 hdr->mode = mode->mode;
131                 hdr->num_channels = mode->num_channels;
132                 hdr->num_rates = mode->num_rates;
133
134                 pos = (u8 *) (hdr + 1);
135                 chan = (struct ieee80211_channel_data *) pos;
136                 for (i = 0; i < mode->num_channels; i++) {
137                         chan[i].chan = mode->channels[i].chan;
138                         chan[i].freq = mode->channels[i].freq;
139                         chan[i].flag = mode->channels[i].flag;
140                 }
141                 pos += clen;
142
143                 rate = (struct ieee80211_rate_data *) pos;
144                 for (i = 0; i < mode->num_rates; i++) {
145                         rate[i].rate = mode->rates[i].rate;
146                         rate[i].flags = mode->rates[i].flags;
147                 }
148                 pos += rlen;
149         }
150
151         return 0;
152 }
153
154 static int ieee80211_ioctl_flush(struct net_device *dev,
155                                  struct prism2_hostapd_param *param)
156 {
157         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
158         sta_info_flush(local, NULL);
159         return 0;
160 }
161
162
163 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
164 struct iapp_layer2_update {
165         u8 da[ETH_ALEN]; /* broadcast */
166         u8 sa[ETH_ALEN]; /* STA addr */
167         __be16 len; /* 6 */
168         u8 dsap; /* 0 */
169         u8 ssap; /* 0 */
170         u8 control;
171         u8 xid_info[3];
172 } __attribute__ ((packed));
173
174 static void ieee80211_send_layer2_update(struct net_device *dev,
175                                          const u8 *addr)
176 {
177         struct iapp_layer2_update *msg;
178         struct sk_buff *skb;
179
180         /* Send Level 2 Update Frame to update forwarding tables in layer 2
181          * bridge devices */
182
183         skb = dev_alloc_skb(sizeof(*msg));
184         if (!skb)
185                 return;
186         msg = (struct iapp_layer2_update *) skb_put(skb, sizeof(*msg));
187
188         /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
189          * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
190
191         memset(msg->da, 0xff, ETH_ALEN);
192         memcpy(msg->sa, addr, ETH_ALEN);
193         msg->len = htons(6);
194         msg->dsap = 0;
195         msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
196         msg->control = 0xaf; /* XID response lsb.1111F101.
197                               * F=0 (no poll command; unsolicited frame) */
198         msg->xid_info[0] = 0x81; /* XID format identifier */
199         msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
200         msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
201
202         skb->dev = dev;
203         skb->protocol = eth_type_trans(skb, dev);
204         memset(skb->cb, 0, sizeof(skb->cb));
205         netif_rx(skb);
206 }
207
208
209 static int ieee80211_ioctl_add_sta(struct net_device *dev,
210                                    struct prism2_hostapd_param *param)
211 {
212         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
213         struct sta_info *sta;
214         u32 rates;
215         int i, j;
216         struct ieee80211_sub_if_data *sdata;
217         struct ieee80211_hw_mode *mode;
218         int add_key_entry = 1;
219
220         /* Prevent a race with changing the rate control algorithm */
221         if (!netif_running(dev))
222                 return -ENETDOWN;
223
224         sta = sta_info_get(local, param->sta_addr);
225
226         if (!sta) {
227                 sta = sta_info_add(local, dev, param->sta_addr, GFP_KERNEL);
228                 if (!sta)
229                         return -ENOMEM;
230         }
231
232         if (sta->dev != dev) {
233                 /* Binding STA to a new interface, so remove all references to
234                  * the old BSS. */
235                 spin_lock_bh(&local->sta_lock);
236                 sta_info_remove_aid_ptr(sta);
237                 spin_unlock_bh(&local->sta_lock);
238         }
239
240         /* TODO
241          * We "steal" the device in case someone owns it
242          * This will hurt WDS links and such when we have a
243          * WDS link and a client associating from the same station
244          */
245         sta->dev = dev;
246         sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
247
248         sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
249         sta->aid = param->u.add_sta.aid;
250         if (sta->aid > IEEE80211_MAX_AID)
251                 sta->aid = 0;
252         sta->listen_interval = param->u.add_sta.listen_interval;
253
254         rates = 0;
255         mode = local->oper_hw_mode;
256         for (i = 0; i < sizeof(param->u.add_sta.supp_rates); i++) {
257                 int rate = (param->u.add_sta.supp_rates[i] & 0x7f) * 5;
258                 if (mode->mode == MODE_ATHEROS_TURBO ||
259                     mode->mode == MODE_ATHEROS_TURBOG)
260                         rate *= 2;
261                 for (j = 0; j < mode->num_rates; j++) {
262                         if (mode->rates[j].rate == rate)
263                                 rates |= BIT(j);
264                 }
265
266         }
267         sta->supp_rates = rates;
268
269         rate_control_rate_init(sta, local);
270
271         if (param->u.add_sta.wds_flags & 0x01)
272                 sta->flags |= WLAN_STA_WDS;
273         else
274                 sta->flags &= ~WLAN_STA_WDS;
275
276         if (add_key_entry && !sta->key && !sdata->default_key &&
277             local->ops->set_key) {
278                 struct ieee80211_key_conf conf;
279                 /* Add key cache entry with NULL key type because this may used
280                  * for TX filtering. */
281                 memset(&conf, 0, sizeof(conf));
282                 conf.hw_key_idx = HW_KEY_IDX_INVALID;
283                 conf.alg = ALG_NULL;
284                 conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
285                 if (local->ops->set_key(local_to_hw(local), SET_KEY,
286                                        sta->addr, &conf, sta->aid)) {
287                         sta->key_idx_compression = HW_KEY_IDX_INVALID;
288                 } else {
289                         sta->key_idx_compression = conf.hw_key_idx;
290                 }
291         }
292
293         sta_info_put(sta);
294
295         if (sdata->type == IEEE80211_IF_TYPE_AP ||
296             sdata->type == IEEE80211_IF_TYPE_VLAN)
297                 ieee80211_send_layer2_update(dev, param->sta_addr);
298
299         return 0;
300 }
301
302
303 static int ieee80211_ioctl_remove_sta(struct net_device *dev,
304                                       struct prism2_hostapd_param *param)
305 {
306         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
307         struct sta_info *sta;
308
309         sta = sta_info_get(local, param->sta_addr);
310         if (sta) {
311                 sta_info_put(sta);
312                 sta_info_free(sta, 0);
313         }
314
315         return sta ? 0 : -ENOENT;
316 }
317
318
319 static int ieee80211_ioctl_get_dot11counterstable(struct net_device *dev,
320                                         struct prism2_hostapd_param *param)
321 {
322         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
323         struct ieee80211_low_level_stats stats;
324
325         memset(&stats, 0, sizeof(stats));
326         if (local->ops->get_stats)
327                 local->ops->get_stats(local_to_hw(local), &stats);
328         param->u.dot11CountersTable.dot11TransmittedFragmentCount =
329                 local->dot11TransmittedFragmentCount;
330         param->u.dot11CountersTable.dot11MulticastTransmittedFrameCount =
331                 local->dot11MulticastTransmittedFrameCount;
332         param->u.dot11CountersTable.dot11ReceivedFragmentCount =
333                 local->dot11ReceivedFragmentCount;
334         param->u.dot11CountersTable.dot11MulticastReceivedFrameCount =
335                 local->dot11MulticastReceivedFrameCount;
336         param->u.dot11CountersTable.dot11TransmittedFrameCount =
337                 local->dot11TransmittedFrameCount;
338         param->u.dot11CountersTable.dot11FCSErrorCount =
339                 stats.dot11FCSErrorCount;
340         param->u.dot11CountersTable.dot11ACKFailureCount =
341                 stats.dot11ACKFailureCount;
342         param->u.dot11CountersTable.dot11RTSFailureCount =
343                 stats.dot11RTSFailureCount;
344         param->u.dot11CountersTable.dot11RTSSuccessCount =
345                 stats.dot11RTSSuccessCount;
346
347         return 0;
348 }
349
350
351 static int ieee80211_ioctl_get_info_sta(struct net_device *dev,
352                                         struct prism2_hostapd_param *param)
353 {
354         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
355         struct ieee80211_hw_mode *mode;
356         struct sta_info *sta;
357
358         if (is_broadcast_ether_addr(param->sta_addr)) {
359                 struct net_device_stats *stats;
360
361                 stats = ieee80211_dev_stats(local->mdev);
362                 param->u.get_info_sta.rx_bytes = stats->rx_bytes;
363                 param->u.get_info_sta.tx_bytes = stats->tx_bytes;
364                 /* go through all STAs and get STA with lowest max. rate */
365                 param->u.get_info_sta.current_tx_rate =
366                         sta_info_min_txrate_get(local);
367                 return 0;
368         }
369
370         sta = sta_info_get(local, param->sta_addr);
371
372         if (!sta)
373                 return -ENOENT;
374
375         param->u.get_info_sta.inactive_msec =
376                 jiffies_to_msecs(jiffies - sta->last_rx);
377         param->u.get_info_sta.rx_packets = sta->rx_packets;
378         param->u.get_info_sta.tx_packets = sta->tx_packets;
379         param->u.get_info_sta.rx_bytes = sta->rx_bytes;
380         param->u.get_info_sta.tx_bytes = sta->tx_bytes;
381         param->u.get_info_sta.channel_use = sta->channel_use;
382         param->u.get_info_sta.flags = sta->flags;
383         mode = local->oper_hw_mode;
384         if (sta->txrate >= 0 && sta->txrate < mode->num_rates)
385                 param->u.get_info_sta.current_tx_rate =
386                         mode->rates[sta->txrate].rate;
387         param->u.get_info_sta.num_ps_buf_frames =
388                 skb_queue_len(&sta->ps_tx_buf);
389         param->u.get_info_sta.tx_retry_failed = sta->tx_retry_failed;
390         param->u.get_info_sta.tx_retry_count = sta->tx_retry_count;
391         param->u.get_info_sta.last_rssi = sta->last_rssi;
392         param->u.get_info_sta.last_ack_rssi = sta->last_ack_rssi[2];
393
394         sta_info_put(sta);
395
396         return 0;
397 }
398
399
400 static int ieee80211_ioctl_set_flags_sta(struct net_device *dev,
401                                          struct prism2_hostapd_param *param)
402 {
403         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
404         struct sta_info *sta;
405
406         sta = sta_info_get(local, param->sta_addr);
407         if (sta) {
408                 sta->flags |= param->u.set_flags_sta.flags_or;
409                 sta->flags &= param->u.set_flags_sta.flags_and;
410                 if (local->ops->set_port_auth &&
411                     (param->u.set_flags_sta.flags_or & WLAN_STA_AUTHORIZED) &&
412                     local->ops->set_port_auth(local_to_hw(local), sta->addr, 1))
413                         printk(KERN_DEBUG "%s: failed to set low-level driver "
414                                "PAE state (authorized) for " MAC_FMT "\n",
415                                dev->name, MAC_ARG(sta->addr));
416                 if (local->ops->set_port_auth &&
417                     !(param->u.set_flags_sta.flags_and & WLAN_STA_AUTHORIZED) &&
418                     local->ops->set_port_auth(local_to_hw(local), sta->addr, 0))
419                         printk(KERN_DEBUG "%s: failed to set low-level driver "
420                                "PAE state (unauthorized) for " MAC_FMT "\n",
421                                dev->name, MAC_ARG(sta->addr));
422                 sta_info_put(sta);
423         }
424
425         return sta ? 0 : -ENOENT;
426 }
427
428
429 int ieee80211_set_hw_encryption(struct net_device *dev,
430                                 struct sta_info *sta, u8 addr[ETH_ALEN],
431                                 struct ieee80211_key *key)
432 {
433         struct ieee80211_key_conf *keyconf = NULL;
434         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
435         int rc = 0;
436
437         /* default to sw encryption; this will be cleared by low-level
438          * driver if the hw supports requested encryption */
439         if (key)
440                 key->force_sw_encrypt = 1;
441
442         if (key && local->ops->set_key &&
443             (keyconf = ieee80211_key_data2conf(local, key))) {
444                 if (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
445                                        keyconf, sta ? sta->aid : 0)) {
446                         rc = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
447                         key->force_sw_encrypt = 1;
448                         key->hw_key_idx = HW_KEY_IDX_INVALID;
449                 } else {
450                         key->force_sw_encrypt =
451                                 !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
452                         key->hw_key_idx =
453                                 keyconf->hw_key_idx;
454
455                 }
456         }
457         kfree(keyconf);
458
459         return rc;
460 }
461
462
463 static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
464                                     int idx, int alg, int set_tx_key, u32 *err,
465                                     const u8 *_key, size_t key_len)
466 {
467         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
468         int ret = 0;
469         struct sta_info *sta;
470         struct ieee80211_key *key, *old_key;
471         int try_hwaccel = 1;
472         struct ieee80211_key_conf *keyconf;
473         struct ieee80211_sub_if_data *sdata;
474
475         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
476
477         if (is_broadcast_ether_addr(sta_addr)) {
478                 sta = NULL;
479                 if (idx >= NUM_DEFAULT_KEYS) {
480                         printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
481                                dev->name, idx);
482                         return -EINVAL;
483                 }
484                 key = sdata->keys[idx];
485
486                 /* TODO: consider adding hwaccel support for these; at least
487                  * Atheros key cache should be able to handle this since AP is
488                  * only transmitting frames with default keys. */
489                 /* FIX: hw key cache can be used when only one virtual
490                  * STA is associated with each AP. If more than one STA
491                  * is associated to the same AP, software encryption
492                  * must be used. This should be done automatically
493                  * based on configured station devices. For the time
494                  * being, this can be only set at compile time. */
495         } else {
496                 set_tx_key = 0;
497                 if (idx != 0) {
498                         printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for "
499                                "individual key\n", dev->name);
500                         return -EINVAL;
501                 }
502
503                 sta = sta_info_get(local, sta_addr);
504                 if (!sta) {
505                         if (err)
506                                 *err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
507 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
508                         printk(KERN_DEBUG "%s: set_encrypt - unknown addr "
509                                MAC_FMT "\n",
510                                dev->name, MAC_ARG(sta_addr));
511 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
512
513                         return -ENOENT;
514                 }
515
516                 key = sta->key;
517         }
518
519         /* FIX:
520          * Cannot configure default hwaccel keys with WEP algorithm, if
521          * any of the virtual interfaces is using static WEP
522          * configuration because hwaccel would otherwise try to decrypt
523          * these frames.
524          *
525          * For now, just disable WEP hwaccel for broadcast when there is
526          * possibility of conflict with default keys. This can maybe later be
527          * optimized by using non-default keys (at least with Atheros ar521x).
528          */
529         if (!sta && alg == ALG_WEP && !local->default_wep_only &&
530             sdata->type != IEEE80211_IF_TYPE_IBSS &&
531             sdata->type != IEEE80211_IF_TYPE_AP) {
532                 try_hwaccel = 0;
533         }
534
535         if (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) {
536                 /* Software encryption cannot be used with devices that hide
537                  * encryption from the host system, so always try to use
538                  * hardware acceleration with such devices. */
539                 try_hwaccel = 1;
540         }
541
542         if ((local->hw.flags & IEEE80211_HW_NO_TKIP_WMM_HWACCEL) &&
543             alg == ALG_TKIP) {
544                 if (sta && (sta->flags & WLAN_STA_WME)) {
545                 /* Hardware does not support hwaccel with TKIP when using WMM.
546                  */
547                         try_hwaccel = 0;
548                 }
549                 else if (sdata->type == IEEE80211_IF_TYPE_STA) {
550                         sta = sta_info_get(local, sdata->u.sta.bssid);
551                         if (sta) {
552                                 if (sta->flags & WLAN_STA_WME) {
553                                         try_hwaccel = 0;
554                                 }
555                                 sta_info_put(sta);
556                                 sta = NULL;
557                         }
558                 }
559         }
560
561         if (alg == ALG_NONE) {
562                 keyconf = NULL;
563                 if (try_hwaccel && key &&
564                     key->hw_key_idx != HW_KEY_IDX_INVALID &&
565                     local->ops->set_key &&
566                     (keyconf = ieee80211_key_data2conf(local, key)) != NULL &&
567                     local->ops->set_key(local_to_hw(local), DISABLE_KEY,
568                                        sta_addr, keyconf, sta ? sta->aid : 0)) {
569                         if (err)
570                                 *err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
571                         printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
572                                " failed\n", dev->name);
573                         ret = -EINVAL;
574                 }
575                 kfree(keyconf);
576
577                 if (set_tx_key || sdata->default_key == key) {
578                         ieee80211_debugfs_key_remove_default(sdata);
579                         sdata->default_key = NULL;
580                 }
581                 ieee80211_debugfs_key_remove(key);
582                 if (sta)
583                         sta->key = NULL;
584                 else
585                         sdata->keys[idx] = NULL;
586                 ieee80211_key_free(key);
587                 key = NULL;
588         } else {
589                 old_key = key;
590                 key = ieee80211_key_alloc(sta ? NULL : sdata, idx, key_len,
591                                           GFP_KERNEL);
592                 if (!key) {
593                         ret = -ENOMEM;
594                         goto err_out;
595                 }
596
597                 /* default to sw encryption; low-level driver sets these if the
598                  * requested encryption is supported */
599                 key->hw_key_idx = HW_KEY_IDX_INVALID;
600                 key->force_sw_encrypt = 1;
601
602                 key->alg = alg;
603                 key->keyidx = idx;
604                 key->keylen = key_len;
605                 memcpy(key->key, _key, key_len);
606                 if (set_tx_key)
607                         key->default_tx_key = 1;
608
609                 if (alg == ALG_CCMP) {
610                         /* Initialize AES key state here as an optimization
611                          * so that it does not need to be initialized for every
612                          * packet. */
613                         key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
614                                 key->key);
615                         if (!key->u.ccmp.tfm) {
616                                 ret = -ENOMEM;
617                                 goto err_free;
618                         }
619                 }
620
621                 if (set_tx_key || sdata->default_key == old_key) {
622                         ieee80211_debugfs_key_remove_default(sdata);
623                         sdata->default_key = NULL;
624                 }
625                 ieee80211_debugfs_key_remove(old_key);
626                 if (sta)
627                         sta->key = key;
628                 else
629                         sdata->keys[idx] = key;
630                 ieee80211_key_free(old_key);
631                 ieee80211_debugfs_key_add(local, key);
632                 if (sta)
633                         ieee80211_debugfs_key_sta_link(key, sta);
634
635                 if (try_hwaccel &&
636                     (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP)) {
637                         int e = ieee80211_set_hw_encryption(dev, sta, sta_addr,
638                                                             key);
639                         if (err)
640                                 *err = e;
641                 }
642         }
643
644         if (set_tx_key || (!sta && !sdata->default_key && key)) {
645                 sdata->default_key = key;
646                 if (key)
647                         ieee80211_debugfs_key_add_default(sdata);
648
649                 if (local->ops->set_key_idx &&
650                     local->ops->set_key_idx(local_to_hw(local), idx))
651                         printk(KERN_DEBUG "%s: failed to set TX key idx for "
652                                "low-level driver\n", dev->name);
653         }
654
655         if (sta)
656                 sta_info_put(sta);
657
658         return 0;
659
660 err_free:
661         ieee80211_key_free(key);
662 err_out:
663         if (sta)
664                 sta_info_put(sta);
665         return ret;
666 }
667
668
669 static int ieee80211_ioctl_set_encryption(struct net_device *dev,
670                                           struct prism2_hostapd_param *param,
671                                           int param_len)
672 {
673         int alg;
674
675         param->u.crypt.err = 0;
676         param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0';
677
678         if (param_len <
679             (int) ((char *) param->u.crypt.key - (char *) param) +
680             param->u.crypt.key_len) {
681                 printk(KERN_DEBUG "%s: set_encrypt - invalid param_lem\n",
682                        dev->name);
683                 return -EINVAL;
684         }
685
686         if (strcmp(param->u.crypt.alg, "none") == 0)
687                 alg = ALG_NONE;
688         else if (strcmp(param->u.crypt.alg, "WEP") == 0)
689                 alg = ALG_WEP;
690         else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
691                 if (param->u.crypt.key_len != ALG_TKIP_KEY_LEN) {
692                         printk(KERN_DEBUG "%s: set_encrypt - invalid TKIP key "
693                                "length %d\n", dev->name,
694                                param->u.crypt.key_len);
695                         return -EINVAL;
696                 }
697                 alg = ALG_TKIP;
698         } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
699                 if (param->u.crypt.key_len != ALG_CCMP_KEY_LEN) {
700                         printk(KERN_DEBUG "%s: set_encrypt - invalid CCMP key "
701                                "length %d\n", dev->name,
702                                param->u.crypt.key_len);
703                         return -EINVAL;
704                 }
705                 alg = ALG_CCMP;
706         } else {
707                 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
708                 printk(KERN_DEBUG "%s: set_encrypt - unknown alg\n",
709                        dev->name);
710                 return -EINVAL;
711         }
712
713         return ieee80211_set_encryption(
714                 dev, param->sta_addr,
715                 param->u.crypt.idx, alg,
716                 param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY,
717                 &param->u.crypt.err, param->u.crypt.key,
718                 param->u.crypt.key_len);
719 }
720
721
722 static int ieee80211_ioctl_get_encryption(struct net_device *dev,
723                                           struct prism2_hostapd_param *param,
724                                           int param_len)
725 {
726         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
727         int ret = 0;
728         struct sta_info *sta;
729         struct ieee80211_key **key;
730         int max_key_len;
731         struct ieee80211_sub_if_data *sdata;
732         u8 *pos;
733
734         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
735
736         param->u.crypt.err = 0;
737
738         max_key_len = param_len -
739                 (int) ((char *) param->u.crypt.key - (char *) param);
740         if (max_key_len < 0)
741                 return -EINVAL;
742
743         if (is_broadcast_ether_addr(param->sta_addr)) {
744                 sta = NULL;
745                 if (param->u.crypt.idx >= NUM_DEFAULT_KEYS) {
746                         param->u.crypt.idx = sdata->default_key ?
747                                 sdata->default_key->keyidx : 0;
748                         return 0;
749                 } else
750                         key = &sdata->keys[param->u.crypt.idx];
751         } else {
752                 sta = sta_info_get(local, param->sta_addr);
753                 if (!sta) {
754                         param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
755                         return -EINVAL;
756                 }
757
758                 key = &sta->key;
759         }
760
761         memset(param->u.crypt.seq_counter, 0, HOSTAP_SEQ_COUNTER_SIZE);
762         if (!*key) {
763                 memcpy(param->u.crypt.alg, "none", 5);
764                 param->u.crypt.key_len = 0;
765                 param->u.crypt.idx = 0xff;
766         } else {
767                 switch ((*key)->alg) {
768                 case ALG_WEP:
769                         memcpy(param->u.crypt.alg, "WEP", 4);
770                         break;
771                 case ALG_TKIP:
772                 {
773                         u32 iv32;
774                         u16 iv16;
775
776                         memcpy(param->u.crypt.alg, "TKIP", 5);
777                         if (local->ops->get_sequence_counter) {
778                         /* Get transmit counter from low level driver */
779                                 if (local->ops->get_sequence_counter(
780                                                 local_to_hw(local),
781                                                 param->sta_addr,
782                                                 (*key)->keyidx,
783                                                 IEEE80211_SEQ_COUNTER_TX,
784                                                 &iv32,
785                                                 &iv16)) {
786                                         /* Error getting value from device */
787                                         return -EIO;
788                                 }
789                         } else {
790                                 /* Get it from our own local data */
791                                 iv32 = (*key)->u.tkip.iv32;
792                                 iv16 = (*key)->u.tkip.iv16;
793                         }
794                         pos = param->u.crypt.seq_counter;
795                         *pos++ = iv16 & 0xff;
796                         *pos++ = (iv16 >> 8) & 0xff;
797                         *pos++ = iv32 & 0xff;
798                         *pos++ = (iv32 >> 8) & 0xff;
799                         *pos++ = (iv32 >> 16) & 0xff;
800                         *pos++ = (iv32 >> 24) & 0xff;
801                         break;
802                         }
803                 case ALG_CCMP:
804                 {
805                         u8 *pn;
806                         memcpy(param->u.crypt.alg, "CCMP", 5);
807                         pos = param->u.crypt.seq_counter;
808                         pn = (*key)->u.ccmp.tx_pn;
809                         *pos++ = pn[5];
810                         *pos++ = pn[4];
811                         *pos++ = pn[3];
812                         *pos++ = pn[2];
813                         *pos++ = pn[1];
814                         *pos++ = pn[0];
815                         break;
816                 }
817                 default:
818                         memcpy(param->u.crypt.alg, "unknown", 8);
819                         break;
820                 }
821
822                 if (max_key_len < (*key)->keylen)
823                         ret = -E2BIG;
824                 else {
825                         param->u.crypt.key_len = (*key)->keylen;
826                         memcpy(param->u.crypt.key, (*key)->key,
827                                (*key)->keylen);
828                 }
829         }
830
831         if (sta)
832                 sta_info_put(sta);
833
834         return ret;
835 }
836
837
838 #ifdef CONFIG_HOSTAPD_WPA_TESTING
839 static int ieee80211_ioctl_wpa_trigger(struct net_device *dev,
840                                        struct prism2_hostapd_param *param)
841 {
842         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
843         struct sta_info *sta;
844
845         if (is_broadcast_ether_addr(param->sta_addr)) {
846                 local->wpa_trigger = param->u.wpa_trigger.trigger;
847                 return 0;
848         }
849
850         sta = sta_info_get(local, param->sta_addr);
851         if (!sta) {
852                 printk(KERN_DEBUG "%s: wpa_trigger - unknown addr\n",
853                        dev->name);
854                 return -EINVAL;
855         }
856
857         sta->wpa_trigger = param->u.wpa_trigger.trigger;
858
859         sta_info_put(sta);
860         return 0;
861 }
862 #endif /* CONFIG_HOSTAPD_WPA_TESTING */
863
864
865 static int ieee80211_ioctl_set_rate_sets(struct net_device *dev,
866                                          struct prism2_hostapd_param *param,
867                                          int param_len)
868 {
869         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
870         u16 *pos = (u16 *) param->u.set_rate_sets.data;
871         int left = param_len - ((u8 *) pos - (u8 *) param);
872         int i, mode, num_supp, num_basic, *supp, *basic, *prev;
873         struct ieee80211_hw_mode *hw_mode;
874
875         mode = param->u.set_rate_sets.mode;
876         num_supp = param->u.set_rate_sets.num_supported_rates;
877         num_basic = param->u.set_rate_sets.num_basic_rates;
878
879         if (left < (num_supp + num_basic) * 2) {
880                 printk(KERN_WARNING "%s: invalid length in hostapd set rate "
881                        "sets ioctl (%d != %d)\n", dev->name, left,
882                        (num_supp + num_basic) * 2);
883                 return -EINVAL;
884         }
885
886         supp = (int *) kmalloc((num_supp + 1) * sizeof(int), GFP_KERNEL);
887         basic = (int *) kmalloc((num_basic + 1) * sizeof(int), GFP_KERNEL);
888
889         if (!supp || !basic) {
890                 kfree(supp);
891                 kfree(basic);
892                 return -ENOMEM;
893         }
894
895         for (i = 0; i < num_supp; i++)
896                 supp[i] = *pos++;
897         supp[i] = -1;
898
899         for (i = 0; i < num_basic; i++)
900                 basic[i] = *pos++;
901         basic[i] = -1;
902
903         if (num_supp == 0) {
904                 kfree(supp);
905                 supp = NULL;
906         }
907
908         if (num_basic == 0) {
909                 kfree(basic);
910                 basic = NULL;
911         }
912
913         prev = local->supp_rates[mode];
914         local->supp_rates[mode] = supp;
915         kfree(prev);
916
917         prev = local->basic_rates[mode];
918         local->basic_rates[mode] = basic;
919         kfree(prev);
920
921         /* TODO: should update STA TX rates and remove STAs if they
922          * do not have any remaining supported rates after the change
923          */
924         list_for_each_entry(hw_mode, &local->modes_list, list)
925                 if (hw_mode->mode == mode)
926                         ieee80211_prepare_rates(local, hw_mode);
927
928         return 0;
929 }
930
931
932 static int ieee80211_ioctl_add_if(struct net_device *dev,
933                                   struct prism2_hostapd_param *param,
934                                   int param_len)
935 {
936         u8 *pos = param->u.if_info.data;
937         int left = param_len - ((u8 *) pos - (u8 *) param);
938         struct net_device *new_dev;
939         int res;
940         struct hostapd_if_wds *wds;
941         struct hostapd_if_bss *bss;
942
943         printk(KERN_WARNING "PRISM2_HOSTAPD_ADD_IF ioctl is deprecated!");
944         switch (param->u.if_info.type) {
945         case HOSTAP_IF_WDS:
946                 wds = (struct hostapd_if_wds *) param->u.if_info.data;
947
948                 if (left < sizeof(struct hostapd_if_wds))
949                         return -EPROTO;
950
951                 res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev,
952                                        IEEE80211_IF_TYPE_WDS);
953                 if (res)
954                         return res;
955                 res = ieee80211_if_update_wds(new_dev, wds->remote_addr);
956                 if (unlikely(res)) {
957                         struct ieee80211_local *local =
958                                 wdev_priv(dev->ieee80211_ptr);
959                         struct ieee80211_sub_if_data *sdata =
960                                 IEEE80211_DEV_TO_SUB_IF(new_dev);
961                         write_lock_bh(&local->sub_if_lock);
962                         list_del(&sdata->list);
963                         write_unlock_bh(&local->sub_if_lock);
964                         __ieee80211_if_del(local, sdata);
965                 }
966                 return res;
967         case HOSTAP_IF_VLAN:
968                 if (left < sizeof(struct hostapd_if_vlan))
969                         return -EPROTO;
970
971                 res = ieee80211_if_add(dev, param->u.if_info.name, NULL,
972                                        IEEE80211_IF_TYPE_VLAN);
973                 return res;
974         case HOSTAP_IF_BSS:
975                 bss = (struct hostapd_if_bss *) param->u.if_info.data;
976
977                 if (left < sizeof(struct hostapd_if_bss))
978                         return -EPROTO;
979
980                 res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev,
981                                        IEEE80211_IF_TYPE_AP);
982                 if (res)
983                         return res;
984                 memcpy(new_dev->dev_addr, bss->bssid, ETH_ALEN);
985                 return 0;
986         case HOSTAP_IF_STA:
987                 if (left < sizeof(struct hostapd_if_sta))
988                         return -EPROTO;
989
990                 res = ieee80211_if_add(dev, param->u.if_info.name, NULL,
991                                        IEEE80211_IF_TYPE_STA);
992                 return res;
993         default:
994                 return -EINVAL;
995         }
996
997         return 0;
998 }
999
1000 static int ieee80211_ioctl_remove_if(struct net_device *dev,
1001                                      struct prism2_hostapd_param *param)
1002 {
1003         unsigned int type;
1004
1005         switch (param->u.if_info.type) {
1006         case HOSTAP_IF_WDS:
1007                 type = IEEE80211_IF_TYPE_WDS;
1008                 break;
1009         case HOSTAP_IF_VLAN:
1010                 type = IEEE80211_IF_TYPE_VLAN;
1011                 break;
1012         case HOSTAP_IF_BSS:
1013                 type = IEEE80211_IF_TYPE_AP;
1014                 break;
1015         case HOSTAP_IF_STA:
1016                 type = IEEE80211_IF_TYPE_STA;
1017                 break;
1018         default:
1019                 return -EINVAL;
1020         }
1021
1022         return ieee80211_if_remove(dev, param->u.if_info.name, type);
1023 }
1024
1025 static int ieee80211_ioctl_update_if(struct net_device *dev,
1026                                      struct prism2_hostapd_param *param,
1027                                      int param_len)
1028 {
1029         u8 *pos = param->u.if_info.data;
1030         int left = param_len - ((u8 *) pos - (u8 *) param);
1031
1032         if (param->u.if_info.type == HOSTAP_IF_WDS) {
1033                 struct hostapd_if_wds *wds =
1034                         (struct hostapd_if_wds *) param->u.if_info.data;
1035                 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1036                 struct net_device *wds_dev = NULL;
1037                 struct ieee80211_sub_if_data *sdata;
1038
1039                 if (left < sizeof(struct ieee80211_if_wds))
1040                         return -EPROTO;
1041
1042                 read_lock(&local->sub_if_lock);
1043                 list_for_each_entry(sdata, &local->sub_if_list, list) {
1044                         if (strcmp(param->u.if_info.name,
1045                                    sdata->dev->name) == 0) {
1046                                 wds_dev = sdata->dev;
1047                                 break;
1048                         }
1049                 }
1050                 read_unlock(&local->sub_if_lock);
1051
1052                 if (!wds_dev || sdata->type != IEEE80211_IF_TYPE_WDS)
1053                         return -ENODEV;
1054
1055                 return ieee80211_if_update_wds(wds_dev, wds->remote_addr);
1056         } else {
1057                 return -EOPNOTSUPP;
1058         }
1059 }
1060
1061
1062 static int ieee80211_ioctl_scan_req(struct net_device *dev,
1063                                     struct prism2_hostapd_param *param,
1064                                     int param_len)
1065 {
1066         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1067         u8 *pos = param->u.scan_req.ssid;
1068         int left = param_len - ((u8 *) pos - (u8 *) param);
1069         int len = param->u.scan_req.ssid_len;
1070
1071         if (local->user_space_mlme)
1072                 return -EOPNOTSUPP;
1073
1074         if (!netif_running(dev))
1075                 return -ENETDOWN;
1076
1077         if (left < len || len > IEEE80211_MAX_SSID_LEN)
1078                 return -EINVAL;
1079
1080         return ieee80211_sta_req_scan(dev, pos, len);
1081 }
1082
1083
1084 static int ieee80211_ioctl_sta_get_state(struct net_device *dev,
1085                                          struct prism2_hostapd_param *param)
1086 {
1087         struct ieee80211_sub_if_data *sdata;
1088
1089         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1090         if (sdata->type != IEEE80211_IF_TYPE_STA &&
1091             sdata->type != IEEE80211_IF_TYPE_IBSS)
1092                 return -EINVAL;
1093         param->u.sta_get_state.state = sdata->u.sta.state;
1094         return 0;
1095 }
1096
1097
1098 static int ieee80211_ioctl_mlme(struct net_device *dev,
1099                                 struct prism2_hostapd_param *param)
1100 {
1101         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1102         struct ieee80211_sub_if_data *sdata;
1103
1104         if (local->user_space_mlme)
1105                 return -EOPNOTSUPP;
1106
1107         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1108         if (sdata->type != IEEE80211_IF_TYPE_STA &&
1109             sdata->type != IEEE80211_IF_TYPE_IBSS)
1110                 return -EINVAL;
1111         switch (param->u.mlme.cmd) {
1112         case MLME_STA_DEAUTH:
1113                 return ieee80211_sta_deauthenticate(dev, param->u.mlme.reason_code);
1114         case MLME_STA_DISASSOC:
1115                 return ieee80211_sta_disassociate(dev, param->u.mlme.reason_code);
1116         }
1117         return 0;
1118 }
1119
1120
1121 static int ieee80211_ioctl_get_load_stats(struct net_device *dev,
1122                                           struct prism2_hostapd_param *param)
1123 {
1124         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1125
1126         param->u.get_load_stats.channel_use = local->channel_use;
1127 /*      if (param->u.get_load_stats.flags & LOAD_STATS_CLEAR)
1128                 local->channel_use = 0; */ /* now it's not raw counter */
1129
1130         return 0;
1131 }
1132
1133
1134 static int ieee80211_ioctl_set_sta_vlan(struct net_device *dev,
1135                                         struct prism2_hostapd_param *param)
1136 {
1137         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1138         struct sta_info *sta;
1139
1140         sta = sta_info_get(local, param->sta_addr);
1141         if (sta) {
1142                 struct net_device *new_vlan_dev;
1143                 new_vlan_dev =
1144                         dev_get_by_name(param->u.set_sta_vlan.vlan_name);
1145                 if (new_vlan_dev) {
1146 #if 0
1147                         printk("%s: Station " MAC_FMT " moved to vlan: %s\n",
1148                                dev->name, MAC_ARG(param->sta_addr),
1149                                new_vlan_dev->name);
1150 #endif
1151                         if (sta->dev != new_vlan_dev) {
1152                                 ieee80211_send_layer2_update(new_vlan_dev,
1153                                                              sta->addr);
1154                         }
1155                         sta->dev = new_vlan_dev;
1156                         sta->vlan_id = param->u.set_sta_vlan.vlan_id;
1157                         dev_put(new_vlan_dev);
1158                 }
1159                 sta_info_put(sta);
1160         }
1161
1162         return sta ? 0 : -ENOENT;
1163 }
1164
1165
1166 static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
1167 {
1168         struct ieee80211_sub_if_data *sdata;
1169         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1170
1171         if (local->user_space_mlme)
1172                 return -EOPNOTSUPP;
1173
1174         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1175         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1176             sdata->type == IEEE80211_IF_TYPE_IBSS) {
1177                 int ret = ieee80211_sta_set_extra_ie(dev, ie, len);
1178                 if (ret)
1179                         return ret;
1180                 sdata->u.sta.auto_bssid_sel = 0;
1181                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
1182                 return 0;
1183         }
1184
1185         if (sdata->type == IEEE80211_IF_TYPE_AP) {
1186                 kfree(sdata->u.ap.generic_elem);
1187                 sdata->u.ap.generic_elem = kmalloc(len, GFP_KERNEL);
1188                 if (!sdata->u.ap.generic_elem)
1189                         return -ENOMEM;
1190                 memcpy(sdata->u.ap.generic_elem, ie, len);
1191                 sdata->u.ap.generic_elem_len = len;
1192                 return ieee80211_if_config(dev);
1193         }
1194         return -EOPNOTSUPP;
1195 }
1196
1197
1198 static int
1199 ieee80211_ioctl_set_generic_info_elem(struct net_device *dev,
1200                                       struct prism2_hostapd_param *param,
1201                                       int param_len)
1202 {
1203         u8 *pos = param->u.set_generic_info_elem.data;
1204         int left = param_len - ((u8 *) pos - (u8 *) param);
1205         int len = param->u.set_generic_info_elem.len;
1206
1207         if (left < len)
1208                 return -EINVAL;
1209
1210         return ieee80211_set_gen_ie(dev, pos, len);
1211 }
1212
1213
1214 static int ieee80211_ioctl_set_regulatory_domain(struct net_device *dev,
1215                                             struct prism2_hostapd_param *param)
1216 {
1217         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1218         struct ieee80211_conf *conf = &local->hw.conf;
1219         conf->regulatory_domain = param->u.set_regulatory_domain.rd;
1220         return 0;
1221 }
1222
1223
1224 static int ieee80211_ioctl_set_radio_enabled(struct net_device *dev,
1225                                              int val)
1226 {
1227         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1228         struct ieee80211_conf *conf = &local->hw.conf;
1229
1230         conf->radio_enabled = val;
1231         return ieee80211_hw_config(wdev_priv(dev->ieee80211_ptr));
1232 }
1233
1234 static int
1235 ieee80211_ioctl_set_tx_queue_params(struct net_device *dev,
1236                                     struct prism2_hostapd_param *param)
1237 {
1238         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1239         struct ieee80211_tx_queue_params qparam;
1240
1241         if (!local->ops->conf_tx) {
1242                 printk(KERN_DEBUG "%s: low-level driver does not support TX "
1243                        "queue configuration\n", dev->name);
1244                 return -EOPNOTSUPP;
1245         }
1246
1247         memset(&qparam, 0, sizeof(qparam));
1248         qparam.aifs = param->u.tx_queue_params.aifs;
1249         qparam.cw_min = param->u.tx_queue_params.cw_min;
1250         qparam.cw_max = param->u.tx_queue_params.cw_max;
1251         qparam.burst_time = param->u.tx_queue_params.burst_time;
1252
1253         return local->ops->conf_tx(local_to_hw(local),
1254                                   param->u.tx_queue_params.queue,
1255                                   &qparam);
1256 }
1257
1258
1259 static int ieee80211_ioctl_get_tx_stats(struct net_device *dev,
1260                                         struct prism2_hostapd_param *param)
1261 {
1262         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1263         struct ieee80211_tx_queue_stats stats;
1264         int ret, i;
1265
1266         if (!local->ops->get_tx_stats)
1267                 return -EOPNOTSUPP;
1268
1269         memset(&stats, 0, sizeof(stats));
1270         ret = local->ops->get_tx_stats(local_to_hw(local), &stats);
1271         if (ret)
1272                 return ret;
1273
1274         for (i = 0; i < 4; i++) {
1275                 param->u.get_tx_stats.data[i].len = stats.data[i].len;
1276                 param->u.get_tx_stats.data[i].limit = stats.data[i].limit;
1277                 param->u.get_tx_stats.data[i].count = stats.data[i].count;
1278         }
1279
1280         return 0;
1281 }
1282
1283
1284 static int ieee80211_ioctl_set_channel_flag(struct net_device *dev,
1285                                             struct prism2_hostapd_param *param)
1286 {
1287         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1288         struct ieee80211_hw_mode *mode;
1289         struct ieee80211_channel *chan = NULL;
1290         int i;
1291
1292         list_for_each_entry(mode, &local->modes_list, list) {
1293                 if (mode->mode == param->u.set_channel_flag.mode)
1294                         goto found;
1295         }
1296         return -ENOENT;
1297 found:
1298
1299         for (i = 0; i < mode->num_channels; i++) {
1300                 chan = &mode->channels[i];
1301                 if (chan->chan == param->u.set_channel_flag.chan)
1302                         break;
1303                 chan = NULL;
1304         }
1305
1306         if (!chan)
1307                 return -ENOENT;
1308
1309         chan->flag = param->u.set_channel_flag.flag;
1310         chan->power_level = param->u.set_channel_flag.power_level;
1311         chan->antenna_max = param->u.set_channel_flag.antenna_max;
1312
1313         return 0;
1314 }
1315
1316
1317 static int ieee80211_ioctl_set_quiet_params(struct net_device *dev,
1318                                             struct prism2_hostapd_param *param)
1319 {
1320         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1321         struct ieee80211_conf *conf = &local->hw.conf;
1322
1323         conf->quiet_duration = param->u.quiet.duration;
1324         conf->quiet_offset = param->u.quiet.offset;
1325         conf->quiet_period = param->u.quiet.period;
1326         return 0;
1327 }
1328
1329
1330 static int ieee80211_ioctl_set_radar_params(struct net_device *dev,
1331                                             struct prism2_hostapd_param *param)
1332 {
1333         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1334         struct ieee80211_conf *conf = &local->hw.conf;
1335
1336         conf->radar_firpwr_threshold = param->u.radar.radar_firpwr_threshold;
1337         conf->radar_rssi_threshold = param->u.radar.radar_rssi_threshold;
1338         conf->pulse_height_threshold = param->u.radar.pulse_height_threshold;
1339         conf->pulse_rssi_threshold = param->u.radar.pulse_rssi_threshold;
1340         conf->pulse_inband_threshold = param->u.radar.pulse_inband_threshold;
1341         return 0;
1342 }
1343
1344
1345 static int ieee80211_ioctl_priv_hostapd(struct net_device *dev,
1346                                         struct iw_point *p)
1347 {
1348         struct prism2_hostapd_param *param;
1349         int ret = 0;
1350
1351         if (p->length < sizeof(struct prism2_hostapd_param) ||
1352             p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) {
1353                 printk(KERN_DEBUG "%s: hostapd ioctl: ptr=%p len=%d min=%d "
1354                        "max=%d\n", dev->name, p->pointer, p->length,
1355                        (int)sizeof(struct prism2_hostapd_param),
1356                        PRISM2_HOSTAPD_MAX_BUF_SIZE);
1357                 return -EINVAL;
1358         }
1359
1360         param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
1361         if (!param)
1362                 return -ENOMEM;
1363
1364         if (copy_from_user(param, p->pointer, p->length)) {
1365                 ret = -EFAULT;
1366                 goto out;
1367         }
1368
1369         switch (param->cmd) {
1370         case PRISM2_HOSTAPD_FLUSH:
1371                 ret = ieee80211_ioctl_flush(dev, param);
1372                 break;
1373         case PRISM2_HOSTAPD_ADD_STA:
1374                 ret = ieee80211_ioctl_add_sta(dev, param);
1375                 break;
1376         case PRISM2_HOSTAPD_REMOVE_STA:
1377                 ret = ieee80211_ioctl_remove_sta(dev, param);
1378                 break;
1379         case PRISM2_HOSTAPD_GET_INFO_STA:
1380                 ret = ieee80211_ioctl_get_info_sta(dev, param);
1381                 break;
1382         case PRISM2_SET_ENCRYPTION:
1383                 ret = ieee80211_ioctl_set_encryption(dev, param, p->length);
1384                 break;
1385         case PRISM2_GET_ENCRYPTION:
1386                 ret = ieee80211_ioctl_get_encryption(dev, param, p->length);
1387                 break;
1388         case PRISM2_HOSTAPD_SET_FLAGS_STA:
1389                 ret = ieee80211_ioctl_set_flags_sta(dev, param);
1390                 break;
1391         case PRISM2_HOSTAPD_SET_BEACON:
1392                 ret = ieee80211_ioctl_set_beacon(dev, param, p->length, 0);
1393                 break;
1394         case PRISM2_HOSTAPD_GET_HW_FEATURES:
1395                 ret = ieee80211_ioctl_get_hw_features(dev, param, p->length);
1396                 break;
1397 #ifdef CONFIG_HOSTAPD_WPA_TESTING
1398         case PRISM2_HOSTAPD_WPA_TRIGGER:
1399                 ret = ieee80211_ioctl_wpa_trigger(dev, param);
1400                 break;
1401 #endif /* CONFIG_HOSTAPD_WPA_TESTING */
1402         case PRISM2_HOSTAPD_SET_RATE_SETS:
1403                 ret = ieee80211_ioctl_set_rate_sets(dev, param, p->length);
1404                 break;
1405         case PRISM2_HOSTAPD_ADD_IF:
1406                 ret = ieee80211_ioctl_add_if(dev, param, p->length);
1407                 break;
1408         case PRISM2_HOSTAPD_REMOVE_IF:
1409                 ret = ieee80211_ioctl_remove_if(dev, param);
1410                 break;
1411         case PRISM2_HOSTAPD_GET_DOT11COUNTERSTABLE:
1412                 ret = ieee80211_ioctl_get_dot11counterstable(dev, param);
1413                 break;
1414         case PRISM2_HOSTAPD_GET_LOAD_STATS:
1415                 ret = ieee80211_ioctl_get_load_stats(dev, param);
1416                 break;
1417         case PRISM2_HOSTAPD_SET_STA_VLAN:
1418                 ret = ieee80211_ioctl_set_sta_vlan(dev, param);
1419                 break;
1420         case PRISM2_HOSTAPD_SET_GENERIC_INFO_ELEM:
1421                 ret = ieee80211_ioctl_set_generic_info_elem(dev, param,
1422                                                             p->length);
1423                 break;
1424         case PRISM2_HOSTAPD_SET_CHANNEL_FLAG:
1425                 ret = ieee80211_ioctl_set_channel_flag(dev, param);
1426                 break;
1427         case PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN:
1428                 ret = ieee80211_ioctl_set_regulatory_domain(dev, param);
1429                 break;
1430         case PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS:
1431                 ret = ieee80211_ioctl_set_tx_queue_params(dev, param);
1432                 break;
1433         case PRISM2_HOSTAPD_GET_TX_STATS:
1434                 ret = ieee80211_ioctl_get_tx_stats(dev, param);
1435                 break;
1436         case PRISM2_HOSTAPD_UPDATE_IF:
1437                 ret = ieee80211_ioctl_update_if(dev, param, p->length);
1438                 break;
1439         case PRISM2_HOSTAPD_SCAN_REQ:
1440                 ret = ieee80211_ioctl_scan_req(dev, param, p->length);
1441                 break;
1442         case PRISM2_STA_GET_STATE:
1443                 ret = ieee80211_ioctl_sta_get_state(dev, param);
1444                 break;
1445         case PRISM2_HOSTAPD_MLME:
1446                 ret = ieee80211_ioctl_mlme(dev, param);
1447                 break;
1448         case PRISM2_HOSTAPD_SET_RADAR_PARAMS:
1449                 ret = ieee80211_ioctl_set_radar_params(dev, param);
1450                 break;
1451         case PRISM2_HOSTAPD_SET_QUIET_PARAMS:
1452                 ret = ieee80211_ioctl_set_quiet_params(dev, param);
1453                 break;
1454         default:
1455                 ret = -EOPNOTSUPP;
1456                 break;
1457         }
1458
1459         if (copy_to_user(p->pointer, param, p->length))
1460                 ret = -EFAULT;
1461
1462  out:
1463         kfree(param);
1464
1465         return ret;
1466 }
1467
1468
1469 static int ieee80211_ioctl_giwname(struct net_device *dev,
1470                                    struct iw_request_info *info,
1471                                    char *name, char *extra)
1472 {
1473         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1474
1475         switch (local->hw.conf.phymode) {
1476         case MODE_IEEE80211A:
1477                 strcpy(name, "IEEE 802.11a");
1478                 break;
1479         case MODE_IEEE80211B:
1480                 strcpy(name, "IEEE 802.11b");
1481                 break;
1482         case MODE_IEEE80211G:
1483                 strcpy(name, "IEEE 802.11g");
1484                 break;
1485         case MODE_ATHEROS_TURBO:
1486                 strcpy(name, "5GHz Turbo");
1487                 break;
1488         default:
1489                 strcpy(name, "IEEE 802.11");
1490                 break;
1491         }
1492
1493         return 0;
1494 }
1495
1496
1497 static int ieee80211_ioctl_giwrange(struct net_device *dev,
1498                                  struct iw_request_info *info,
1499                                  struct iw_point *data, char *extra)
1500 {
1501         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1502         struct iw_range *range = (struct iw_range *) extra;
1503
1504         data->length = sizeof(struct iw_range);
1505         memset(range, 0, sizeof(struct iw_range));
1506
1507         range->we_version_compiled = WIRELESS_EXT;
1508         range->we_version_source = 21;
1509         range->retry_capa = IW_RETRY_LIMIT;
1510         range->retry_flags = IW_RETRY_LIMIT;
1511         range->min_retry = 0;
1512         range->max_retry = 255;
1513         range->min_rts = 0;
1514         range->max_rts = 2347;
1515         range->min_frag = 256;
1516         range->max_frag = 2346;
1517
1518         range->encoding_size[0] = 5;
1519         range->encoding_size[1] = 13;
1520         range->num_encoding_sizes = 2;
1521         range->max_encoding_tokens = NUM_DEFAULT_KEYS;
1522
1523         range->max_qual.qual = local->hw.max_signal;
1524         range->max_qual.level = local->hw.max_rssi;
1525         range->max_qual.noise = local->hw.max_noise;
1526         range->max_qual.updated = local->wstats_flags;
1527
1528         range->avg_qual.qual = local->hw.max_signal/2;
1529         range->avg_qual.level = 0;
1530         range->avg_qual.noise = 0;
1531         range->avg_qual.updated = local->wstats_flags;
1532
1533         range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1534                           IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1535
1536         IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
1537         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
1538         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
1539         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
1540
1541         return 0;
1542 }
1543
1544
1545 static int ieee80211_ioctl_siwmode(struct net_device *dev,
1546                                    struct iw_request_info *info,
1547                                    __u32 *mode, char *extra)
1548 {
1549         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1550         int type;
1551
1552         if (sdata->type == IEEE80211_IF_TYPE_VLAN)
1553                 return -EOPNOTSUPP;
1554
1555         switch (*mode) {
1556         case IW_MODE_MASTER:
1557                 type = IEEE80211_IF_TYPE_AP;
1558                 break;
1559         case IW_MODE_INFRA:
1560                 type = IEEE80211_IF_TYPE_STA;
1561                 break;
1562         case IW_MODE_ADHOC:
1563                 type = IEEE80211_IF_TYPE_IBSS;
1564                 break;
1565         case IW_MODE_MONITOR:
1566                 type = IEEE80211_IF_TYPE_MNTR;
1567                 break;
1568         case IW_MODE_REPEAT:
1569                 type = IEEE80211_IF_TYPE_WDS;
1570                 break;
1571         default:
1572                 return -EINVAL;
1573         }
1574
1575         if (type == sdata->type)
1576                 return 0;
1577         if (netif_running(dev))
1578                 return -EBUSY;
1579
1580         ieee80211_if_reinit(dev);
1581         ieee80211_if_set_type(dev, type);
1582
1583         return 0;
1584 }
1585
1586
1587 static int ieee80211_ioctl_giwmode(struct net_device *dev,
1588                                    struct iw_request_info *info,
1589                                    __u32 *mode, char *extra)
1590 {
1591         struct ieee80211_sub_if_data *sdata;
1592
1593         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1594         switch (sdata->type) {
1595         case IEEE80211_IF_TYPE_AP:
1596                 *mode = IW_MODE_MASTER;
1597                 break;
1598         case IEEE80211_IF_TYPE_STA:
1599                 *mode = IW_MODE_INFRA;
1600                 break;
1601         case IEEE80211_IF_TYPE_IBSS:
1602                 *mode = IW_MODE_ADHOC;
1603                 break;
1604         case IEEE80211_IF_TYPE_MNTR:
1605                 *mode = IW_MODE_MONITOR;
1606                 break;
1607         case IEEE80211_IF_TYPE_WDS:
1608                 *mode = IW_MODE_REPEAT;
1609                 break;
1610         case IEEE80211_IF_TYPE_VLAN:
1611                 *mode = IW_MODE_SECOND;         /* FIXME */
1612                 break;
1613         default:
1614                 *mode = IW_MODE_AUTO;
1615                 break;
1616         }
1617         return 0;
1618 }
1619
1620 int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
1621 {
1622         struct ieee80211_hw_mode *mode;
1623         int c, set = 0;
1624         int ret = -EINVAL;
1625
1626         list_for_each_entry(mode, &local->modes_list, list) {
1627                 if (!(local->enabled_modes & (1 << mode->mode)))
1628                         continue;
1629                 for (c = 0; c < mode->num_channels; c++) {
1630                         struct ieee80211_channel *chan = &mode->channels[c];
1631                         if (chan->flag & IEEE80211_CHAN_W_SCAN &&
1632                             ((chan->chan == channel) || (chan->freq == freq))) {
1633                                 /* Use next_mode as the mode preference to
1634                                  * resolve non-unique channel numbers. */
1635                                 if (set && mode->mode != local->next_mode)
1636                                         continue;
1637
1638                                 local->oper_channel = chan;
1639                                 local->oper_hw_mode = mode;
1640                                 set++;
1641                         }
1642                 }
1643         }
1644
1645         if (set) {
1646                 if (local->sta_scanning)
1647                         ret = 0;
1648                 else
1649                         ret = ieee80211_hw_config(local);
1650
1651                 rate_control_clear(local);
1652         }
1653
1654         return ret;
1655 }
1656
1657 static int ieee80211_ioctl_siwfreq(struct net_device *dev,
1658                                    struct iw_request_info *info,
1659                                    struct iw_freq *freq, char *extra)
1660 {
1661         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1662         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1663
1664         if (sdata->type == IEEE80211_IF_TYPE_STA)
1665                 sdata->u.sta.auto_channel_sel = 0;
1666
1667         /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
1668         if (freq->e == 0) {
1669                 if (freq->m < 0) {
1670                         if (sdata->type == IEEE80211_IF_TYPE_STA)
1671                                 sdata->u.sta.auto_channel_sel = 1;
1672                         return 0;
1673                 } else
1674                         return ieee80211_set_channel(local, freq->m, -1);
1675         } else {
1676                 int i, div = 1000000;
1677                 for (i = 0; i < freq->e; i++)
1678                         div /= 10;
1679                 if (div > 0)
1680                         return ieee80211_set_channel(local, -1, freq->m / div);
1681                 else
1682                         return -EINVAL;
1683         }
1684 }
1685
1686
1687 static int ieee80211_ioctl_giwfreq(struct net_device *dev,
1688                                    struct iw_request_info *info,
1689                                    struct iw_freq *freq, char *extra)
1690 {
1691         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1692
1693         /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
1694          * driver for the current channel with firmware-based management */
1695
1696         freq->m = local->hw.conf.freq;
1697         freq->e = 6;
1698
1699         return 0;
1700 }
1701
1702
1703 static int ieee80211_ioctl_siwessid(struct net_device *dev,
1704                                     struct iw_request_info *info,
1705                                     struct iw_point *data, char *ssid)
1706 {
1707         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1708         struct ieee80211_sub_if_data *sdata;
1709         size_t len = data->length;
1710
1711         /* iwconfig uses nul termination in SSID.. */
1712         if (len > 0 && ssid[len - 1] == '\0')
1713                 len--;
1714
1715         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1716         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1717             sdata->type == IEEE80211_IF_TYPE_IBSS) {
1718                 int ret;
1719                 if (local->user_space_mlme) {
1720                         if (len > IEEE80211_MAX_SSID_LEN)
1721                                 return -EINVAL;
1722                         memcpy(sdata->u.sta.ssid, ssid, len);
1723                         sdata->u.sta.ssid_len = len;
1724                         return 0;
1725                 }
1726                 sdata->u.sta.auto_ssid_sel = !data->flags;
1727                 ret = ieee80211_sta_set_ssid(dev, ssid, len);
1728                 if (ret)
1729                         return ret;
1730                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
1731                 return 0;
1732         }
1733
1734         if (sdata->type == IEEE80211_IF_TYPE_AP) {
1735                 memcpy(sdata->u.ap.ssid, ssid, len);
1736                 memset(sdata->u.ap.ssid + len, 0,
1737                        IEEE80211_MAX_SSID_LEN - len);
1738                 sdata->u.ap.ssid_len = len;
1739                 return ieee80211_if_config(dev);
1740         }
1741         return -EOPNOTSUPP;
1742 }
1743
1744
1745 static int ieee80211_ioctl_giwessid(struct net_device *dev,
1746                                     struct iw_request_info *info,
1747                                     struct iw_point *data, char *ssid)
1748 {
1749         size_t len;
1750
1751         struct ieee80211_sub_if_data *sdata;
1752         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1753         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1754             sdata->type == IEEE80211_IF_TYPE_IBSS) {
1755                 int res = ieee80211_sta_get_ssid(dev, ssid, &len);
1756                 if (res == 0) {
1757                         data->length = len;
1758                         data->flags = 1;
1759                 } else
1760                         data->flags = 0;
1761                 return res;
1762         }
1763
1764         if (sdata->type == IEEE80211_IF_TYPE_AP) {
1765                 len = sdata->u.ap.ssid_len;
1766                 if (len > IW_ESSID_MAX_SIZE)
1767                         len = IW_ESSID_MAX_SIZE;
1768                 memcpy(ssid, sdata->u.ap.ssid, len);
1769                 data->length = len;
1770                 data->flags = 1;
1771                 return 0;
1772         }
1773         return -EOPNOTSUPP;
1774 }
1775
1776
1777 static int ieee80211_ioctl_siwap(struct net_device *dev,
1778                                  struct iw_request_info *info,
1779                                  struct sockaddr *ap_addr, char *extra)
1780 {
1781         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1782         struct ieee80211_sub_if_data *sdata;
1783
1784         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1785         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1786             sdata->type == IEEE80211_IF_TYPE_IBSS) {
1787                 int ret;
1788                 if (local->user_space_mlme) {
1789                         memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
1790                                ETH_ALEN);
1791                         return 0;
1792                 }
1793                 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) {
1794                         sdata->u.sta.auto_bssid_sel = 1;
1795                         sdata->u.sta.auto_channel_sel = 1;
1796                 } else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
1797                         sdata->u.sta.auto_bssid_sel = 1;
1798                 else
1799                         sdata->u.sta.auto_bssid_sel = 0;
1800                 ret = ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data);
1801                 if (ret)
1802                         return ret;
1803                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
1804                 return 0;
1805         } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
1806                 if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
1807                            ETH_ALEN) == 0)
1808                         return 0;
1809                 return ieee80211_if_update_wds(dev, (u8 *) &ap_addr->sa_data);
1810         }
1811
1812         return -EOPNOTSUPP;
1813 }
1814
1815
1816 static int ieee80211_ioctl_giwap(struct net_device *dev,
1817                                  struct iw_request_info *info,
1818                                  struct sockaddr *ap_addr, char *extra)
1819 {
1820         struct ieee80211_sub_if_data *sdata;
1821
1822         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1823         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1824             sdata->type == IEEE80211_IF_TYPE_IBSS) {
1825                 ap_addr->sa_family = ARPHRD_ETHER;
1826                 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
1827                 return 0;
1828         } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
1829                 ap_addr->sa_family = ARPHRD_ETHER;
1830                 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
1831                 return 0;
1832         }
1833
1834         return -EOPNOTSUPP;
1835 }
1836
1837
1838 static int ieee80211_ioctl_siwscan(struct net_device *dev,
1839                                    struct iw_request_info *info,
1840                                    struct iw_point *data, char *extra)
1841 {
1842         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1843         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1844         u8 *ssid = NULL;
1845         size_t ssid_len = 0;
1846
1847         if (!netif_running(dev))
1848                 return -ENETDOWN;
1849
1850         if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
1851                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1852                     sdata->type == IEEE80211_IF_TYPE_IBSS) {
1853                         ssid = sdata->u.sta.ssid;
1854                         ssid_len = sdata->u.sta.ssid_len;
1855                 } else if (sdata->type == IEEE80211_IF_TYPE_AP) {
1856                         ssid = sdata->u.ap.ssid;
1857                         ssid_len = sdata->u.ap.ssid_len;
1858                 } else
1859                         return -EINVAL;
1860         }
1861         return ieee80211_sta_req_scan(dev, ssid, ssid_len);
1862 }
1863
1864
1865 static int ieee80211_ioctl_giwscan(struct net_device *dev,
1866                                    struct iw_request_info *info,
1867                                    struct iw_point *data, char *extra)
1868 {
1869         int res;
1870         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1871         if (local->sta_scanning)
1872                 return -EAGAIN;
1873         res = ieee80211_sta_scan_results(dev, extra, data->length);
1874         if (res >= 0) {
1875                 data->length = res;
1876                 return 0;
1877         }
1878         data->length = 0;
1879         return res;
1880 }
1881
1882
1883 static int ieee80211_ioctl_giwrate(struct net_device *dev,
1884                                   struct iw_request_info *info,
1885                                   struct iw_param *rate, char *extra)
1886 {
1887         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1888         struct sta_info *sta;
1889         struct ieee80211_sub_if_data *sdata;
1890
1891         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1892         if (sdata->type == IEEE80211_IF_TYPE_STA)
1893                 sta = sta_info_get(local, sdata->u.sta.bssid);
1894         else
1895                 return -EOPNOTSUPP;
1896         if (!sta)
1897                 return -ENODEV;
1898         if (sta->txrate < local->oper_hw_mode->num_rates)
1899                 rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
1900         else
1901                 rate->value = 0;
1902         sta_info_put(sta);
1903         return 0;
1904 }
1905
1906 static int ieee80211_ioctl_siwrts(struct net_device *dev,
1907                                   struct iw_request_info *info,
1908                                   struct iw_param *rts, char *extra)
1909 {
1910         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1911
1912         if (rts->disabled)
1913                 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
1914         else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
1915                 return -EINVAL;
1916         else
1917                 local->rts_threshold = rts->value;
1918
1919         /* If the wlan card performs RTS/CTS in hardware/firmware,
1920          * configure it here */
1921
1922         if (local->ops->set_rts_threshold)
1923                 local->ops->set_rts_threshold(local_to_hw(local),
1924                                              local->rts_threshold);
1925
1926         return 0;
1927 }
1928
1929 static int ieee80211_ioctl_giwrts(struct net_device *dev,
1930                                   struct iw_request_info *info,
1931                                   struct iw_param *rts, char *extra)
1932 {
1933         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1934
1935         rts->value = local->rts_threshold;
1936         rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
1937         rts->fixed = 1;
1938
1939         return 0;
1940 }
1941
1942
1943 static int ieee80211_ioctl_siwfrag(struct net_device *dev,
1944                                    struct iw_request_info *info,
1945                                    struct iw_param *frag, char *extra)
1946 {
1947         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1948
1949         if (frag->disabled)
1950                 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
1951         else if (frag->value < 256 ||
1952                  frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
1953                 return -EINVAL;
1954         else {
1955                 /* Fragment length must be even, so strip LSB. */
1956                 local->fragmentation_threshold = frag->value & ~0x1;
1957         }
1958
1959         /* If the wlan card performs fragmentation in hardware/firmware,
1960          * configure it here */
1961
1962         if (local->ops->set_frag_threshold)
1963                 local->ops->set_frag_threshold(
1964                         local_to_hw(local),
1965                         local->fragmentation_threshold);
1966
1967         return 0;
1968 }
1969
1970 static int ieee80211_ioctl_giwfrag(struct net_device *dev,
1971                                    struct iw_request_info *info,
1972                                    struct iw_param *frag, char *extra)
1973 {
1974         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1975
1976         frag->value = local->fragmentation_threshold;
1977         frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD);
1978         frag->fixed = 1;
1979
1980         return 0;
1981 }
1982
1983
1984 static int ieee80211_ioctl_siwretry(struct net_device *dev,
1985                                     struct iw_request_info *info,
1986                                     struct iw_param *retry, char *extra)
1987 {
1988         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1989
1990         if (retry->disabled ||
1991             (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
1992                 return -EINVAL;
1993
1994         if (retry->flags & IW_RETRY_MAX)
1995                 local->long_retry_limit = retry->value;
1996         else if (retry->flags & IW_RETRY_MIN)
1997                 local->short_retry_limit = retry->value;
1998         else {
1999                 local->long_retry_limit = retry->value;
2000                 local->short_retry_limit = retry->value;
2001         }
2002
2003         if (local->ops->set_retry_limit) {
2004                 return local->ops->set_retry_limit(
2005                         local_to_hw(local),
2006                         local->short_retry_limit,
2007                         local->long_retry_limit);
2008         }
2009
2010         return 0;
2011 }
2012
2013
2014 static int ieee80211_ioctl_giwretry(struct net_device *dev,
2015                                     struct iw_request_info *info,
2016                                     struct iw_param *retry, char *extra)
2017 {
2018         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2019
2020         retry->disabled = 0;
2021         if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
2022                 /* first return min value, iwconfig will ask max value
2023                  * later if needed */
2024                 retry->flags |= IW_RETRY_LIMIT;
2025                 retry->value = local->short_retry_limit;
2026                 if (local->long_retry_limit != local->short_retry_limit)
2027                         retry->flags |= IW_RETRY_MIN;
2028                 return 0;
2029         }
2030         if (retry->flags & IW_RETRY_MAX) {
2031                 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
2032                 retry->value = local->long_retry_limit;
2033         }
2034
2035         return 0;
2036 }
2037
2038 static int ieee80211_ioctl_clear_keys(struct net_device *dev)
2039 {
2040         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2041         struct ieee80211_key_conf key;
2042         int i;
2043         u8 addr[ETH_ALEN];
2044         struct ieee80211_key_conf *keyconf;
2045         struct ieee80211_sub_if_data *sdata;
2046         struct sta_info *sta;
2047
2048         memset(addr, 0xff, ETH_ALEN);
2049         read_lock(&local->sub_if_lock);
2050         list_for_each_entry(sdata, &local->sub_if_list, list) {
2051                 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
2052                         keyconf = NULL;
2053                         if (sdata->keys[i] &&
2054                             !sdata->keys[i]->force_sw_encrypt &&
2055                             local->ops->set_key &&
2056                             (keyconf = ieee80211_key_data2conf(local,
2057                                                                sdata->keys[i])))
2058                                 local->ops->set_key(local_to_hw(local),
2059                                                    DISABLE_KEY, addr,
2060                                                    keyconf, 0);
2061                         kfree(keyconf);
2062                         ieee80211_key_free(sdata->keys[i]);
2063                         sdata->keys[i] = NULL;
2064                 }
2065                 sdata->default_key = NULL;
2066         }
2067         read_unlock(&local->sub_if_lock);
2068
2069         spin_lock_bh(&local->sta_lock);
2070         list_for_each_entry(sta, &local->sta_list, list) {
2071                 keyconf = NULL;
2072                 if (sta->key && !sta->key->force_sw_encrypt &&
2073                     local->ops->set_key &&
2074                     (keyconf = ieee80211_key_data2conf(local, sta->key)))
2075                         local->ops->set_key(local_to_hw(local), DISABLE_KEY,
2076                                            sta->addr, keyconf, sta->aid);
2077                 kfree(keyconf);
2078                 ieee80211_key_free(sta->key);
2079                 sta->key = NULL;
2080         }
2081         spin_unlock_bh(&local->sta_lock);
2082
2083         memset(&key, 0, sizeof(key));
2084         if (local->ops->set_key &&
2085                     local->ops->set_key(local_to_hw(local), REMOVE_ALL_KEYS,
2086                                        NULL, &key, 0))
2087                 printk(KERN_DEBUG "%s: failed to remove hwaccel keys\n",
2088                        dev->name);
2089
2090         return 0;
2091 }
2092
2093
2094 static int
2095 ieee80211_ioctl_force_unicast_rate(struct net_device *dev,
2096                                    struct ieee80211_sub_if_data *sdata,
2097                                    int rate)
2098 {
2099         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2100         struct ieee80211_hw_mode *mode;
2101         int i;
2102
2103         if (sdata->type != IEEE80211_IF_TYPE_AP)
2104                 return -ENOENT;
2105
2106         if (rate == 0) {
2107                 sdata->u.ap.force_unicast_rateidx = -1;
2108                 return 0;
2109         }
2110
2111         mode = local->oper_hw_mode;
2112         for (i = 0; i < mode->num_rates; i++) {
2113                 if (mode->rates[i].rate == rate) {
2114                         sdata->u.ap.force_unicast_rateidx = i;
2115                         return 0;
2116                 }
2117         }
2118         return -EINVAL;
2119 }
2120
2121
2122 static int
2123 ieee80211_ioctl_max_ratectrl_rate(struct net_device *dev,
2124                                   struct ieee80211_sub_if_data *sdata,
2125                                   int rate)
2126 {
2127         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2128         struct ieee80211_hw_mode *mode;
2129         int i;
2130
2131         if (sdata->type != IEEE80211_IF_TYPE_AP)
2132                 return -ENOENT;
2133
2134         if (rate == 0) {
2135                 sdata->u.ap.max_ratectrl_rateidx = -1;
2136                 return 0;
2137         }
2138
2139         mode = local->oper_hw_mode;
2140         for (i = 0; i < mode->num_rates; i++) {
2141                 if (mode->rates[i].rate == rate) {
2142                         sdata->u.ap.max_ratectrl_rateidx = i;
2143                         return 0;
2144                 }
2145         }
2146         return -EINVAL;
2147 }
2148
2149
2150 static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
2151                                          struct ieee80211_key *key)
2152 {
2153         struct ieee80211_key_conf *keyconf;
2154         u8 addr[ETH_ALEN];
2155
2156         if (!key || key->alg != ALG_WEP || !key->force_sw_encrypt ||
2157             (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
2158                 return;
2159
2160         memset(addr, 0xff, ETH_ALEN);
2161         keyconf = ieee80211_key_data2conf(local, key);
2162         if (keyconf && local->ops->set_key &&
2163             local->ops->set_key(local_to_hw(local),
2164                                SET_KEY, addr, keyconf, 0) == 0) {
2165                 key->force_sw_encrypt =
2166                         !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
2167                 key->hw_key_idx = keyconf->hw_key_idx;
2168         }
2169         kfree(keyconf);
2170 }
2171
2172
2173 static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local,
2174                                           struct ieee80211_key *key)
2175 {
2176         struct ieee80211_key_conf *keyconf;
2177         u8 addr[ETH_ALEN];
2178
2179         if (!key || key->alg != ALG_WEP || key->force_sw_encrypt ||
2180             (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
2181                 return;
2182
2183         memset(addr, 0xff, ETH_ALEN);
2184         keyconf = ieee80211_key_data2conf(local, key);
2185         if (keyconf && local->ops->set_key)
2186                 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
2187                                    addr, keyconf, 0);
2188         kfree(keyconf);
2189         key->force_sw_encrypt = 1;
2190 }
2191
2192
2193 static int ieee80211_ioctl_default_wep_only(struct ieee80211_local *local,
2194                                             int value)
2195 {
2196         int i;
2197         struct ieee80211_sub_if_data *sdata;
2198
2199         local->default_wep_only = value;
2200         read_lock(&local->sub_if_lock);
2201         list_for_each_entry(sdata, &local->sub_if_list, list)
2202                 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
2203                         if (value)
2204                                 ieee80211_key_enable_hwaccel(local,
2205                                                              sdata->keys[i]);
2206                         else
2207                                 ieee80211_key_disable_hwaccel(local,
2208                                                               sdata->keys[i]);
2209         read_unlock(&local->sub_if_lock);
2210
2211         return 0;
2212 }
2213
2214
2215 void ieee80211_update_default_wep_only(struct ieee80211_local *local)
2216 {
2217         int i = 0;
2218         struct ieee80211_sub_if_data *sdata;
2219
2220         read_lock(&local->sub_if_lock);
2221         list_for_each_entry(sdata, &local->sub_if_list, list) {
2222
2223                 if (sdata->dev == local->mdev)
2224                         continue;
2225
2226                 /* If there is an AP interface then depend on userspace to
2227                    set default_wep_only correctly. */
2228                 if (sdata->type == IEEE80211_IF_TYPE_AP) {
2229                         read_unlock(&local->sub_if_lock);
2230                         return;
2231                 }
2232
2233                 i++;
2234         }
2235
2236         read_unlock(&local->sub_if_lock);
2237
2238         if (i <= 1)
2239                 ieee80211_ioctl_default_wep_only(local, 1);
2240         else
2241                 ieee80211_ioctl_default_wep_only(local, 0);
2242 }
2243
2244
2245 static int ieee80211_ioctl_prism2_param(struct net_device *dev,
2246                                         struct iw_request_info *info,
2247                                         void *wrqu, char *extra)
2248 {
2249         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2250         struct ieee80211_sub_if_data *sdata;
2251         int *i = (int *) extra;
2252         int param = *i;
2253         int value = *(i + 1);
2254         int ret = 0;
2255
2256         if (!capable(CAP_NET_ADMIN))
2257                 return -EPERM;
2258
2259         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2260
2261         switch (param) {
2262         case PRISM2_PARAM_HOST_ENCRYPT:
2263         case PRISM2_PARAM_HOST_DECRYPT:
2264                 /* TODO: implement these; return success now to prevent
2265                  * hostapd from aborting */
2266                 break;
2267
2268         case PRISM2_PARAM_BEACON_INT:
2269                 local->hw.conf.beacon_int = value;
2270                 if (ieee80211_hw_config(local))
2271                         ret = -EINVAL;
2272                 break;
2273
2274         case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2275                 local->bridge_packets = value;
2276                 break;
2277
2278         case PRISM2_PARAM_AP_AUTH_ALGS:
2279                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
2280                     sdata->type == IEEE80211_IF_TYPE_IBSS) {
2281                         sdata->u.sta.auth_algs = value;
2282                 } else
2283                         ret = -EOPNOTSUPP;
2284                 break;
2285
2286         case PRISM2_PARAM_DTIM_PERIOD:
2287                 if (value < 1)
2288                         ret = -EINVAL;
2289                 else if (sdata->type != IEEE80211_IF_TYPE_AP)
2290                         ret = -ENOENT;
2291                 else
2292                         sdata->u.ap.dtim_period = value;
2293                 break;
2294
2295         case PRISM2_PARAM_IEEE_802_1X:
2296                 if (local->ops->set_ieee8021x)
2297                         ret = local->ops->set_ieee8021x(local_to_hw(local),
2298                                                         value);
2299                 if (ret)
2300                         printk(KERN_DEBUG "%s: failed to set IEEE 802.1X (%d) "
2301                                "for low-level driver\n", dev->name, value);
2302                 else
2303                         sdata->ieee802_1x = value;
2304                 break;
2305
2306         case PRISM2_PARAM_ANTSEL_TX:
2307                 local->hw.conf.antenna_sel_tx = value;
2308                 if (ieee80211_hw_config(local))
2309                         ret = -EINVAL;
2310                 break;
2311
2312         case PRISM2_PARAM_ANTSEL_RX:
2313                 local->hw.conf.antenna_sel_rx = value;
2314                 if (ieee80211_hw_config(local))
2315                         ret = -EINVAL;
2316                 break;
2317
2318         case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
2319                 local->cts_protect_erp_frames = value;
2320                 break;
2321
2322         case PRISM2_PARAM_DROP_UNENCRYPTED:
2323                 sdata->drop_unencrypted = value;
2324                 break;
2325
2326         case PRISM2_PARAM_PREAMBLE:
2327                 local->short_preamble = value;
2328                 break;
2329
2330         case PRISM2_PARAM_STAT_TIME:
2331                 if (!local->stat_time && value) {
2332                         local->stat_timer.expires = jiffies + HZ * value / 100;
2333                         add_timer(&local->stat_timer);
2334                 } else if (local->stat_time && !value) {
2335                         del_timer_sync(&local->stat_timer);
2336                 }
2337                 local->stat_time = value;
2338                 break;
2339         case PRISM2_PARAM_SHORT_SLOT_TIME:
2340                 if (value)
2341                         local->hw.conf.flags |= IEEE80211_CONF_SHORT_SLOT_TIME;
2342                 else
2343                         local->hw.conf.flags &= ~IEEE80211_CONF_SHORT_SLOT_TIME;
2344                 if (ieee80211_hw_config(local))
2345                         ret = -EINVAL;
2346                 break;
2347
2348         case PRISM2_PARAM_PRIVACY_INVOKED:
2349                 if (local->ops->set_privacy_invoked)
2350                         ret = local->ops->set_privacy_invoked(
2351                                         local_to_hw(local), value);
2352                 break;
2353
2354         case PRISM2_PARAM_NEXT_MODE:
2355                 local->next_mode = value;
2356                 break;
2357
2358         case PRISM2_PARAM_CLEAR_KEYS:
2359                 ret = ieee80211_ioctl_clear_keys(dev);
2360                 break;
2361
2362         case PRISM2_PARAM_RADIO_ENABLED:
2363                 ret = ieee80211_ioctl_set_radio_enabled(dev, value);
2364                 break;
2365
2366         case PRISM2_PARAM_ANTENNA_MODE:
2367                 local->hw.conf.antenna_mode = value;
2368                 if (ieee80211_hw_config(local))
2369                         ret = -EINVAL;
2370                 break;
2371
2372         case PRISM2_PARAM_BROADCAST_SSID:
2373                 if ((value < 0) || (value > 1))
2374                         ret = -EINVAL;
2375                 else if (value)
2376                         local->hw.conf.flags |= IEEE80211_CONF_SSID_HIDDEN;
2377                 else
2378                         local->hw.conf.flags &= ~IEEE80211_CONF_SSID_HIDDEN;
2379                 break;
2380
2381         case PRISM2_PARAM_STA_ANTENNA_SEL:
2382                 local->sta_antenna_sel = value;
2383                 break;
2384
2385         case PRISM2_PARAM_FORCE_UNICAST_RATE:
2386                 ret = ieee80211_ioctl_force_unicast_rate(dev, sdata, value);
2387                 break;
2388
2389         case PRISM2_PARAM_MAX_RATECTRL_RATE:
2390                 ret = ieee80211_ioctl_max_ratectrl_rate(dev, sdata, value);
2391                 break;
2392
2393         case PRISM2_PARAM_RATE_CTRL_NUM_UP:
2394                 local->rate_ctrl_num_up = value;
2395                 break;
2396
2397         case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:
2398                 local->rate_ctrl_num_down = value;
2399                 break;
2400
2401         case PRISM2_PARAM_TX_POWER_REDUCTION:
2402                 if (value < 0)
2403                         ret = -EINVAL;
2404                 else
2405                         local->hw.conf.tx_power_reduction = value;
2406                 break;
2407
2408         case PRISM2_PARAM_EAPOL:
2409                 sdata->eapol = value;
2410                 break;
2411
2412         case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
2413                 local->key_tx_rx_threshold = value;
2414                 break;
2415
2416         case PRISM2_PARAM_KEY_INDEX:
2417                 if (value < 0 || value >= NUM_DEFAULT_KEYS)
2418                         ret = -EINVAL;
2419                 else if (!sdata->keys[value])
2420                         ret = -ENOENT;
2421                 else
2422                         sdata->default_key = sdata->keys[value];
2423                 break;
2424
2425         case PRISM2_PARAM_DEFAULT_WEP_ONLY:
2426                 ret = ieee80211_ioctl_default_wep_only(local, value);
2427                 break;
2428
2429         case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
2430                 local->wifi_wme_noack_test = value;
2431                 break;
2432
2433         case PRISM2_PARAM_ALLOW_BROADCAST_ALWAYS:
2434                 local->allow_broadcast_always = value;
2435                 break;
2436
2437         case PRISM2_PARAM_SCAN_FLAGS:
2438                 local->scan_flags = value;
2439                 break;
2440
2441         case PRISM2_PARAM_MIXED_CELL:
2442                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
2443                     sdata->type != IEEE80211_IF_TYPE_IBSS)
2444                         ret = -EINVAL;
2445                 else
2446                         sdata->u.sta.mixed_cell = !!value;
2447                 break;
2448
2449         case PRISM2_PARAM_KEY_MGMT:
2450                 if (sdata->type != IEEE80211_IF_TYPE_STA)
2451                         ret = -EINVAL;
2452                 else
2453                         sdata->u.sta.key_mgmt = value;
2454                 break;
2455
2456         case PRISM2_PARAM_HW_MODES:
2457                 local->enabled_modes = value;
2458                 break;
2459
2460         case PRISM2_PARAM_CREATE_IBSS:
2461                 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
2462                         ret = -EINVAL;
2463                 else
2464                         sdata->u.sta.create_ibss = !!value;
2465                 break;
2466         case PRISM2_PARAM_WMM_ENABLED:
2467                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
2468                     sdata->type != IEEE80211_IF_TYPE_IBSS)
2469                         ret = -EINVAL;
2470                 else
2471                         sdata->u.sta.wmm_enabled = !!value;
2472                 break;
2473         case PRISM2_PARAM_RADAR_DETECT:
2474                 local->hw.conf.radar_detect = value;
2475                 break;
2476         case PRISM2_PARAM_SPECTRUM_MGMT:
2477                 local->hw.conf.spect_mgmt = value;
2478                 break;
2479         case PRISM2_PARAM_MGMT_IF:
2480                 if (value == 1) {
2481                         if (!local->apdev)
2482                                 ret = ieee80211_if_add_mgmt(local);
2483                 } else if (value == 0) {
2484                         if (local->apdev)
2485                                 ieee80211_if_del_mgmt(local);
2486                 } else
2487                         ret = -EINVAL;
2488                 break;
2489         case PRISM2_PARAM_USER_SPACE_MLME:
2490                 local->user_space_mlme = value;
2491                 break;
2492         default:
2493                 ret = -EOPNOTSUPP;
2494                 break;
2495         }
2496
2497         return ret;
2498 }
2499
2500
2501 static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
2502                                             struct iw_request_info *info,
2503                                             void *wrqu, char *extra)
2504 {
2505         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2506         struct ieee80211_sub_if_data *sdata;
2507         int *param = (int *) extra;
2508         int ret = 0;
2509
2510         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2511
2512         switch (*param) {
2513         case PRISM2_PARAM_BEACON_INT:
2514                 *param = local->hw.conf.beacon_int;
2515                 break;
2516
2517         case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2518                 *param = local->bridge_packets;
2519                 break;
2520
2521         case PRISM2_PARAM_AP_AUTH_ALGS:
2522                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
2523                     sdata->type == IEEE80211_IF_TYPE_IBSS) {
2524                         *param = sdata->u.sta.auth_algs;
2525                 } else
2526                         ret = -EOPNOTSUPP;
2527                 break;
2528
2529         case PRISM2_PARAM_DTIM_PERIOD:
2530                 if (sdata->type != IEEE80211_IF_TYPE_AP)
2531                         ret = -ENOENT;
2532                 else
2533                         *param = sdata->u.ap.dtim_period;
2534                 break;
2535
2536         case PRISM2_PARAM_IEEE_802_1X:
2537                 *param = sdata->ieee802_1x;
2538                 break;
2539
2540         case PRISM2_PARAM_ANTSEL_TX:
2541                 *param = local->hw.conf.antenna_sel_tx;
2542                 break;
2543
2544         case PRISM2_PARAM_ANTSEL_RX:
2545                 *param = local->hw.conf.antenna_sel_rx;
2546                 break;
2547
2548         case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
2549                 *param = local->cts_protect_erp_frames;
2550                 break;
2551
2552         case PRISM2_PARAM_DROP_UNENCRYPTED:
2553                 *param = sdata->drop_unencrypted;
2554                 break;
2555
2556         case PRISM2_PARAM_PREAMBLE:
2557                 *param = local->short_preamble;
2558                 break;
2559
2560         case PRISM2_PARAM_STAT_TIME:
2561                 *param = local->stat_time;
2562                 break;
2563         case PRISM2_PARAM_SHORT_SLOT_TIME:
2564                 *param = !!(local->hw.conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME);
2565                 break;
2566
2567         case PRISM2_PARAM_NEXT_MODE:
2568                 *param = local->next_mode;
2569                 break;
2570
2571         case PRISM2_PARAM_ANTENNA_MODE:
2572                 *param = local->hw.conf.antenna_mode;
2573                 break;
2574
2575         case PRISM2_PARAM_BROADCAST_SSID:
2576                 *param = !!(local->hw.conf.flags & IEEE80211_CONF_SSID_HIDDEN);
2577                 break;
2578
2579         case PRISM2_PARAM_STA_ANTENNA_SEL:
2580                 *param = local->sta_antenna_sel;
2581                 break;
2582
2583         case PRISM2_PARAM_RATE_CTRL_NUM_UP:
2584                 *param = local->rate_ctrl_num_up;
2585                 break;
2586
2587         case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:
2588                 *param = local->rate_ctrl_num_down;
2589                 break;
2590
2591         case PRISM2_PARAM_TX_POWER_REDUCTION:
2592                 *param = local->hw.conf.tx_power_reduction;
2593                 break;
2594
2595         case PRISM2_PARAM_EAPOL:
2596                 *param = sdata->eapol;
2597                 break;
2598
2599         case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
2600                 *param = local->key_tx_rx_threshold;
2601                 break;
2602
2603         case PRISM2_PARAM_KEY_INDEX:
2604                 if (!sdata->default_key)
2605                         ret = -ENOENT;
2606                 else if (sdata->default_key == sdata->keys[0])
2607                         *param = 0;
2608                 else if (sdata->default_key == sdata->keys[1])
2609                         *param = 1;
2610                 else if (sdata->default_key == sdata->keys[2])
2611                         *param = 2;
2612                 else if (sdata->default_key == sdata->keys[3])
2613                         *param = 3;
2614                 else
2615                         ret = -ENOENT;
2616                 break;
2617
2618         case PRISM2_PARAM_DEFAULT_WEP_ONLY:
2619                 *param = local->default_wep_only;
2620                 break;
2621
2622         case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
2623                 *param = local->wifi_wme_noack_test;
2624                 break;
2625
2626         case PRISM2_PARAM_ALLOW_BROADCAST_ALWAYS:
2627                 *param = local->allow_broadcast_always;
2628                 break;
2629
2630         case PRISM2_PARAM_SCAN_FLAGS:
2631                 *param = local->scan_flags;
2632                 break;
2633
2634         case PRISM2_PARAM_HW_MODES:
2635                 *param = local->enabled_modes;
2636                 break;
2637
2638         case PRISM2_PARAM_CREATE_IBSS:
2639                 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
2640                         ret = -EINVAL;
2641                 else
2642                         *param = !!sdata->u.sta.create_ibss;
2643                 break;
2644
2645         case PRISM2_PARAM_MIXED_CELL:
2646                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
2647                     sdata->type != IEEE80211_IF_TYPE_IBSS)
2648                         ret = -EINVAL;
2649                 else
2650                         *param = !!sdata->u.sta.mixed_cell;
2651                 break;
2652
2653         case PRISM2_PARAM_KEY_MGMT:
2654                 if (sdata->type != IEEE80211_IF_TYPE_STA)
2655                         ret = -EINVAL;
2656                 else
2657                         *param = sdata->u.sta.key_mgmt;
2658                 break;
2659         case PRISM2_PARAM_WMM_ENABLED:
2660                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
2661                     sdata->type != IEEE80211_IF_TYPE_IBSS)
2662                         ret = -EINVAL;
2663                 else
2664                         *param = !!sdata->u.sta.wmm_enabled;
2665                 break;
2666         case PRISM2_PARAM_MGMT_IF:
2667                 if (local->apdev)
2668                         *param = local->apdev->ifindex;
2669                 else
2670                         ret = -ENOENT;
2671                 break;
2672         case PRISM2_PARAM_USER_SPACE_MLME:
2673                 *param = local->user_space_mlme;
2674                 break;
2675
2676         default:
2677                 ret = -EOPNOTSUPP;
2678                 break;
2679         }
2680
2681         return ret;
2682 }
2683
2684 static int ieee80211_ioctl_siwmlme(struct net_device *dev,
2685                                    struct iw_request_info *info,
2686                                    struct iw_point *data, char *extra)
2687 {
2688         struct ieee80211_sub_if_data *sdata;
2689         struct iw_mlme *mlme = (struct iw_mlme *) extra;
2690
2691         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2692         if (sdata->type != IEEE80211_IF_TYPE_STA &&
2693             sdata->type != IEEE80211_IF_TYPE_IBSS)
2694                 return -EINVAL;
2695
2696         switch (mlme->cmd) {
2697         case IW_MLME_DEAUTH:
2698                 /* TODO: mlme->addr.sa_data */
2699                 return ieee80211_sta_deauthenticate(dev, mlme->reason_code);
2700         case IW_MLME_DISASSOC:
2701                 /* TODO: mlme->addr.sa_data */
2702                 return ieee80211_sta_disassociate(dev, mlme->reason_code);
2703         default:
2704                 return -EOPNOTSUPP;
2705         }
2706 }
2707
2708
2709 static int ieee80211_ioctl_siwencode(struct net_device *dev,
2710                                      struct iw_request_info *info,
2711                                      struct iw_point *erq, char *keybuf)
2712 {
2713         struct ieee80211_sub_if_data *sdata;
2714         int idx, i, alg = ALG_WEP;
2715         u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2716
2717         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2718
2719         idx = erq->flags & IW_ENCODE_INDEX;
2720         if (idx == 0) {
2721                 if (sdata->default_key)
2722                         for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
2723                                 if (sdata->default_key == sdata->keys[i]) {
2724                                         idx = i;
2725                                         break;
2726                                 }
2727                         }
2728         } else if (idx < 1 || idx > 4)
2729                 return -EINVAL;
2730         else
2731                 idx--;
2732
2733         if (erq->flags & IW_ENCODE_DISABLED)
2734                 alg = ALG_NONE;
2735         else if (erq->length == 0) {
2736                 /* No key data - just set the default TX key index */
2737                 if (sdata->default_key != sdata->keys[idx]) {
2738                         ieee80211_debugfs_key_remove_default(sdata);
2739                         sdata->default_key = sdata->keys[idx];
2740                         if (sdata->default_key)
2741                                 ieee80211_debugfs_key_add_default(sdata);
2742                 }
2743                 return 0;
2744         }
2745
2746         return ieee80211_set_encryption(
2747                 dev, bcaddr,
2748                 idx, alg,
2749                 !sdata->default_key,
2750                 NULL, keybuf, erq->length);
2751 }
2752
2753
2754 static int ieee80211_ioctl_giwencode(struct net_device *dev,
2755                                      struct iw_request_info *info,
2756                                      struct iw_point *erq, char *key)
2757 {
2758         struct ieee80211_sub_if_data *sdata;
2759         int idx, i;
2760
2761         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2762
2763         idx = erq->flags & IW_ENCODE_INDEX;
2764         if (idx < 1 || idx > 4) {
2765                 idx = -1;
2766                 if (!sdata->default_key)
2767                         idx = 0;
2768                 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
2769                         if (sdata->default_key == sdata->keys[i]) {
2770                                 idx = i;
2771                                 break;
2772                         }
2773                 }
2774                 if (idx < 0)
2775                         return -EINVAL;
2776         } else
2777                 idx--;
2778
2779         erq->flags = idx + 1;
2780
2781         if (!sdata->keys[idx]) {
2782                 erq->length = 0;
2783                 erq->flags |= IW_ENCODE_DISABLED;
2784                 return 0;
2785         }
2786
2787         memcpy(key, sdata->keys[idx]->key,
2788                min((int)erq->length, sdata->keys[idx]->keylen));
2789         erq->length = sdata->keys[idx]->keylen;
2790         erq->flags |= IW_ENCODE_ENABLED;
2791
2792         return 0;
2793 }
2794
2795
2796 static int ieee80211_ioctl_siwgenie(struct net_device *dev,
2797                                     struct iw_request_info *info,
2798                                     struct iw_point *data, char *extra)
2799 {
2800         return ieee80211_set_gen_ie(dev, extra, data->length);
2801 }
2802
2803
2804 static int ieee80211_ioctl_siwauth(struct net_device *dev,
2805                                    struct iw_request_info *info,
2806                                    struct iw_param *data, char *extra)
2807 {
2808         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2809         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2810         int ret = 0;
2811
2812         switch (data->flags & IW_AUTH_INDEX) {
2813         case IW_AUTH_WPA_VERSION:
2814         case IW_AUTH_CIPHER_PAIRWISE:
2815         case IW_AUTH_CIPHER_GROUP:
2816         case IW_AUTH_WPA_ENABLED:
2817         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2818                 break;
2819         case IW_AUTH_KEY_MGMT:
2820                 if (sdata->type != IEEE80211_IF_TYPE_STA)
2821                         ret = -EINVAL;
2822                 else {
2823                         /*
2824                          * TODO: sdata->u.sta.key_mgmt does not match with WE18
2825                          * value completely; could consider modifying this to
2826                          * be closer to WE18. For now, this value is not really
2827                          * used for anything else than Privacy matching, so the
2828                          * current code here should be more or less OK.
2829                          */
2830                         if (data->value & IW_AUTH_KEY_MGMT_802_1X) {
2831                                 sdata->u.sta.key_mgmt =
2832                                         IEEE80211_KEY_MGMT_WPA_EAP;
2833                         } else if (data->value & IW_AUTH_KEY_MGMT_PSK) {
2834                                 sdata->u.sta.key_mgmt =
2835                                         IEEE80211_KEY_MGMT_WPA_PSK;
2836                         } else {
2837                                 sdata->u.sta.key_mgmt =
2838                                         IEEE80211_KEY_MGMT_NONE;
2839                         }
2840                 }
2841                 break;
2842         case IW_AUTH_80211_AUTH_ALG:
2843                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
2844                     sdata->type == IEEE80211_IF_TYPE_IBSS)
2845                         sdata->u.sta.auth_algs = data->value;
2846                 else
2847                         ret = -EOPNOTSUPP;
2848                 break;
2849         case IW_AUTH_PRIVACY_INVOKED:
2850                 if (local->ops->set_privacy_invoked)
2851                         ret = local->ops->set_privacy_invoked(
2852                                         local_to_hw(local), data->value);
2853                 break;
2854         default:
2855                 ret = -EOPNOTSUPP;
2856                 break;
2857         }
2858         return ret;
2859 }
2860
2861 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
2862 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
2863 {
2864         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2865         struct iw_statistics *wstats = &local->wstats;
2866         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2867         struct sta_info *sta = NULL;
2868
2869         if (sdata->type == IEEE80211_IF_TYPE_STA ||
2870             sdata->type == IEEE80211_IF_TYPE_IBSS)
2871                 sta = sta_info_get(local, sdata->u.sta.bssid);
2872         if (!sta) {
2873                 wstats->discard.fragment = 0;
2874                 wstats->discard.misc = 0;
2875                 wstats->qual.qual = 0;
2876                 wstats->qual.level = 0;
2877                 wstats->qual.noise = 0;
2878                 wstats->qual.updated = IW_QUAL_ALL_INVALID;
2879         } else {
2880                 wstats->qual.level = sta->last_rssi;
2881                 wstats->qual.qual = sta->last_signal;
2882                 wstats->qual.noise = sta->last_noise;
2883                 wstats->qual.updated = local->wstats_flags;
2884                 sta_info_put(sta);
2885         }
2886         return wstats;
2887 }
2888
2889 static int ieee80211_ioctl_giwauth(struct net_device *dev,
2890                                    struct iw_request_info *info,
2891                                    struct iw_param *data, char *extra)
2892 {
2893         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2894         int ret = 0;
2895
2896         switch (data->flags & IW_AUTH_INDEX) {
2897         case IW_AUTH_80211_AUTH_ALG:
2898                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
2899                     sdata->type == IEEE80211_IF_TYPE_IBSS)
2900                         data->value = sdata->u.sta.auth_algs;
2901                 else
2902                         ret = -EOPNOTSUPP;
2903                 break;
2904         default:
2905                 ret = -EOPNOTSUPP;
2906                 break;
2907         }
2908         return ret;
2909 }
2910
2911
2912 static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
2913                                         struct iw_request_info *info,
2914                                         struct iw_point *erq, char *extra)
2915 {
2916         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2917         struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
2918         int alg, idx, i;
2919
2920         switch (ext->alg) {
2921         case IW_ENCODE_ALG_NONE:
2922                 alg = ALG_NONE;
2923                 break;
2924         case IW_ENCODE_ALG_WEP:
2925                 alg = ALG_WEP;
2926                 break;
2927         case IW_ENCODE_ALG_TKIP:
2928                 alg = ALG_TKIP;
2929                 break;
2930         case IW_ENCODE_ALG_CCMP:
2931                 alg = ALG_CCMP;
2932                 break;
2933         default:
2934                 return -EOPNOTSUPP;
2935         }
2936
2937         if (erq->flags & IW_ENCODE_DISABLED)
2938                 alg = ALG_NONE;
2939
2940         idx = erq->flags & IW_ENCODE_INDEX;
2941         if (idx < 1 || idx > 4) {
2942                 idx = -1;
2943                 if (!sdata->default_key)
2944                         idx = 0;
2945                 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
2946                         if (sdata->default_key == sdata->keys[i]) {
2947                                 idx = i;
2948                                 break;
2949                         }
2950                 }
2951                 if (idx < 0)
2952                         return -EINVAL;
2953         } else
2954                 idx--;
2955
2956         return ieee80211_set_encryption(dev, ext->addr.sa_data, idx, alg,
2957                                         ext->ext_flags &
2958                                         IW_ENCODE_EXT_SET_TX_KEY,
2959                                         NULL, ext->key, ext->key_len);
2960 }
2961
2962
2963 static const struct iw_priv_args ieee80211_ioctl_priv[] = {
2964         { PRISM2_IOCTL_PRISM2_PARAM,
2965           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" },
2966         { PRISM2_IOCTL_GET_PRISM2_PARAM,
2967           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2968           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" },
2969 };
2970
2971
2972 int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2973 {
2974         struct iwreq *wrq = (struct iwreq *) rq;
2975         int ret = 0;
2976
2977         switch (cmd) {
2978                 /* Private ioctls (iwpriv) that have not yet been converted
2979                  * into new wireless extensions API */
2980         case PRISM2_IOCTL_HOSTAPD:
2981                 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
2982                 else ret = ieee80211_ioctl_priv_hostapd(dev, &wrq->u.data);
2983                 break;
2984         default:
2985                 ret = -EOPNOTSUPP;
2986                 break;
2987         }
2988
2989         return ret;
2990 }
2991
2992
2993 /* Structures to export the Wireless Handlers */
2994
2995 static const iw_handler ieee80211_handler[] =
2996 {
2997         (iw_handler) NULL,                              /* SIOCSIWCOMMIT */
2998         (iw_handler) ieee80211_ioctl_giwname,           /* SIOCGIWNAME */
2999         (iw_handler) NULL,                              /* SIOCSIWNWID */
3000         (iw_handler) NULL,                              /* SIOCGIWNWID */
3001         (iw_handler) ieee80211_ioctl_siwfreq,           /* SIOCSIWFREQ */
3002         (iw_handler) ieee80211_ioctl_giwfreq,           /* SIOCGIWFREQ */
3003         (iw_handler) ieee80211_ioctl_siwmode,           /* SIOCSIWMODE */
3004         (iw_handler) ieee80211_ioctl_giwmode,           /* SIOCGIWMODE */
3005         (iw_handler) NULL,                              /* SIOCSIWSENS */
3006         (iw_handler) NULL,                              /* SIOCGIWSENS */
3007         (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE */
3008         (iw_handler) ieee80211_ioctl_giwrange,          /* SIOCGIWRANGE */
3009         (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV */
3010         (iw_handler) NULL /* kernel code */,            /* SIOCGIWPRIV */
3011         (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS */
3012         (iw_handler) NULL /* kernel code */,            /* SIOCGIWSTATS */
3013         iw_handler_set_spy,                             /* SIOCSIWSPY */
3014         iw_handler_get_spy,                             /* SIOCGIWSPY */
3015         iw_handler_set_thrspy,                          /* SIOCSIWTHRSPY */
3016         iw_handler_get_thrspy,                          /* SIOCGIWTHRSPY */
3017         (iw_handler) ieee80211_ioctl_siwap,             /* SIOCSIWAP */
3018         (iw_handler) ieee80211_ioctl_giwap,             /* SIOCGIWAP */
3019         (iw_handler) ieee80211_ioctl_siwmlme,           /* SIOCSIWMLME */
3020         (iw_handler) NULL,                              /* SIOCGIWAPLIST */
3021         (iw_handler) ieee80211_ioctl_siwscan,           /* SIOCSIWSCAN */
3022         (iw_handler) ieee80211_ioctl_giwscan,           /* SIOCGIWSCAN */
3023         (iw_handler) ieee80211_ioctl_siwessid,          /* SIOCSIWESSID */
3024         (iw_handler) ieee80211_ioctl_giwessid,          /* SIOCGIWESSID */
3025         (iw_handler) NULL,                              /* SIOCSIWNICKN */
3026         (iw_handler) NULL,                              /* SIOCGIWNICKN */
3027         (iw_handler) NULL,                              /* -- hole -- */
3028         (iw_handler) NULL,                              /* -- hole -- */
3029         (iw_handler) NULL,                              /* SIOCSIWRATE */
3030         (iw_handler) ieee80211_ioctl_giwrate,           /* SIOCGIWRATE */
3031         (iw_handler) ieee80211_ioctl_siwrts,            /* SIOCSIWRTS */
3032         (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */
3033         (iw_handler) ieee80211_ioctl_siwfrag,           /* SIOCSIWFRAG */
3034         (iw_handler) ieee80211_ioctl_giwfrag,           /* SIOCGIWFRAG */
3035         (iw_handler) NULL,                              /* SIOCSIWTXPOW */
3036         (iw_handler) NULL,                              /* SIOCGIWTXPOW */
3037         (iw_handler) ieee80211_ioctl_siwretry,          /* SIOCSIWRETRY */
3038         (iw_handler) ieee80211_ioctl_giwretry,          /* SIOCGIWRETRY */
3039         (iw_handler) ieee80211_ioctl_siwencode,         /* SIOCSIWENCODE */
3040         (iw_handler) ieee80211_ioctl_giwencode,         /* SIOCGIWENCODE */
3041         (iw_handler) NULL,                              /* SIOCSIWPOWER */
3042         (iw_handler) NULL,                              /* SIOCGIWPOWER */
3043         (iw_handler) NULL,                              /* -- hole -- */
3044         (iw_handler) NULL,                              /* -- hole -- */
3045         (iw_handler) ieee80211_ioctl_siwgenie,          /* SIOCSIWGENIE */
3046         (iw_handler) NULL,                              /* SIOCGIWGENIE */
3047         (iw_handler) ieee80211_ioctl_siwauth,           /* SIOCSIWAUTH */
3048         (iw_handler) ieee80211_ioctl_giwauth,           /* SIOCGIWAUTH */
3049         (iw_handler) ieee80211_ioctl_siwencodeext,      /* SIOCSIWENCODEEXT */
3050         (iw_handler) NULL,                              /* SIOCGIWENCODEEXT */
3051         (iw_handler) NULL,                              /* SIOCSIWPMKSA */
3052         (iw_handler) NULL,                              /* -- hole -- */
3053 };
3054
3055 static const iw_handler ieee80211_private_handler[] =
3056 {                                                       /* SIOCIWFIRSTPRIV + */
3057         (iw_handler) ieee80211_ioctl_prism2_param,      /* 0 */
3058         (iw_handler) ieee80211_ioctl_get_prism2_param,  /* 1 */
3059 };
3060
3061 const struct iw_handler_def ieee80211_iw_handler_def =
3062 {
3063         .num_standard   = ARRAY_SIZE(ieee80211_handler),
3064         .num_private    = ARRAY_SIZE(ieee80211_private_handler),
3065         .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv),
3066         .standard       = (iw_handler *) ieee80211_handler,
3067         .private        = (iw_handler *) ieee80211_private_handler,
3068         .private_args   = (struct iw_priv_args *) ieee80211_ioctl_priv,
3069         .get_wireless_stats = ieee80211_get_wireless_stats,
3070 };