~ubuntu-branches/ubuntu/hardy/linux-backports-modules-2.6.24/hardy-security

« back to all changes in this revision

Viewing changes to updates/wireless/iwlwifi/mac80211/origin/net/mac80211/ieee80211_ioctl.c

  • Committer: Bazaar Package Importer
  • Author(s): , Ben Collins
  • Date: 2008-04-02 06:59:04 UTC
  • Revision ID: james.westby@ubuntu.com-20080402065904-e5knh2gn2hms3xbb
Tags: 2.6.24-14.11
[Ben Collins]

* iwlwifi: Update to iwlwifi-1.2.25 and mac80211-10.0.4
  - LP: #200950
* ubuntu: Slight cleanups to module hiearchy and Makefiles
* mac80211: Enable LED triggers
* iwlwifi: Add LED trigger support (rx and tx only)
  - LP: #176090

Show diffs side-by-side

added added

removed removed

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