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,
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 &&
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 printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
153 " failed\n", dev->name);
157 if (set_tx_key || sdata->default_key == key) {
158 ieee80211_debugfs_key_remove_default(sdata);
159 sdata->default_key = NULL;
161 ieee80211_debugfs_key_remove(key);
165 sdata->keys[idx] = NULL;
166 ieee80211_key_free(key);
170 key = ieee80211_key_alloc(sta ? NULL : sdata, idx, key_len,
177 /* default to sw encryption; low-level driver sets these if the
178 * requested encryption is supported */
179 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
180 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
183 key->conf.keyidx = idx;
184 key->conf.keylen = key_len;
185 memcpy(key->conf.key, _key, key_len);
187 if (alg == ALG_CCMP) {
188 /* Initialize AES key state here as an optimization
189 * so that it does not need to be initialized for every
191 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
193 if (!key->u.ccmp.tfm) {
199 if (set_tx_key || sdata->default_key == old_key) {
200 ieee80211_debugfs_key_remove_default(sdata);
201 sdata->default_key = NULL;
203 ieee80211_debugfs_key_remove(old_key);
207 sdata->keys[idx] = key;
208 ieee80211_key_free(old_key);
209 ieee80211_debugfs_key_add(local, key);
211 ieee80211_debugfs_key_sta_link(key, sta);
214 (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP))
215 ieee80211_set_hw_encryption(dev, sta, sta_addr, key);
218 if (set_tx_key || (!sta && !sdata->default_key && key)) {
219 sdata->default_key = key;
221 ieee80211_debugfs_key_add_default(sdata);
223 if (local->ops->set_key_idx &&
224 local->ops->set_key_idx(local_to_hw(local), idx))
225 printk(KERN_DEBUG "%s: failed to set TX key idx for "
226 "low-level driver\n", dev->name);
235 ieee80211_key_free(key);
242 static int ieee80211_ioctl_siwgenie(struct net_device *dev,
243 struct iw_request_info *info,
244 struct iw_point *data, char *extra)
246 struct ieee80211_sub_if_data *sdata;
247 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
249 if (local->user_space_mlme)
252 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
253 if (sdata->type == IEEE80211_IF_TYPE_STA ||
254 sdata->type == IEEE80211_IF_TYPE_IBSS) {
255 int ret = ieee80211_sta_set_extra_ie(dev, extra, data->length);
258 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
259 ieee80211_sta_req_auth(dev, &sdata->u.sta);
263 if (sdata->type == IEEE80211_IF_TYPE_AP) {
264 kfree(sdata->u.ap.generic_elem);
265 sdata->u.ap.generic_elem = kmalloc(data->length, GFP_KERNEL);
266 if (!sdata->u.ap.generic_elem)
268 memcpy(sdata->u.ap.generic_elem, extra, data->length);
269 sdata->u.ap.generic_elem_len = data->length;
270 return ieee80211_if_config(dev);
275 static int ieee80211_ioctl_giwname(struct net_device *dev,
276 struct iw_request_info *info,
277 char *name, char *extra)
279 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
281 switch (local->hw.conf.phymode) {
282 case MODE_IEEE80211A:
283 strcpy(name, "IEEE 802.11a");
285 case MODE_IEEE80211B:
286 strcpy(name, "IEEE 802.11b");
288 case MODE_IEEE80211G:
289 strcpy(name, "IEEE 802.11g");
291 case MODE_ATHEROS_TURBO:
292 strcpy(name, "5GHz Turbo");
295 strcpy(name, "IEEE 802.11");
303 static int ieee80211_ioctl_giwrange(struct net_device *dev,
304 struct iw_request_info *info,
305 struct iw_point *data, char *extra)
307 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
308 struct iw_range *range = (struct iw_range *) extra;
309 struct ieee80211_hw_mode *mode = NULL;
312 data->length = sizeof(struct iw_range);
313 memset(range, 0, sizeof(struct iw_range));
315 range->we_version_compiled = WIRELESS_EXT;
316 range->we_version_source = 21;
317 range->retry_capa = IW_RETRY_LIMIT;
318 range->retry_flags = IW_RETRY_LIMIT;
319 range->min_retry = 0;
320 range->max_retry = 255;
322 range->max_rts = 2347;
323 range->min_frag = 256;
324 range->max_frag = 2346;
326 range->encoding_size[0] = 5;
327 range->encoding_size[1] = 13;
328 range->num_encoding_sizes = 2;
329 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
331 range->max_qual.qual = local->hw.max_signal;
332 range->max_qual.level = local->hw.max_rssi;
333 range->max_qual.noise = local->hw.max_noise;
334 range->max_qual.updated = local->wstats_flags;
336 range->avg_qual.qual = local->hw.max_signal/2;
337 range->avg_qual.level = 0;
338 range->avg_qual.noise = 0;
339 range->avg_qual.updated = local->wstats_flags;
341 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
342 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
344 list_for_each_entry(mode, &local->modes_list, list) {
347 if (!(local->enabled_modes & (1 << mode->mode)) ||
348 (local->hw_modes & local->enabled_modes &
349 (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))
352 while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) {
353 struct ieee80211_channel *chan = &mode->channels[i];
355 if (chan->flag & IEEE80211_CHAN_W_SCAN) {
356 range->freq[c].i = chan->chan;
357 range->freq[c].m = chan->freq * 100000;
358 range->freq[c].e = 1;
364 range->num_channels = c;
365 range->num_frequency = c;
367 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
368 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
369 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
370 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
376 static int ieee80211_ioctl_siwmode(struct net_device *dev,
377 struct iw_request_info *info,
378 __u32 *mode, char *extra)
380 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
383 if (sdata->type == IEEE80211_IF_TYPE_VLAN)
388 type = IEEE80211_IF_TYPE_STA;
391 type = IEEE80211_IF_TYPE_IBSS;
393 case IW_MODE_MONITOR:
394 type = IEEE80211_IF_TYPE_MNTR;
400 if (type == sdata->type)
402 if (netif_running(dev))
405 ieee80211_if_reinit(dev);
406 ieee80211_if_set_type(dev, type);
412 static int ieee80211_ioctl_giwmode(struct net_device *dev,
413 struct iw_request_info *info,
414 __u32 *mode, char *extra)
416 struct ieee80211_sub_if_data *sdata;
418 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
419 switch (sdata->type) {
420 case IEEE80211_IF_TYPE_AP:
421 *mode = IW_MODE_MASTER;
423 case IEEE80211_IF_TYPE_STA:
424 *mode = IW_MODE_INFRA;
426 case IEEE80211_IF_TYPE_IBSS:
427 *mode = IW_MODE_ADHOC;
429 case IEEE80211_IF_TYPE_MNTR:
430 *mode = IW_MODE_MONITOR;
432 case IEEE80211_IF_TYPE_WDS:
433 *mode = IW_MODE_REPEAT;
435 case IEEE80211_IF_TYPE_VLAN:
436 *mode = IW_MODE_SECOND; /* FIXME */
439 *mode = IW_MODE_AUTO;
445 int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
447 struct ieee80211_hw_mode *mode;
451 list_for_each_entry(mode, &local->modes_list, list) {
452 if (!(local->enabled_modes & (1 << mode->mode)))
454 for (c = 0; c < mode->num_channels; c++) {
455 struct ieee80211_channel *chan = &mode->channels[c];
456 if (chan->flag & IEEE80211_CHAN_W_SCAN &&
457 ((chan->chan == channel) || (chan->freq == freq))) {
458 /* Use next_mode as the mode preference to
459 * resolve non-unique channel numbers. */
460 if (set && mode->mode != local->next_mode)
463 local->oper_channel = chan;
464 local->oper_hw_mode = mode;
471 if (local->sta_scanning)
474 ret = ieee80211_hw_config(local);
476 rate_control_clear(local);
482 static int ieee80211_ioctl_siwfreq(struct net_device *dev,
483 struct iw_request_info *info,
484 struct iw_freq *freq, char *extra)
486 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
487 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
489 if (sdata->type == IEEE80211_IF_TYPE_STA)
490 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
492 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
495 if (sdata->type == IEEE80211_IF_TYPE_STA)
496 sdata->u.sta.flags |=
497 IEEE80211_STA_AUTO_CHANNEL_SEL;
500 return ieee80211_set_channel(local, freq->m, -1);
502 int i, div = 1000000;
503 for (i = 0; i < freq->e; i++)
506 return ieee80211_set_channel(local, -1, freq->m / div);
513 static int ieee80211_ioctl_giwfreq(struct net_device *dev,
514 struct iw_request_info *info,
515 struct iw_freq *freq, char *extra)
517 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
519 /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
520 * driver for the current channel with firmware-based management */
522 freq->m = local->hw.conf.freq;
529 static int ieee80211_ioctl_siwessid(struct net_device *dev,
530 struct iw_request_info *info,
531 struct iw_point *data, char *ssid)
533 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
534 struct ieee80211_sub_if_data *sdata;
535 size_t len = data->length;
537 /* iwconfig uses nul termination in SSID.. */
538 if (len > 0 && ssid[len - 1] == '\0')
541 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
542 if (sdata->type == IEEE80211_IF_TYPE_STA ||
543 sdata->type == IEEE80211_IF_TYPE_IBSS) {
545 if (local->user_space_mlme) {
546 if (len > IEEE80211_MAX_SSID_LEN)
548 memcpy(sdata->u.sta.ssid, ssid, len);
549 sdata->u.sta.ssid_len = len;
553 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
555 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL;
556 ret = ieee80211_sta_set_ssid(dev, ssid, len);
559 ieee80211_sta_req_auth(dev, &sdata->u.sta);
563 if (sdata->type == IEEE80211_IF_TYPE_AP) {
564 memcpy(sdata->u.ap.ssid, ssid, len);
565 memset(sdata->u.ap.ssid + len, 0,
566 IEEE80211_MAX_SSID_LEN - len);
567 sdata->u.ap.ssid_len = len;
568 return ieee80211_if_config(dev);
574 static int ieee80211_ioctl_giwessid(struct net_device *dev,
575 struct iw_request_info *info,
576 struct iw_point *data, char *ssid)
580 struct ieee80211_sub_if_data *sdata;
581 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
582 if (sdata->type == IEEE80211_IF_TYPE_STA ||
583 sdata->type == IEEE80211_IF_TYPE_IBSS) {
584 int res = ieee80211_sta_get_ssid(dev, ssid, &len);
593 if (sdata->type == IEEE80211_IF_TYPE_AP) {
594 len = sdata->u.ap.ssid_len;
595 if (len > IW_ESSID_MAX_SIZE)
596 len = IW_ESSID_MAX_SIZE;
597 memcpy(ssid, sdata->u.ap.ssid, len);
606 static int ieee80211_ioctl_siwap(struct net_device *dev,
607 struct iw_request_info *info,
608 struct sockaddr *ap_addr, char *extra)
610 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
611 struct ieee80211_sub_if_data *sdata;
613 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
614 if (sdata->type == IEEE80211_IF_TYPE_STA ||
615 sdata->type == IEEE80211_IF_TYPE_IBSS) {
617 if (local->user_space_mlme) {
618 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
622 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
623 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
624 IEEE80211_STA_AUTO_CHANNEL_SEL;
625 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
626 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
628 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
629 ret = ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data);
632 ieee80211_sta_req_auth(dev, &sdata->u.sta);
634 } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
635 if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
638 return ieee80211_if_update_wds(dev, (u8 *) &ap_addr->sa_data);
645 static int ieee80211_ioctl_giwap(struct net_device *dev,
646 struct iw_request_info *info,
647 struct sockaddr *ap_addr, char *extra)
649 struct ieee80211_sub_if_data *sdata;
651 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
652 if (sdata->type == IEEE80211_IF_TYPE_STA ||
653 sdata->type == IEEE80211_IF_TYPE_IBSS) {
654 ap_addr->sa_family = ARPHRD_ETHER;
655 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
657 } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
658 ap_addr->sa_family = ARPHRD_ETHER;
659 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
667 static int ieee80211_ioctl_siwscan(struct net_device *dev,
668 struct iw_request_info *info,
669 struct iw_point *data, char *extra)
671 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
672 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
676 if (!netif_running(dev))
679 switch (sdata->type) {
680 case IEEE80211_IF_TYPE_STA:
681 case IEEE80211_IF_TYPE_IBSS:
682 if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
683 ssid = sdata->u.sta.ssid;
684 ssid_len = sdata->u.sta.ssid_len;
687 case IEEE80211_IF_TYPE_AP:
688 if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
689 ssid = sdata->u.ap.ssid;
690 ssid_len = sdata->u.ap.ssid_len;
697 return ieee80211_sta_req_scan(dev, ssid, ssid_len);
701 static int ieee80211_ioctl_giwscan(struct net_device *dev,
702 struct iw_request_info *info,
703 struct iw_point *data, char *extra)
706 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
707 if (local->sta_scanning)
709 res = ieee80211_sta_scan_results(dev, extra, data->length);
719 static int ieee80211_ioctl_siwrate(struct net_device *dev,
720 struct iw_request_info *info,
721 struct iw_param *rate, char *extra)
723 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
724 struct ieee80211_hw_mode *mode;
726 u32 target_rate = rate->value / 100000;
727 struct ieee80211_sub_if_data *sdata;
729 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
732 mode = local->oper_hw_mode;
733 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
734 * target_rate = X, rate->fixed = 1 means only rate X
735 * target_rate = X, rate->fixed = 0 means all rates <= X */
736 sdata->bss->max_ratectrl_rateidx = -1;
737 sdata->bss->force_unicast_rateidx = -1;
740 for (i=0; i< mode->num_rates; i++) {
741 struct ieee80211_rate *rates = &mode->rates[i];
742 int this_rate = rates->rate;
744 if (mode->mode == MODE_ATHEROS_TURBO ||
745 mode->mode == MODE_ATHEROS_TURBOG)
747 if (target_rate == this_rate) {
748 sdata->bss->max_ratectrl_rateidx = i;
750 sdata->bss->force_unicast_rateidx = i;
757 static int ieee80211_ioctl_giwrate(struct net_device *dev,
758 struct iw_request_info *info,
759 struct iw_param *rate, char *extra)
761 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
762 struct sta_info *sta;
763 struct ieee80211_sub_if_data *sdata;
765 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
766 if (sdata->type == IEEE80211_IF_TYPE_STA)
767 sta = sta_info_get(local, sdata->u.sta.bssid);
772 if (sta->txrate < local->oper_hw_mode->num_rates)
773 rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
780 static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
781 struct iw_request_info *info,
782 union iwreq_data *data, char *extra)
784 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
786 data->txpower.fixed = 1;
787 data->txpower.disabled = !(local->hw.conf.radio_enabled);
788 data->txpower.value = local->hw.conf.power_level;
789 data->txpower.flags = IW_TXPOW_DBM;
794 static int ieee80211_ioctl_siwrts(struct net_device *dev,
795 struct iw_request_info *info,
796 struct iw_param *rts, char *extra)
798 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
801 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
802 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
805 local->rts_threshold = rts->value;
807 /* If the wlan card performs RTS/CTS in hardware/firmware,
808 * configure it here */
810 if (local->ops->set_rts_threshold)
811 local->ops->set_rts_threshold(local_to_hw(local),
812 local->rts_threshold);
817 static int ieee80211_ioctl_giwrts(struct net_device *dev,
818 struct iw_request_info *info,
819 struct iw_param *rts, char *extra)
821 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
823 rts->value = local->rts_threshold;
824 rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
831 static int ieee80211_ioctl_siwfrag(struct net_device *dev,
832 struct iw_request_info *info,
833 struct iw_param *frag, char *extra)
835 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
838 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
839 else if (frag->value < 256 ||
840 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
843 /* Fragment length must be even, so strip LSB. */
844 local->fragmentation_threshold = frag->value & ~0x1;
847 /* If the wlan card performs fragmentation in hardware/firmware,
848 * configure it here */
850 if (local->ops->set_frag_threshold)
851 local->ops->set_frag_threshold(
853 local->fragmentation_threshold);
858 static int ieee80211_ioctl_giwfrag(struct net_device *dev,
859 struct iw_request_info *info,
860 struct iw_param *frag, char *extra)
862 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
864 frag->value = local->fragmentation_threshold;
865 frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD);
872 static int ieee80211_ioctl_siwretry(struct net_device *dev,
873 struct iw_request_info *info,
874 struct iw_param *retry, char *extra)
876 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
878 if (retry->disabled ||
879 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
882 if (retry->flags & IW_RETRY_MAX)
883 local->long_retry_limit = retry->value;
884 else if (retry->flags & IW_RETRY_MIN)
885 local->short_retry_limit = retry->value;
887 local->long_retry_limit = retry->value;
888 local->short_retry_limit = retry->value;
891 if (local->ops->set_retry_limit) {
892 return local->ops->set_retry_limit(
894 local->short_retry_limit,
895 local->long_retry_limit);
902 static int ieee80211_ioctl_giwretry(struct net_device *dev,
903 struct iw_request_info *info,
904 struct iw_param *retry, char *extra)
906 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
909 if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
910 /* first return min value, iwconfig will ask max value
912 retry->flags |= IW_RETRY_LIMIT;
913 retry->value = local->short_retry_limit;
914 if (local->long_retry_limit != local->short_retry_limit)
915 retry->flags |= IW_RETRY_MIN;
918 if (retry->flags & IW_RETRY_MAX) {
919 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
920 retry->value = local->long_retry_limit;
926 static int ieee80211_ioctl_prism2_param(struct net_device *dev,
927 struct iw_request_info *info,
928 void *wrqu, char *extra)
930 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
931 struct ieee80211_sub_if_data *sdata;
932 int *i = (int *) extra;
934 int value = *(i + 1);
937 if (!capable(CAP_NET_ADMIN))
940 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
943 case PRISM2_PARAM_IEEE_802_1X:
944 if (local->ops->set_ieee8021x)
945 ret = local->ops->set_ieee8021x(local_to_hw(local),
948 printk(KERN_DEBUG "%s: failed to set IEEE 802.1X (%d) "
949 "for low-level driver\n", dev->name, value);
951 sdata->ieee802_1x = value;
954 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
955 if (sdata->type == IEEE80211_IF_TYPE_AP) {
957 sdata->flags |= IEEE80211_SDATA_USE_PROTECTION;
959 sdata->flags &= ~IEEE80211_SDATA_USE_PROTECTION;
960 ieee80211_erp_info_change_notify(dev,
961 IEEE80211_ERP_CHANGE_PROTECTION);
967 case PRISM2_PARAM_PREAMBLE:
968 if (sdata->type != IEEE80211_IF_TYPE_AP) {
970 sdata->flags |= IEEE80211_SDATA_SHORT_PREAMBLE;
972 sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE;
973 ieee80211_erp_info_change_notify(dev,
974 IEEE80211_ERP_CHANGE_PREAMBLE);
980 case PRISM2_PARAM_SHORT_SLOT_TIME:
982 local->hw.conf.flags |= IEEE80211_CONF_SHORT_SLOT_TIME;
984 local->hw.conf.flags &= ~IEEE80211_CONF_SHORT_SLOT_TIME;
985 if (ieee80211_hw_config(local))
989 case PRISM2_PARAM_NEXT_MODE:
990 local->next_mode = value;
993 case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
994 local->key_tx_rx_threshold = value;
997 case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
998 local->wifi_wme_noack_test = value;
1001 case PRISM2_PARAM_SCAN_FLAGS:
1002 local->scan_flags = value;
1005 case PRISM2_PARAM_MIXED_CELL:
1006 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1007 sdata->type != IEEE80211_IF_TYPE_IBSS)
1011 sdata->u.sta.flags |= IEEE80211_STA_MIXED_CELL;
1013 sdata->u.sta.flags &= ~IEEE80211_STA_MIXED_CELL;
1017 case PRISM2_PARAM_HW_MODES:
1018 local->enabled_modes = value;
1021 case PRISM2_PARAM_CREATE_IBSS:
1022 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
1026 sdata->u.sta.flags |= IEEE80211_STA_CREATE_IBSS;
1028 sdata->u.sta.flags &= ~IEEE80211_STA_CREATE_IBSS;
1031 case PRISM2_PARAM_WMM_ENABLED:
1032 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1033 sdata->type != IEEE80211_IF_TYPE_IBSS)
1037 sdata->u.sta.flags |= IEEE80211_STA_WMM_ENABLED;
1039 sdata->u.sta.flags &= ~IEEE80211_STA_WMM_ENABLED;
1051 static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
1052 struct iw_request_info *info,
1053 void *wrqu, char *extra)
1055 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1056 struct ieee80211_sub_if_data *sdata;
1057 int *param = (int *) extra;
1060 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1063 case PRISM2_PARAM_IEEE_802_1X:
1064 *param = sdata->ieee802_1x;
1067 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
1068 *param = !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION);
1071 case PRISM2_PARAM_PREAMBLE:
1072 *param = !!(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
1075 case PRISM2_PARAM_SHORT_SLOT_TIME:
1076 *param = !!(local->hw.conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME);
1079 case PRISM2_PARAM_NEXT_MODE:
1080 *param = local->next_mode;
1083 case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
1084 *param = local->key_tx_rx_threshold;
1087 case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
1088 *param = local->wifi_wme_noack_test;
1091 case PRISM2_PARAM_SCAN_FLAGS:
1092 *param = local->scan_flags;
1095 case PRISM2_PARAM_HW_MODES:
1096 *param = local->enabled_modes;
1099 case PRISM2_PARAM_CREATE_IBSS:
1100 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
1103 *param = !!(sdata->u.sta.flags &
1104 IEEE80211_STA_CREATE_IBSS);
1107 case PRISM2_PARAM_MIXED_CELL:
1108 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1109 sdata->type != IEEE80211_IF_TYPE_IBSS)
1112 *param = !!(sdata->u.sta.flags &
1113 IEEE80211_STA_MIXED_CELL);
1115 case PRISM2_PARAM_WMM_ENABLED:
1116 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1117 sdata->type != IEEE80211_IF_TYPE_IBSS)
1120 *param = !!(sdata->u.sta.flags &
1121 IEEE80211_STA_WMM_ENABLED);
1131 static int ieee80211_ioctl_siwmlme(struct net_device *dev,
1132 struct iw_request_info *info,
1133 struct iw_point *data, char *extra)
1135 struct ieee80211_sub_if_data *sdata;
1136 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1138 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1139 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1140 sdata->type != IEEE80211_IF_TYPE_IBSS)
1143 switch (mlme->cmd) {
1144 case IW_MLME_DEAUTH:
1145 /* TODO: mlme->addr.sa_data */
1146 return ieee80211_sta_deauthenticate(dev, mlme->reason_code);
1147 case IW_MLME_DISASSOC:
1148 /* TODO: mlme->addr.sa_data */
1149 return ieee80211_sta_disassociate(dev, mlme->reason_code);
1156 static int ieee80211_ioctl_siwencode(struct net_device *dev,
1157 struct iw_request_info *info,
1158 struct iw_point *erq, char *keybuf)
1160 struct ieee80211_sub_if_data *sdata;
1161 int idx, i, alg = ALG_WEP;
1162 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1164 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1166 idx = erq->flags & IW_ENCODE_INDEX;
1168 if (sdata->default_key)
1169 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1170 if (sdata->default_key == sdata->keys[i]) {
1175 } else if (idx < 1 || idx > 4)
1180 if (erq->flags & IW_ENCODE_DISABLED)
1182 else if (erq->length == 0) {
1183 /* No key data - just set the default TX key index */
1184 if (sdata->default_key != sdata->keys[idx]) {
1185 ieee80211_debugfs_key_remove_default(sdata);
1186 sdata->default_key = sdata->keys[idx];
1187 if (sdata->default_key)
1188 ieee80211_debugfs_key_add_default(sdata);
1193 return ieee80211_set_encryption(
1196 !sdata->default_key,
1197 keybuf, erq->length);
1201 static int ieee80211_ioctl_giwencode(struct net_device *dev,
1202 struct iw_request_info *info,
1203 struct iw_point *erq, char *key)
1205 struct ieee80211_sub_if_data *sdata;
1208 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1210 idx = erq->flags & IW_ENCODE_INDEX;
1211 if (idx < 1 || idx > 4) {
1213 if (!sdata->default_key)
1215 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1216 if (sdata->default_key == sdata->keys[i]) {
1226 erq->flags = idx + 1;
1228 if (!sdata->keys[idx]) {
1230 erq->flags |= IW_ENCODE_DISABLED;
1234 memcpy(key, sdata->keys[idx]->conf.key,
1235 min((int)erq->length, sdata->keys[idx]->conf.keylen));
1236 erq->length = sdata->keys[idx]->conf.keylen;
1237 erq->flags |= IW_ENCODE_ENABLED;
1242 static int ieee80211_ioctl_siwauth(struct net_device *dev,
1243 struct iw_request_info *info,
1244 struct iw_param *data, char *extra)
1246 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1247 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1250 switch (data->flags & IW_AUTH_INDEX) {
1251 case IW_AUTH_WPA_VERSION:
1252 case IW_AUTH_CIPHER_PAIRWISE:
1253 case IW_AUTH_CIPHER_GROUP:
1254 case IW_AUTH_WPA_ENABLED:
1255 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1257 case IW_AUTH_KEY_MGMT:
1258 if (sdata->type != IEEE80211_IF_TYPE_STA)
1262 * Key management was set by wpa_supplicant,
1263 * we only need this to associate to a network
1264 * that has privacy enabled regardless of not
1267 sdata->u.sta.key_management_enabled = !!data->value;
1270 case IW_AUTH_80211_AUTH_ALG:
1271 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1272 sdata->type == IEEE80211_IF_TYPE_IBSS)
1273 sdata->u.sta.auth_algs = data->value;
1277 case IW_AUTH_PRIVACY_INVOKED:
1278 if (local->ops->set_privacy_invoked)
1279 ret = local->ops->set_privacy_invoked(
1280 local_to_hw(local), data->value);
1289 /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
1290 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
1292 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1293 struct iw_statistics *wstats = &local->wstats;
1294 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1295 struct sta_info *sta = NULL;
1297 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1298 sdata->type == IEEE80211_IF_TYPE_IBSS)
1299 sta = sta_info_get(local, sdata->u.sta.bssid);
1301 wstats->discard.fragment = 0;
1302 wstats->discard.misc = 0;
1303 wstats->qual.qual = 0;
1304 wstats->qual.level = 0;
1305 wstats->qual.noise = 0;
1306 wstats->qual.updated = IW_QUAL_ALL_INVALID;
1308 wstats->qual.level = sta->last_rssi;
1309 wstats->qual.qual = sta->last_signal;
1310 wstats->qual.noise = sta->last_noise;
1311 wstats->qual.updated = local->wstats_flags;
1317 static int ieee80211_ioctl_giwauth(struct net_device *dev,
1318 struct iw_request_info *info,
1319 struct iw_param *data, char *extra)
1321 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1324 switch (data->flags & IW_AUTH_INDEX) {
1325 case IW_AUTH_80211_AUTH_ALG:
1326 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1327 sdata->type == IEEE80211_IF_TYPE_IBSS)
1328 data->value = sdata->u.sta.auth_algs;
1340 static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
1341 struct iw_request_info *info,
1342 struct iw_point *erq, char *extra)
1344 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1345 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
1349 case IW_ENCODE_ALG_NONE:
1352 case IW_ENCODE_ALG_WEP:
1355 case IW_ENCODE_ALG_TKIP:
1358 case IW_ENCODE_ALG_CCMP:
1365 if (erq->flags & IW_ENCODE_DISABLED)
1368 idx = erq->flags & IW_ENCODE_INDEX;
1369 if (idx < 1 || idx > 4) {
1371 if (!sdata->default_key)
1373 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1374 if (sdata->default_key == sdata->keys[i]) {
1384 return ieee80211_set_encryption(dev, ext->addr.sa_data, idx, alg,
1386 IW_ENCODE_EXT_SET_TX_KEY,
1387 ext->key, ext->key_len);
1391 static const struct iw_priv_args ieee80211_ioctl_priv[] = {
1392 { PRISM2_IOCTL_PRISM2_PARAM,
1393 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" },
1394 { PRISM2_IOCTL_GET_PRISM2_PARAM,
1395 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1396 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" },
1399 /* Structures to export the Wireless Handlers */
1401 static const iw_handler ieee80211_handler[] =
1403 (iw_handler) NULL, /* SIOCSIWCOMMIT */
1404 (iw_handler) ieee80211_ioctl_giwname, /* SIOCGIWNAME */
1405 (iw_handler) NULL, /* SIOCSIWNWID */
1406 (iw_handler) NULL, /* SIOCGIWNWID */
1407 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
1408 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
1409 (iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */
1410 (iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */
1411 (iw_handler) NULL, /* SIOCSIWSENS */
1412 (iw_handler) NULL, /* SIOCGIWSENS */
1413 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
1414 (iw_handler) ieee80211_ioctl_giwrange, /* SIOCGIWRANGE */
1415 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
1416 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
1417 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
1418 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
1419 iw_handler_set_spy, /* SIOCSIWSPY */
1420 iw_handler_get_spy, /* SIOCGIWSPY */
1421 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
1422 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
1423 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
1424 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
1425 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */
1426 (iw_handler) NULL, /* SIOCGIWAPLIST */
1427 (iw_handler) ieee80211_ioctl_siwscan, /* SIOCSIWSCAN */
1428 (iw_handler) ieee80211_ioctl_giwscan, /* SIOCGIWSCAN */
1429 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
1430 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
1431 (iw_handler) NULL, /* SIOCSIWNICKN */
1432 (iw_handler) NULL, /* SIOCGIWNICKN */
1433 (iw_handler) NULL, /* -- hole -- */
1434 (iw_handler) NULL, /* -- hole -- */
1435 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
1436 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
1437 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
1438 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
1439 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
1440 (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */
1441 (iw_handler) NULL, /* SIOCSIWTXPOW */
1442 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
1443 (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */
1444 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
1445 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
1446 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
1447 (iw_handler) NULL, /* SIOCSIWPOWER */
1448 (iw_handler) NULL, /* SIOCGIWPOWER */
1449 (iw_handler) NULL, /* -- hole -- */
1450 (iw_handler) NULL, /* -- hole -- */
1451 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */
1452 (iw_handler) NULL, /* SIOCGIWGENIE */
1453 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */
1454 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */
1455 (iw_handler) ieee80211_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
1456 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
1457 (iw_handler) NULL, /* SIOCSIWPMKSA */
1458 (iw_handler) NULL, /* -- hole -- */
1461 static const iw_handler ieee80211_private_handler[] =
1462 { /* SIOCIWFIRSTPRIV + */
1463 (iw_handler) ieee80211_ioctl_prism2_param, /* 0 */
1464 (iw_handler) ieee80211_ioctl_get_prism2_param, /* 1 */
1467 const struct iw_handler_def ieee80211_iw_handler_def =
1469 .num_standard = ARRAY_SIZE(ieee80211_handler),
1470 .num_private = ARRAY_SIZE(ieee80211_private_handler),
1471 .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv),
1472 .standard = (iw_handler *) ieee80211_handler,
1473 .private = (iw_handler *) ieee80211_private_handler,
1474 .private_args = (struct iw_priv_args *) ieee80211_ioctl_priv,
1475 .get_wireless_stats = ieee80211_get_wireless_stats,