2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.
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.
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>
22 #include <net/mac80211.h>
23 #include "ieee80211_i.h"
24 #include "hostapd_ioctl.h"
25 #include "ieee80211_rate.h"
28 #include "debugfs_key.h"
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
)
34 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
36 /* default to sw encryption; this will be cleared by low-level
37 * driver if the hw supports requested encryption */
39 key
->conf
.flags
|= IEEE80211_KEY_FORCE_SW_ENCRYPT
;
41 if (key
&& local
->ops
->set_key
) {
42 if (local
->ops
->set_key(local_to_hw(local
), SET_KEY
, addr
,
43 &key
->conf
, local
->default_wep_only
)) {
44 key
->conf
.flags
|= IEEE80211_KEY_FORCE_SW_ENCRYPT
;
45 key
->conf
.hw_key_idx
= HW_KEY_IDX_INVALID
;
51 static int ieee80211_set_encryption(struct net_device
*dev
, u8
*sta_addr
,
52 int idx
, int alg
, int set_tx_key
,
53 const u8
*_key
, size_t key_len
)
55 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
58 struct ieee80211_key
*key
, *old_key
;
60 struct ieee80211_sub_if_data
*sdata
;
62 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
64 if (is_broadcast_ether_addr(sta_addr
)) {
66 if (idx
>= NUM_DEFAULT_KEYS
) {
67 printk(KERN_DEBUG
"%s: set_encrypt - invalid idx=%d\n",
71 key
= sdata
->keys
[idx
];
73 /* TODO: consider adding hwaccel support for these; at least
74 * Atheros key cache should be able to handle this since AP is
75 * only transmitting frames with default keys. */
76 /* FIX: hw key cache can be used when only one virtual
77 * STA is associated with each AP. If more than one STA
78 * is associated to the same AP, software encryption
79 * must be used. This should be done automatically
80 * based on configured station devices. For the time
81 * being, this can be only set at compile time. */
85 printk(KERN_DEBUG
"%s: set_encrypt - non-zero idx for "
86 "individual key\n", dev
->name
);
90 sta
= sta_info_get(local
, sta_addr
);
92 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
93 printk(KERN_DEBUG
"%s: set_encrypt - unknown addr "
95 dev
->name
, MAC_ARG(sta_addr
));
96 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
105 * Cannot configure default hwaccel keys with WEP algorithm, if
106 * any of the virtual interfaces is using static WEP
107 * configuration because hwaccel would otherwise try to decrypt
110 * For now, just disable WEP hwaccel for broadcast when there is
111 * possibility of conflict with default keys. This can maybe later be
112 * optimized by using non-default keys (at least with Atheros ar521x).
114 if (!sta
&& alg
== ALG_WEP
&& !local
->default_wep_only
&&
115 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
&&
116 sdata
->type
!= IEEE80211_IF_TYPE_AP
) {
120 if (local
->hw
.flags
& IEEE80211_HW_DEVICE_HIDES_WEP
) {
121 /* Software encryption cannot be used with devices that hide
122 * encryption from the host system, so always try to use
123 * hardware acceleration with such devices. */
127 if ((local
->hw
.flags
& IEEE80211_HW_NO_TKIP_WMM_HWACCEL
) &&
129 if (sta
&& (sta
->flags
& WLAN_STA_WME
)) {
130 /* Hardware does not support hwaccel with TKIP when using WMM.
134 else if (sdata
->type
== IEEE80211_IF_TYPE_STA
) {
135 sta
= sta_info_get(local
, sdata
->u
.sta
.bssid
);
137 if (sta
->flags
& WLAN_STA_WME
) {
146 if (alg
== ALG_NONE
) {
147 if (try_hwaccel
&& key
&&
148 key
->conf
.hw_key_idx
!= HW_KEY_IDX_INVALID
&&
149 local
->ops
->set_key
&&
150 local
->ops
->set_key(local_to_hw(local
), DISABLE_KEY
,
151 sta_addr
, &key
->conf
,
152 local
->default_wep_only
)) {
153 printk(KERN_DEBUG
"%s: set_encrypt - low-level disable"
154 " failed\n", dev
->name
);
158 if (set_tx_key
|| sdata
->default_key
== key
) {
159 ieee80211_debugfs_key_remove_default(sdata
);
160 sdata
->default_key
= NULL
;
162 ieee80211_debugfs_key_remove(key
);
166 sdata
->keys
[idx
] = NULL
;
167 ieee80211_key_free(key
);
171 key
= ieee80211_key_alloc(sta
? NULL
: sdata
, idx
, key_len
,
178 /* default to sw encryption; low-level driver sets these if the
179 * requested encryption is supported */
180 key
->conf
.hw_key_idx
= HW_KEY_IDX_INVALID
;
181 key
->conf
.flags
|= IEEE80211_KEY_FORCE_SW_ENCRYPT
;
184 key
->conf
.keyidx
= idx
;
185 key
->conf
.keylen
= key_len
;
186 memcpy(key
->conf
.key
, _key
, key_len
);
188 if (alg
== ALG_CCMP
) {
189 /* Initialize AES key state here as an optimization
190 * so that it does not need to be initialized for every
192 key
->u
.ccmp
.tfm
= ieee80211_aes_key_setup_encrypt(
194 if (!key
->u
.ccmp
.tfm
) {
200 if (set_tx_key
|| sdata
->default_key
== old_key
) {
201 ieee80211_debugfs_key_remove_default(sdata
);
202 sdata
->default_key
= NULL
;
204 ieee80211_debugfs_key_remove(old_key
);
208 sdata
->keys
[idx
] = key
;
209 ieee80211_key_free(old_key
);
210 ieee80211_debugfs_key_add(local
, key
);
212 ieee80211_debugfs_key_sta_link(key
, sta
);
215 (alg
== ALG_WEP
|| alg
== ALG_TKIP
|| alg
== ALG_CCMP
))
216 ieee80211_set_hw_encryption(dev
, sta
, sta_addr
, key
);
219 if (set_tx_key
|| (!sta
&& !sdata
->default_key
&& key
)) {
220 sdata
->default_key
= key
;
222 ieee80211_debugfs_key_add_default(sdata
);
224 if (local
->ops
->set_key_idx
&&
225 local
->ops
->set_key_idx(local_to_hw(local
), idx
))
226 printk(KERN_DEBUG
"%s: failed to set TX key idx for "
227 "low-level driver\n", dev
->name
);
236 ieee80211_key_free(key
);
243 static int ieee80211_ioctl_siwgenie(struct net_device
*dev
,
244 struct iw_request_info
*info
,
245 struct iw_point
*data
, char *extra
)
247 struct ieee80211_sub_if_data
*sdata
;
248 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
250 if (local
->user_space_mlme
)
253 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
254 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
255 sdata
->type
== IEEE80211_IF_TYPE_IBSS
) {
256 int ret
= ieee80211_sta_set_extra_ie(dev
, extra
, data
->length
);
259 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_AUTO_BSSID_SEL
;
260 ieee80211_sta_req_auth(dev
, &sdata
->u
.sta
);
264 if (sdata
->type
== IEEE80211_IF_TYPE_AP
) {
265 kfree(sdata
->u
.ap
.generic_elem
);
266 sdata
->u
.ap
.generic_elem
= kmalloc(data
->length
, GFP_KERNEL
);
267 if (!sdata
->u
.ap
.generic_elem
)
269 memcpy(sdata
->u
.ap
.generic_elem
, extra
, data
->length
);
270 sdata
->u
.ap
.generic_elem_len
= data
->length
;
271 return ieee80211_if_config(dev
);
276 static int ieee80211_ioctl_giwname(struct net_device
*dev
,
277 struct iw_request_info
*info
,
278 char *name
, char *extra
)
280 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
282 switch (local
->hw
.conf
.phymode
) {
283 case MODE_IEEE80211A
:
284 strcpy(name
, "IEEE 802.11a");
286 case MODE_IEEE80211B
:
287 strcpy(name
, "IEEE 802.11b");
289 case MODE_IEEE80211G
:
290 strcpy(name
, "IEEE 802.11g");
292 case MODE_ATHEROS_TURBO
:
293 strcpy(name
, "5GHz Turbo");
296 strcpy(name
, "IEEE 802.11");
304 static int ieee80211_ioctl_giwrange(struct net_device
*dev
,
305 struct iw_request_info
*info
,
306 struct iw_point
*data
, char *extra
)
308 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
309 struct iw_range
*range
= (struct iw_range
*) extra
;
310 struct ieee80211_hw_mode
*mode
= NULL
;
313 data
->length
= sizeof(struct iw_range
);
314 memset(range
, 0, sizeof(struct iw_range
));
316 range
->we_version_compiled
= WIRELESS_EXT
;
317 range
->we_version_source
= 21;
318 range
->retry_capa
= IW_RETRY_LIMIT
;
319 range
->retry_flags
= IW_RETRY_LIMIT
;
320 range
->min_retry
= 0;
321 range
->max_retry
= 255;
323 range
->max_rts
= 2347;
324 range
->min_frag
= 256;
325 range
->max_frag
= 2346;
327 range
->encoding_size
[0] = 5;
328 range
->encoding_size
[1] = 13;
329 range
->num_encoding_sizes
= 2;
330 range
->max_encoding_tokens
= NUM_DEFAULT_KEYS
;
332 range
->max_qual
.qual
= local
->hw
.max_signal
;
333 range
->max_qual
.level
= local
->hw
.max_rssi
;
334 range
->max_qual
.noise
= local
->hw
.max_noise
;
335 range
->max_qual
.updated
= local
->wstats_flags
;
337 range
->avg_qual
.qual
= local
->hw
.max_signal
/2;
338 range
->avg_qual
.level
= 0;
339 range
->avg_qual
.noise
= 0;
340 range
->avg_qual
.updated
= local
->wstats_flags
;
342 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
343 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
345 list_for_each_entry(mode
, &local
->modes_list
, list
) {
348 if (!(local
->enabled_modes
& (1 << mode
->mode
)) ||
349 (local
->hw_modes
& local
->enabled_modes
&
350 (1 << MODE_IEEE80211G
) && mode
->mode
== MODE_IEEE80211B
))
353 while (i
< mode
->num_channels
&& c
< IW_MAX_FREQUENCIES
) {
354 struct ieee80211_channel
*chan
= &mode
->channels
[i
];
356 if (chan
->flag
& IEEE80211_CHAN_W_SCAN
) {
357 range
->freq
[c
].i
= chan
->chan
;
358 range
->freq
[c
].m
= chan
->freq
* 100000;
359 range
->freq
[c
].e
= 1;
365 range
->num_channels
= c
;
366 range
->num_frequency
= c
;
368 IW_EVENT_CAPA_SET_KERNEL(range
->event_capa
);
369 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWTHRSPY
);
370 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWAP
);
371 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWSCAN
);
377 static int ieee80211_ioctl_siwmode(struct net_device
*dev
,
378 struct iw_request_info
*info
,
379 __u32
*mode
, char *extra
)
381 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
384 if (sdata
->type
== IEEE80211_IF_TYPE_VLAN
)
389 type
= IEEE80211_IF_TYPE_STA
;
392 type
= IEEE80211_IF_TYPE_IBSS
;
394 case IW_MODE_MONITOR
:
395 type
= IEEE80211_IF_TYPE_MNTR
;
401 if (type
== sdata
->type
)
403 if (netif_running(dev
))
406 ieee80211_if_reinit(dev
);
407 ieee80211_if_set_type(dev
, type
);
413 static int ieee80211_ioctl_giwmode(struct net_device
*dev
,
414 struct iw_request_info
*info
,
415 __u32
*mode
, char *extra
)
417 struct ieee80211_sub_if_data
*sdata
;
419 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
420 switch (sdata
->type
) {
421 case IEEE80211_IF_TYPE_AP
:
422 *mode
= IW_MODE_MASTER
;
424 case IEEE80211_IF_TYPE_STA
:
425 *mode
= IW_MODE_INFRA
;
427 case IEEE80211_IF_TYPE_IBSS
:
428 *mode
= IW_MODE_ADHOC
;
430 case IEEE80211_IF_TYPE_MNTR
:
431 *mode
= IW_MODE_MONITOR
;
433 case IEEE80211_IF_TYPE_WDS
:
434 *mode
= IW_MODE_REPEAT
;
436 case IEEE80211_IF_TYPE_VLAN
:
437 *mode
= IW_MODE_SECOND
; /* FIXME */
440 *mode
= IW_MODE_AUTO
;
446 int ieee80211_set_channel(struct ieee80211_local
*local
, int channel
, int freq
)
448 struct ieee80211_hw_mode
*mode
;
452 list_for_each_entry(mode
, &local
->modes_list
, list
) {
453 if (!(local
->enabled_modes
& (1 << mode
->mode
)))
455 for (c
= 0; c
< mode
->num_channels
; c
++) {
456 struct ieee80211_channel
*chan
= &mode
->channels
[c
];
457 if (chan
->flag
& IEEE80211_CHAN_W_SCAN
&&
458 ((chan
->chan
== channel
) || (chan
->freq
== freq
))) {
459 /* Use next_mode as the mode preference to
460 * resolve non-unique channel numbers. */
461 if (set
&& mode
->mode
!= local
->next_mode
)
464 local
->oper_channel
= chan
;
465 local
->oper_hw_mode
= mode
;
472 if (local
->sta_scanning
)
475 ret
= ieee80211_hw_config(local
);
477 rate_control_clear(local
);
483 static int ieee80211_ioctl_siwfreq(struct net_device
*dev
,
484 struct iw_request_info
*info
,
485 struct iw_freq
*freq
, char *extra
)
487 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
488 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
490 if (sdata
->type
== IEEE80211_IF_TYPE_STA
)
491 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_AUTO_CHANNEL_SEL
;
493 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
496 if (sdata
->type
== IEEE80211_IF_TYPE_STA
)
497 sdata
->u
.sta
.flags
|=
498 IEEE80211_STA_AUTO_CHANNEL_SEL
;
501 return ieee80211_set_channel(local
, freq
->m
, -1);
503 int i
, div
= 1000000;
504 for (i
= 0; i
< freq
->e
; i
++)
507 return ieee80211_set_channel(local
, -1, freq
->m
/ div
);
514 static int ieee80211_ioctl_giwfreq(struct net_device
*dev
,
515 struct iw_request_info
*info
,
516 struct iw_freq
*freq
, char *extra
)
518 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
520 /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
521 * driver for the current channel with firmware-based management */
523 freq
->m
= local
->hw
.conf
.freq
;
530 static int ieee80211_ioctl_siwessid(struct net_device
*dev
,
531 struct iw_request_info
*info
,
532 struct iw_point
*data
, char *ssid
)
534 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
535 struct ieee80211_sub_if_data
*sdata
;
536 size_t len
= data
->length
;
538 /* iwconfig uses nul termination in SSID.. */
539 if (len
> 0 && ssid
[len
- 1] == '\0')
542 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
543 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
544 sdata
->type
== IEEE80211_IF_TYPE_IBSS
) {
546 if (local
->user_space_mlme
) {
547 if (len
> IEEE80211_MAX_SSID_LEN
)
549 memcpy(sdata
->u
.sta
.ssid
, ssid
, len
);
550 sdata
->u
.sta
.ssid_len
= len
;
554 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_AUTO_SSID_SEL
;
556 sdata
->u
.sta
.flags
|= IEEE80211_STA_AUTO_SSID_SEL
;
557 ret
= ieee80211_sta_set_ssid(dev
, ssid
, len
);
560 ieee80211_sta_req_auth(dev
, &sdata
->u
.sta
);
564 if (sdata
->type
== IEEE80211_IF_TYPE_AP
) {
565 memcpy(sdata
->u
.ap
.ssid
, ssid
, len
);
566 memset(sdata
->u
.ap
.ssid
+ len
, 0,
567 IEEE80211_MAX_SSID_LEN
- len
);
568 sdata
->u
.ap
.ssid_len
= len
;
569 return ieee80211_if_config(dev
);
575 static int ieee80211_ioctl_giwessid(struct net_device
*dev
,
576 struct iw_request_info
*info
,
577 struct iw_point
*data
, char *ssid
)
581 struct ieee80211_sub_if_data
*sdata
;
582 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
583 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
584 sdata
->type
== IEEE80211_IF_TYPE_IBSS
) {
585 int res
= ieee80211_sta_get_ssid(dev
, ssid
, &len
);
594 if (sdata
->type
== IEEE80211_IF_TYPE_AP
) {
595 len
= sdata
->u
.ap
.ssid_len
;
596 if (len
> IW_ESSID_MAX_SIZE
)
597 len
= IW_ESSID_MAX_SIZE
;
598 memcpy(ssid
, sdata
->u
.ap
.ssid
, len
);
607 static int ieee80211_ioctl_siwap(struct net_device
*dev
,
608 struct iw_request_info
*info
,
609 struct sockaddr
*ap_addr
, char *extra
)
611 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
612 struct ieee80211_sub_if_data
*sdata
;
614 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
615 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
616 sdata
->type
== IEEE80211_IF_TYPE_IBSS
) {
618 if (local
->user_space_mlme
) {
619 memcpy(sdata
->u
.sta
.bssid
, (u8
*) &ap_addr
->sa_data
,
623 if (is_zero_ether_addr((u8
*) &ap_addr
->sa_data
))
624 sdata
->u
.sta
.flags
|= IEEE80211_STA_AUTO_BSSID_SEL
|
625 IEEE80211_STA_AUTO_CHANNEL_SEL
;
626 else if (is_broadcast_ether_addr((u8
*) &ap_addr
->sa_data
))
627 sdata
->u
.sta
.flags
|= IEEE80211_STA_AUTO_BSSID_SEL
;
629 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_AUTO_BSSID_SEL
;
630 ret
= ieee80211_sta_set_bssid(dev
, (u8
*) &ap_addr
->sa_data
);
633 ieee80211_sta_req_auth(dev
, &sdata
->u
.sta
);
635 } else if (sdata
->type
== IEEE80211_IF_TYPE_WDS
) {
636 if (memcmp(sdata
->u
.wds
.remote_addr
, (u8
*) &ap_addr
->sa_data
,
639 return ieee80211_if_update_wds(dev
, (u8
*) &ap_addr
->sa_data
);
646 static int ieee80211_ioctl_giwap(struct net_device
*dev
,
647 struct iw_request_info
*info
,
648 struct sockaddr
*ap_addr
, char *extra
)
650 struct ieee80211_sub_if_data
*sdata
;
652 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
653 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
654 sdata
->type
== IEEE80211_IF_TYPE_IBSS
) {
655 ap_addr
->sa_family
= ARPHRD_ETHER
;
656 memcpy(&ap_addr
->sa_data
, sdata
->u
.sta
.bssid
, ETH_ALEN
);
658 } else if (sdata
->type
== IEEE80211_IF_TYPE_WDS
) {
659 ap_addr
->sa_family
= ARPHRD_ETHER
;
660 memcpy(&ap_addr
->sa_data
, sdata
->u
.wds
.remote_addr
, ETH_ALEN
);
668 static int ieee80211_ioctl_siwscan(struct net_device
*dev
,
669 struct iw_request_info
*info
,
670 struct iw_point
*data
, char *extra
)
672 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
673 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
677 if (!netif_running(dev
))
680 switch (sdata
->type
) {
681 case IEEE80211_IF_TYPE_STA
:
682 case IEEE80211_IF_TYPE_IBSS
:
683 if (local
->scan_flags
& IEEE80211_SCAN_MATCH_SSID
) {
684 ssid
= sdata
->u
.sta
.ssid
;
685 ssid_len
= sdata
->u
.sta
.ssid_len
;
688 case IEEE80211_IF_TYPE_AP
:
689 if (local
->scan_flags
& IEEE80211_SCAN_MATCH_SSID
) {
690 ssid
= sdata
->u
.ap
.ssid
;
691 ssid_len
= sdata
->u
.ap
.ssid_len
;
698 return ieee80211_sta_req_scan(dev
, ssid
, ssid_len
);
702 static int ieee80211_ioctl_giwscan(struct net_device
*dev
,
703 struct iw_request_info
*info
,
704 struct iw_point
*data
, char *extra
)
707 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
708 if (local
->sta_scanning
)
710 res
= ieee80211_sta_scan_results(dev
, extra
, data
->length
);
720 static int ieee80211_ioctl_siwrate(struct net_device
*dev
,
721 struct iw_request_info
*info
,
722 struct iw_param
*rate
, char *extra
)
724 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
725 struct ieee80211_hw_mode
*mode
;
727 u32 target_rate
= rate
->value
/ 100000;
728 struct ieee80211_sub_if_data
*sdata
;
730 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
733 mode
= local
->oper_hw_mode
;
734 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
735 * target_rate = X, rate->fixed = 1 means only rate X
736 * target_rate = X, rate->fixed = 0 means all rates <= X */
737 sdata
->bss
->max_ratectrl_rateidx
= -1;
738 sdata
->bss
->force_unicast_rateidx
= -1;
741 for (i
=0; i
< mode
->num_rates
; i
++) {
742 struct ieee80211_rate
*rates
= &mode
->rates
[i
];
743 int this_rate
= rates
->rate
;
745 if (mode
->mode
== MODE_ATHEROS_TURBO
||
746 mode
->mode
== MODE_ATHEROS_TURBOG
)
748 if (target_rate
== this_rate
) {
749 sdata
->bss
->max_ratectrl_rateidx
= i
;
751 sdata
->bss
->force_unicast_rateidx
= i
;
758 static int ieee80211_ioctl_giwrate(struct net_device
*dev
,
759 struct iw_request_info
*info
,
760 struct iw_param
*rate
, char *extra
)
762 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
763 struct sta_info
*sta
;
764 struct ieee80211_sub_if_data
*sdata
;
766 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
767 if (sdata
->type
== IEEE80211_IF_TYPE_STA
)
768 sta
= sta_info_get(local
, sdata
->u
.sta
.bssid
);
773 if (sta
->txrate
< local
->oper_hw_mode
->num_rates
)
774 rate
->value
= local
->oper_hw_mode
->rates
[sta
->txrate
].rate
* 100000;
781 static int ieee80211_ioctl_giwtxpower(struct net_device
*dev
,
782 struct iw_request_info
*info
,
783 union iwreq_data
*data
, char *extra
)
785 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
787 data
->txpower
.fixed
= 1;
788 data
->txpower
.disabled
= !(local
->hw
.conf
.radio_enabled
);
789 data
->txpower
.value
= local
->hw
.conf
.power_level
;
790 data
->txpower
.flags
= IW_TXPOW_DBM
;
795 static int ieee80211_ioctl_siwrts(struct net_device
*dev
,
796 struct iw_request_info
*info
,
797 struct iw_param
*rts
, char *extra
)
799 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
802 local
->rts_threshold
= IEEE80211_MAX_RTS_THRESHOLD
;
803 else if (rts
->value
< 0 || rts
->value
> IEEE80211_MAX_RTS_THRESHOLD
)
806 local
->rts_threshold
= rts
->value
;
808 /* If the wlan card performs RTS/CTS in hardware/firmware,
809 * configure it here */
811 if (local
->ops
->set_rts_threshold
)
812 local
->ops
->set_rts_threshold(local_to_hw(local
),
813 local
->rts_threshold
);
818 static int ieee80211_ioctl_giwrts(struct net_device
*dev
,
819 struct iw_request_info
*info
,
820 struct iw_param
*rts
, char *extra
)
822 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
824 rts
->value
= local
->rts_threshold
;
825 rts
->disabled
= (rts
->value
>= IEEE80211_MAX_RTS_THRESHOLD
);
832 static int ieee80211_ioctl_siwfrag(struct net_device
*dev
,
833 struct iw_request_info
*info
,
834 struct iw_param
*frag
, char *extra
)
836 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
839 local
->fragmentation_threshold
= IEEE80211_MAX_FRAG_THRESHOLD
;
840 else if (frag
->value
< 256 ||
841 frag
->value
> IEEE80211_MAX_FRAG_THRESHOLD
)
844 /* Fragment length must be even, so strip LSB. */
845 local
->fragmentation_threshold
= frag
->value
& ~0x1;
848 /* If the wlan card performs fragmentation in hardware/firmware,
849 * configure it here */
851 if (local
->ops
->set_frag_threshold
)
852 local
->ops
->set_frag_threshold(
854 local
->fragmentation_threshold
);
859 static int ieee80211_ioctl_giwfrag(struct net_device
*dev
,
860 struct iw_request_info
*info
,
861 struct iw_param
*frag
, char *extra
)
863 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
865 frag
->value
= local
->fragmentation_threshold
;
866 frag
->disabled
= (frag
->value
>= IEEE80211_MAX_RTS_THRESHOLD
);
873 static int ieee80211_ioctl_siwretry(struct net_device
*dev
,
874 struct iw_request_info
*info
,
875 struct iw_param
*retry
, char *extra
)
877 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
879 if (retry
->disabled
||
880 (retry
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
)
883 if (retry
->flags
& IW_RETRY_MAX
)
884 local
->long_retry_limit
= retry
->value
;
885 else if (retry
->flags
& IW_RETRY_MIN
)
886 local
->short_retry_limit
= retry
->value
;
888 local
->long_retry_limit
= retry
->value
;
889 local
->short_retry_limit
= retry
->value
;
892 if (local
->ops
->set_retry_limit
) {
893 return local
->ops
->set_retry_limit(
895 local
->short_retry_limit
,
896 local
->long_retry_limit
);
903 static int ieee80211_ioctl_giwretry(struct net_device
*dev
,
904 struct iw_request_info
*info
,
905 struct iw_param
*retry
, char *extra
)
907 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
910 if (retry
->flags
== 0 || retry
->flags
& IW_RETRY_MIN
) {
911 /* first return min value, iwconfig will ask max value
913 retry
->flags
|= IW_RETRY_LIMIT
;
914 retry
->value
= local
->short_retry_limit
;
915 if (local
->long_retry_limit
!= local
->short_retry_limit
)
916 retry
->flags
|= IW_RETRY_MIN
;
919 if (retry
->flags
& IW_RETRY_MAX
) {
920 retry
->flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
921 retry
->value
= local
->long_retry_limit
;
927 static void ieee80211_key_enable_hwaccel(struct ieee80211_local
*local
,
928 struct ieee80211_key
*key
)
932 if (!key
|| key
->conf
.alg
!= ALG_WEP
||
933 !(key
->conf
.flags
& IEEE80211_KEY_FORCE_SW_ENCRYPT
) ||
934 (local
->hw
.flags
& IEEE80211_HW_DEVICE_HIDES_WEP
))
937 memset(addr
, 0xff, ETH_ALEN
);
939 if (local
->ops
->set_key
)
940 local
->ops
->set_key(local_to_hw(local
),
941 SET_KEY
, addr
, &key
->conf
,
942 local
->default_wep_only
);
946 static void ieee80211_key_disable_hwaccel(struct ieee80211_local
*local
,
947 struct ieee80211_key
*key
)
951 if (!key
|| key
->conf
.alg
!= ALG_WEP
||
952 (key
->conf
.flags
& IEEE80211_KEY_FORCE_SW_ENCRYPT
) ||
953 (local
->hw
.flags
& IEEE80211_HW_DEVICE_HIDES_WEP
))
956 memset(addr
, 0xff, ETH_ALEN
);
957 if (local
->ops
->set_key
)
958 local
->ops
->set_key(local_to_hw(local
), DISABLE_KEY
,
960 local
->default_wep_only
);
961 key
->conf
.flags
|= IEEE80211_KEY_FORCE_SW_ENCRYPT
;
965 static int ieee80211_ioctl_default_wep_only(struct ieee80211_local
*local
,
969 struct ieee80211_sub_if_data
*sdata
;
971 local
->default_wep_only
= value
;
972 read_lock(&local
->sub_if_lock
);
973 list_for_each_entry(sdata
, &local
->sub_if_list
, list
)
974 for (i
= 0; i
< NUM_DEFAULT_KEYS
; i
++)
976 ieee80211_key_enable_hwaccel(local
,
979 ieee80211_key_disable_hwaccel(local
,
981 read_unlock(&local
->sub_if_lock
);
987 void ieee80211_update_default_wep_only(struct ieee80211_local
*local
)
990 struct ieee80211_sub_if_data
*sdata
;
992 read_lock(&local
->sub_if_lock
);
993 list_for_each_entry(sdata
, &local
->sub_if_list
, list
) {
995 if (sdata
->dev
== local
->mdev
)
998 /* If there is an AP interface then depend on userspace to
999 set default_wep_only correctly. */
1000 if (sdata
->type
== IEEE80211_IF_TYPE_AP
) {
1001 read_unlock(&local
->sub_if_lock
);
1008 read_unlock(&local
->sub_if_lock
);
1011 ieee80211_ioctl_default_wep_only(local
, 1);
1013 ieee80211_ioctl_default_wep_only(local
, 0);
1017 static int ieee80211_ioctl_prism2_param(struct net_device
*dev
,
1018 struct iw_request_info
*info
,
1019 void *wrqu
, char *extra
)
1021 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
1022 struct ieee80211_sub_if_data
*sdata
;
1023 int *i
= (int *) extra
;
1025 int value
= *(i
+ 1);
1028 if (!capable(CAP_NET_ADMIN
))
1031 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1034 case PRISM2_PARAM_IEEE_802_1X
:
1035 if (local
->ops
->set_ieee8021x
)
1036 ret
= local
->ops
->set_ieee8021x(local_to_hw(local
),
1039 printk(KERN_DEBUG
"%s: failed to set IEEE 802.1X (%d) "
1040 "for low-level driver\n", dev
->name
, value
);
1042 sdata
->ieee802_1x
= value
;
1045 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES
:
1046 if (sdata
->type
== IEEE80211_IF_TYPE_AP
) {
1048 sdata
->flags
|= IEEE80211_SDATA_USE_PROTECTION
;
1050 sdata
->flags
&= ~IEEE80211_SDATA_USE_PROTECTION
;
1051 ieee80211_erp_info_change_notify(dev
,
1052 IEEE80211_ERP_CHANGE_PROTECTION
);
1058 case PRISM2_PARAM_PREAMBLE
:
1059 if (sdata
->type
!= IEEE80211_IF_TYPE_AP
) {
1061 sdata
->flags
|= IEEE80211_SDATA_SHORT_PREAMBLE
;
1063 sdata
->flags
&= ~IEEE80211_SDATA_SHORT_PREAMBLE
;
1064 ieee80211_erp_info_change_notify(dev
,
1065 IEEE80211_ERP_CHANGE_PREAMBLE
);
1071 case PRISM2_PARAM_SHORT_SLOT_TIME
:
1073 local
->hw
.conf
.flags
|= IEEE80211_CONF_SHORT_SLOT_TIME
;
1075 local
->hw
.conf
.flags
&= ~IEEE80211_CONF_SHORT_SLOT_TIME
;
1076 if (ieee80211_hw_config(local
))
1080 case PRISM2_PARAM_NEXT_MODE
:
1081 local
->next_mode
= value
;
1084 case PRISM2_PARAM_KEY_TX_RX_THRESHOLD
:
1085 local
->key_tx_rx_threshold
= value
;
1088 case PRISM2_PARAM_WIFI_WME_NOACK_TEST
:
1089 local
->wifi_wme_noack_test
= value
;
1092 case PRISM2_PARAM_SCAN_FLAGS
:
1093 local
->scan_flags
= value
;
1096 case PRISM2_PARAM_MIXED_CELL
:
1097 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
&&
1098 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1102 sdata
->u
.sta
.flags
|= IEEE80211_STA_MIXED_CELL
;
1104 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_MIXED_CELL
;
1108 case PRISM2_PARAM_HW_MODES
:
1109 local
->enabled_modes
= value
;
1112 case PRISM2_PARAM_CREATE_IBSS
:
1113 if (sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1117 sdata
->u
.sta
.flags
|= IEEE80211_STA_CREATE_IBSS
;
1119 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_CREATE_IBSS
;
1122 case PRISM2_PARAM_WMM_ENABLED
:
1123 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
&&
1124 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1128 sdata
->u
.sta
.flags
|= IEEE80211_STA_WMM_ENABLED
;
1130 sdata
->u
.sta
.flags
&= ~IEEE80211_STA_WMM_ENABLED
;
1142 static int ieee80211_ioctl_get_prism2_param(struct net_device
*dev
,
1143 struct iw_request_info
*info
,
1144 void *wrqu
, char *extra
)
1146 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
1147 struct ieee80211_sub_if_data
*sdata
;
1148 int *param
= (int *) extra
;
1151 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1154 case PRISM2_PARAM_IEEE_802_1X
:
1155 *param
= sdata
->ieee802_1x
;
1158 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES
:
1159 *param
= !!(sdata
->flags
& IEEE80211_SDATA_USE_PROTECTION
);
1162 case PRISM2_PARAM_PREAMBLE
:
1163 *param
= !!(sdata
->flags
& IEEE80211_SDATA_SHORT_PREAMBLE
);
1166 case PRISM2_PARAM_SHORT_SLOT_TIME
:
1167 *param
= !!(local
->hw
.conf
.flags
& IEEE80211_CONF_SHORT_SLOT_TIME
);
1170 case PRISM2_PARAM_NEXT_MODE
:
1171 *param
= local
->next_mode
;
1174 case PRISM2_PARAM_KEY_TX_RX_THRESHOLD
:
1175 *param
= local
->key_tx_rx_threshold
;
1178 case PRISM2_PARAM_WIFI_WME_NOACK_TEST
:
1179 *param
= local
->wifi_wme_noack_test
;
1182 case PRISM2_PARAM_SCAN_FLAGS
:
1183 *param
= local
->scan_flags
;
1186 case PRISM2_PARAM_HW_MODES
:
1187 *param
= local
->enabled_modes
;
1190 case PRISM2_PARAM_CREATE_IBSS
:
1191 if (sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1194 *param
= !!(sdata
->u
.sta
.flags
&
1195 IEEE80211_STA_CREATE_IBSS
);
1198 case PRISM2_PARAM_MIXED_CELL
:
1199 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
&&
1200 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1203 *param
= !!(sdata
->u
.sta
.flags
&
1204 IEEE80211_STA_MIXED_CELL
);
1206 case PRISM2_PARAM_WMM_ENABLED
:
1207 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
&&
1208 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1211 *param
= !!(sdata
->u
.sta
.flags
&
1212 IEEE80211_STA_WMM_ENABLED
);
1222 static int ieee80211_ioctl_siwmlme(struct net_device
*dev
,
1223 struct iw_request_info
*info
,
1224 struct iw_point
*data
, char *extra
)
1226 struct ieee80211_sub_if_data
*sdata
;
1227 struct iw_mlme
*mlme
= (struct iw_mlme
*) extra
;
1229 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1230 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
&&
1231 sdata
->type
!= IEEE80211_IF_TYPE_IBSS
)
1234 switch (mlme
->cmd
) {
1235 case IW_MLME_DEAUTH
:
1236 /* TODO: mlme->addr.sa_data */
1237 return ieee80211_sta_deauthenticate(dev
, mlme
->reason_code
);
1238 case IW_MLME_DISASSOC
:
1239 /* TODO: mlme->addr.sa_data */
1240 return ieee80211_sta_disassociate(dev
, mlme
->reason_code
);
1247 static int ieee80211_ioctl_siwencode(struct net_device
*dev
,
1248 struct iw_request_info
*info
,
1249 struct iw_point
*erq
, char *keybuf
)
1251 struct ieee80211_sub_if_data
*sdata
;
1252 int idx
, i
, alg
= ALG_WEP
;
1253 u8 bcaddr
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1255 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1257 idx
= erq
->flags
& IW_ENCODE_INDEX
;
1259 if (sdata
->default_key
)
1260 for (i
= 0; i
< NUM_DEFAULT_KEYS
; i
++) {
1261 if (sdata
->default_key
== sdata
->keys
[i
]) {
1266 } else if (idx
< 1 || idx
> 4)
1271 if (erq
->flags
& IW_ENCODE_DISABLED
)
1273 else if (erq
->length
== 0) {
1274 /* No key data - just set the default TX key index */
1275 if (sdata
->default_key
!= sdata
->keys
[idx
]) {
1276 ieee80211_debugfs_key_remove_default(sdata
);
1277 sdata
->default_key
= sdata
->keys
[idx
];
1278 if (sdata
->default_key
)
1279 ieee80211_debugfs_key_add_default(sdata
);
1284 return ieee80211_set_encryption(
1287 !sdata
->default_key
,
1288 keybuf
, erq
->length
);
1292 static int ieee80211_ioctl_giwencode(struct net_device
*dev
,
1293 struct iw_request_info
*info
,
1294 struct iw_point
*erq
, char *key
)
1296 struct ieee80211_sub_if_data
*sdata
;
1299 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1301 idx
= erq
->flags
& IW_ENCODE_INDEX
;
1302 if (idx
< 1 || idx
> 4) {
1304 if (!sdata
->default_key
)
1306 else for (i
= 0; i
< NUM_DEFAULT_KEYS
; i
++) {
1307 if (sdata
->default_key
== sdata
->keys
[i
]) {
1317 erq
->flags
= idx
+ 1;
1319 if (!sdata
->keys
[idx
]) {
1321 erq
->flags
|= IW_ENCODE_DISABLED
;
1325 memcpy(key
, sdata
->keys
[idx
]->conf
.key
,
1326 min((int)erq
->length
, sdata
->keys
[idx
]->conf
.keylen
));
1327 erq
->length
= sdata
->keys
[idx
]->conf
.keylen
;
1328 erq
->flags
|= IW_ENCODE_ENABLED
;
1333 static int ieee80211_ioctl_siwauth(struct net_device
*dev
,
1334 struct iw_request_info
*info
,
1335 struct iw_param
*data
, char *extra
)
1337 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
1338 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1341 switch (data
->flags
& IW_AUTH_INDEX
) {
1342 case IW_AUTH_WPA_VERSION
:
1343 case IW_AUTH_CIPHER_PAIRWISE
:
1344 case IW_AUTH_CIPHER_GROUP
:
1345 case IW_AUTH_WPA_ENABLED
:
1346 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1348 case IW_AUTH_KEY_MGMT
:
1349 if (sdata
->type
!= IEEE80211_IF_TYPE_STA
)
1353 * Key management was set by wpa_supplicant,
1354 * we only need this to associate to a network
1355 * that has privacy enabled regardless of not
1358 sdata
->u
.sta
.key_management_enabled
= !!data
->value
;
1361 case IW_AUTH_80211_AUTH_ALG
:
1362 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
1363 sdata
->type
== IEEE80211_IF_TYPE_IBSS
)
1364 sdata
->u
.sta
.auth_algs
= data
->value
;
1368 case IW_AUTH_PRIVACY_INVOKED
:
1369 if (local
->ops
->set_privacy_invoked
)
1370 ret
= local
->ops
->set_privacy_invoked(
1371 local_to_hw(local
), data
->value
);
1380 /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
1381 static struct iw_statistics
*ieee80211_get_wireless_stats(struct net_device
*dev
)
1383 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
1384 struct iw_statistics
*wstats
= &local
->wstats
;
1385 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1386 struct sta_info
*sta
= NULL
;
1388 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
1389 sdata
->type
== IEEE80211_IF_TYPE_IBSS
)
1390 sta
= sta_info_get(local
, sdata
->u
.sta
.bssid
);
1392 wstats
->discard
.fragment
= 0;
1393 wstats
->discard
.misc
= 0;
1394 wstats
->qual
.qual
= 0;
1395 wstats
->qual
.level
= 0;
1396 wstats
->qual
.noise
= 0;
1397 wstats
->qual
.updated
= IW_QUAL_ALL_INVALID
;
1399 wstats
->qual
.level
= sta
->last_rssi
;
1400 wstats
->qual
.qual
= sta
->last_signal
;
1401 wstats
->qual
.noise
= sta
->last_noise
;
1402 wstats
->qual
.updated
= local
->wstats_flags
;
1408 static int ieee80211_ioctl_giwauth(struct net_device
*dev
,
1409 struct iw_request_info
*info
,
1410 struct iw_param
*data
, char *extra
)
1412 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1415 switch (data
->flags
& IW_AUTH_INDEX
) {
1416 case IW_AUTH_80211_AUTH_ALG
:
1417 if (sdata
->type
== IEEE80211_IF_TYPE_STA
||
1418 sdata
->type
== IEEE80211_IF_TYPE_IBSS
)
1419 data
->value
= sdata
->u
.sta
.auth_algs
;
1431 static int ieee80211_ioctl_siwencodeext(struct net_device
*dev
,
1432 struct iw_request_info
*info
,
1433 struct iw_point
*erq
, char *extra
)
1435 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
1436 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*) extra
;
1440 case IW_ENCODE_ALG_NONE
:
1443 case IW_ENCODE_ALG_WEP
:
1446 case IW_ENCODE_ALG_TKIP
:
1449 case IW_ENCODE_ALG_CCMP
:
1456 if (erq
->flags
& IW_ENCODE_DISABLED
)
1459 idx
= erq
->flags
& IW_ENCODE_INDEX
;
1460 if (idx
< 1 || idx
> 4) {
1462 if (!sdata
->default_key
)
1464 else for (i
= 0; i
< NUM_DEFAULT_KEYS
; i
++) {
1465 if (sdata
->default_key
== sdata
->keys
[i
]) {
1475 return ieee80211_set_encryption(dev
, ext
->addr
.sa_data
, idx
, alg
,
1477 IW_ENCODE_EXT_SET_TX_KEY
,
1478 ext
->key
, ext
->key_len
);
1482 static const struct iw_priv_args ieee80211_ioctl_priv
[] = {
1483 { PRISM2_IOCTL_PRISM2_PARAM
,
1484 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "param" },
1485 { PRISM2_IOCTL_GET_PRISM2_PARAM
,
1486 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
1487 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_param" },
1490 /* Structures to export the Wireless Handlers */
1492 static const iw_handler ieee80211_handler
[] =
1494 (iw_handler
) NULL
, /* SIOCSIWCOMMIT */
1495 (iw_handler
) ieee80211_ioctl_giwname
, /* SIOCGIWNAME */
1496 (iw_handler
) NULL
, /* SIOCSIWNWID */
1497 (iw_handler
) NULL
, /* SIOCGIWNWID */
1498 (iw_handler
) ieee80211_ioctl_siwfreq
, /* SIOCSIWFREQ */
1499 (iw_handler
) ieee80211_ioctl_giwfreq
, /* SIOCGIWFREQ */
1500 (iw_handler
) ieee80211_ioctl_siwmode
, /* SIOCSIWMODE */
1501 (iw_handler
) ieee80211_ioctl_giwmode
, /* SIOCGIWMODE */
1502 (iw_handler
) NULL
, /* SIOCSIWSENS */
1503 (iw_handler
) NULL
, /* SIOCGIWSENS */
1504 (iw_handler
) NULL
/* not used */, /* SIOCSIWRANGE */
1505 (iw_handler
) ieee80211_ioctl_giwrange
, /* SIOCGIWRANGE */
1506 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
1507 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
1508 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
1509 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
1510 iw_handler_set_spy
, /* SIOCSIWSPY */
1511 iw_handler_get_spy
, /* SIOCGIWSPY */
1512 iw_handler_set_thrspy
, /* SIOCSIWTHRSPY */
1513 iw_handler_get_thrspy
, /* SIOCGIWTHRSPY */
1514 (iw_handler
) ieee80211_ioctl_siwap
, /* SIOCSIWAP */
1515 (iw_handler
) ieee80211_ioctl_giwap
, /* SIOCGIWAP */
1516 (iw_handler
) ieee80211_ioctl_siwmlme
, /* SIOCSIWMLME */
1517 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
1518 (iw_handler
) ieee80211_ioctl_siwscan
, /* SIOCSIWSCAN */
1519 (iw_handler
) ieee80211_ioctl_giwscan
, /* SIOCGIWSCAN */
1520 (iw_handler
) ieee80211_ioctl_siwessid
, /* SIOCSIWESSID */
1521 (iw_handler
) ieee80211_ioctl_giwessid
, /* SIOCGIWESSID */
1522 (iw_handler
) NULL
, /* SIOCSIWNICKN */
1523 (iw_handler
) NULL
, /* SIOCGIWNICKN */
1524 (iw_handler
) NULL
, /* -- hole -- */
1525 (iw_handler
) NULL
, /* -- hole -- */
1526 (iw_handler
) ieee80211_ioctl_siwrate
, /* SIOCSIWRATE */
1527 (iw_handler
) ieee80211_ioctl_giwrate
, /* SIOCGIWRATE */
1528 (iw_handler
) ieee80211_ioctl_siwrts
, /* SIOCSIWRTS */
1529 (iw_handler
) ieee80211_ioctl_giwrts
, /* SIOCGIWRTS */
1530 (iw_handler
) ieee80211_ioctl_siwfrag
, /* SIOCSIWFRAG */
1531 (iw_handler
) ieee80211_ioctl_giwfrag
, /* SIOCGIWFRAG */
1532 (iw_handler
) NULL
, /* SIOCSIWTXPOW */
1533 (iw_handler
) ieee80211_ioctl_giwtxpower
, /* SIOCGIWTXPOW */
1534 (iw_handler
) ieee80211_ioctl_siwretry
, /* SIOCSIWRETRY */
1535 (iw_handler
) ieee80211_ioctl_giwretry
, /* SIOCGIWRETRY */
1536 (iw_handler
) ieee80211_ioctl_siwencode
, /* SIOCSIWENCODE */
1537 (iw_handler
) ieee80211_ioctl_giwencode
, /* SIOCGIWENCODE */
1538 (iw_handler
) NULL
, /* SIOCSIWPOWER */
1539 (iw_handler
) NULL
, /* SIOCGIWPOWER */
1540 (iw_handler
) NULL
, /* -- hole -- */
1541 (iw_handler
) NULL
, /* -- hole -- */
1542 (iw_handler
) ieee80211_ioctl_siwgenie
, /* SIOCSIWGENIE */
1543 (iw_handler
) NULL
, /* SIOCGIWGENIE */
1544 (iw_handler
) ieee80211_ioctl_siwauth
, /* SIOCSIWAUTH */
1545 (iw_handler
) ieee80211_ioctl_giwauth
, /* SIOCGIWAUTH */
1546 (iw_handler
) ieee80211_ioctl_siwencodeext
, /* SIOCSIWENCODEEXT */
1547 (iw_handler
) NULL
, /* SIOCGIWENCODEEXT */
1548 (iw_handler
) NULL
, /* SIOCSIWPMKSA */
1549 (iw_handler
) NULL
, /* -- hole -- */
1552 static const iw_handler ieee80211_private_handler
[] =
1553 { /* SIOCIWFIRSTPRIV + */
1554 (iw_handler
) ieee80211_ioctl_prism2_param
, /* 0 */
1555 (iw_handler
) ieee80211_ioctl_get_prism2_param
, /* 1 */
1558 const struct iw_handler_def ieee80211_iw_handler_def
=
1560 .num_standard
= ARRAY_SIZE(ieee80211_handler
),
1561 .num_private
= ARRAY_SIZE(ieee80211_private_handler
),
1562 .num_private_args
= ARRAY_SIZE(ieee80211_ioctl_priv
),
1563 .standard
= (iw_handler
*) ieee80211_handler
,
1564 .private = (iw_handler
*) ieee80211_private_handler
,
1565 .private_args
= (struct iw_priv_args
*) ieee80211_ioctl_priv
,
1566 .get_wireless_stats
= ieee80211_get_wireless_stats
,