at v2.6.29 1118 lines 30 kB view raw
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 "led.h" 25#include "rate.h" 26#include "wpa.h" 27#include "aes_ccm.h" 28 29 30static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr, 31 int idx, int alg, int remove, 32 int set_tx_key, const u8 *_key, 33 size_t key_len) 34{ 35 struct ieee80211_local *local = sdata->local; 36 struct sta_info *sta; 37 struct ieee80211_key *key; 38 int err; 39 40 if (idx < 0 || idx >= NUM_DEFAULT_KEYS) { 41 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n", 42 sdata->dev->name, idx); 43 return -EINVAL; 44 } 45 46 if (remove) { 47 rcu_read_lock(); 48 49 err = 0; 50 51 if (is_broadcast_ether_addr(sta_addr)) { 52 key = sdata->keys[idx]; 53 } else { 54 sta = sta_info_get(local, sta_addr); 55 if (!sta) { 56 err = -ENOENT; 57 goto out_unlock; 58 } 59 key = sta->key; 60 } 61 62 ieee80211_key_free(key); 63 } else { 64 key = ieee80211_key_alloc(alg, idx, key_len, _key); 65 if (!key) 66 return -ENOMEM; 67 68 sta = NULL; 69 err = 0; 70 71 rcu_read_lock(); 72 73 if (!is_broadcast_ether_addr(sta_addr)) { 74 set_tx_key = 0; 75 /* 76 * According to the standard, the key index of a 77 * pairwise key must be zero. However, some AP are 78 * broken when it comes to WEP key indices, so we 79 * work around this. 80 */ 81 if (idx != 0 && alg != ALG_WEP) { 82 ieee80211_key_free(key); 83 err = -EINVAL; 84 goto out_unlock; 85 } 86 87 sta = sta_info_get(local, sta_addr); 88 if (!sta) { 89 ieee80211_key_free(key); 90 err = -ENOENT; 91 goto out_unlock; 92 } 93 } 94 95 if (alg == ALG_WEP && 96 key_len != LEN_WEP40 && key_len != LEN_WEP104) { 97 ieee80211_key_free(key); 98 err = -EINVAL; 99 goto out_unlock; 100 } 101 102 ieee80211_key_link(key, sdata, sta); 103 104 if (set_tx_key || (!sta && !sdata->default_key && key)) 105 ieee80211_set_default_key(sdata, idx); 106 } 107 108 out_unlock: 109 rcu_read_unlock(); 110 111 return err; 112} 113 114static int ieee80211_ioctl_siwgenie(struct net_device *dev, 115 struct iw_request_info *info, 116 struct iw_point *data, char *extra) 117{ 118 struct ieee80211_sub_if_data *sdata; 119 120 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 121 122 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) 123 return -EOPNOTSUPP; 124 125 if (sdata->vif.type == NL80211_IFTYPE_STATION || 126 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 127 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length); 128 if (ret) 129 return ret; 130 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 131 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 132 return 0; 133 } 134 135 return -EOPNOTSUPP; 136} 137 138static int ieee80211_ioctl_giwrange(struct net_device *dev, 139 struct iw_request_info *info, 140 struct iw_point *data, char *extra) 141{ 142 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 143 struct iw_range *range = (struct iw_range *) extra; 144 enum ieee80211_band band; 145 int c = 0; 146 147 data->length = sizeof(struct iw_range); 148 memset(range, 0, sizeof(struct iw_range)); 149 150 range->we_version_compiled = WIRELESS_EXT; 151 range->we_version_source = 21; 152 range->retry_capa = IW_RETRY_LIMIT; 153 range->retry_flags = IW_RETRY_LIMIT; 154 range->min_retry = 0; 155 range->max_retry = 255; 156 range->min_rts = 0; 157 range->max_rts = 2347; 158 range->min_frag = 256; 159 range->max_frag = 2346; 160 161 range->encoding_size[0] = 5; 162 range->encoding_size[1] = 13; 163 range->num_encoding_sizes = 2; 164 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 165 166 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC || 167 local->hw.flags & IEEE80211_HW_SIGNAL_DB) 168 range->max_qual.level = local->hw.max_signal; 169 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 170 range->max_qual.level = -110; 171 else 172 range->max_qual.level = 0; 173 174 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) 175 range->max_qual.noise = -110; 176 else 177 range->max_qual.noise = 0; 178 179 range->max_qual.qual = 100; 180 range->max_qual.updated = local->wstats_flags; 181 182 range->avg_qual.qual = 50; 183 /* not always true but better than nothing */ 184 range->avg_qual.level = range->max_qual.level / 2; 185 range->avg_qual.noise = range->max_qual.noise / 2; 186 range->avg_qual.updated = local->wstats_flags; 187 188 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 189 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 190 191 192 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { 193 int i; 194 struct ieee80211_supported_band *sband; 195 196 sband = local->hw.wiphy->bands[band]; 197 198 if (!sband) 199 continue; 200 201 for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) { 202 struct ieee80211_channel *chan = &sband->channels[i]; 203 204 if (!(chan->flags & IEEE80211_CHAN_DISABLED)) { 205 range->freq[c].i = 206 ieee80211_frequency_to_channel( 207 chan->center_freq); 208 range->freq[c].m = chan->center_freq; 209 range->freq[c].e = 6; 210 c++; 211 } 212 } 213 } 214 range->num_channels = c; 215 range->num_frequency = c; 216 217 IW_EVENT_CAPA_SET_KERNEL(range->event_capa); 218 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); 219 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); 220 221 range->scan_capa |= IW_SCAN_CAPA_ESSID; 222 223 return 0; 224} 225 226 227static int ieee80211_ioctl_siwfreq(struct net_device *dev, 228 struct iw_request_info *info, 229 struct iw_freq *freq, char *extra) 230{ 231 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 232 233 if (sdata->vif.type == NL80211_IFTYPE_STATION) 234 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 235 236 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 237 if (freq->e == 0) { 238 if (freq->m < 0) { 239 if (sdata->vif.type == NL80211_IFTYPE_STATION) 240 sdata->u.sta.flags |= 241 IEEE80211_STA_AUTO_CHANNEL_SEL; 242 return 0; 243 } else 244 return ieee80211_set_freq(sdata, 245 ieee80211_channel_to_frequency(freq->m)); 246 } else { 247 int i, div = 1000000; 248 for (i = 0; i < freq->e; i++) 249 div /= 10; 250 if (div > 0) 251 return ieee80211_set_freq(sdata, freq->m / div); 252 else 253 return -EINVAL; 254 } 255} 256 257 258static int ieee80211_ioctl_giwfreq(struct net_device *dev, 259 struct iw_request_info *info, 260 struct iw_freq *freq, char *extra) 261{ 262 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 263 264 freq->m = local->hw.conf.channel->center_freq; 265 freq->e = 6; 266 267 return 0; 268} 269 270 271static int ieee80211_ioctl_siwessid(struct net_device *dev, 272 struct iw_request_info *info, 273 struct iw_point *data, char *ssid) 274{ 275 struct ieee80211_sub_if_data *sdata; 276 size_t len = data->length; 277 278 /* iwconfig uses nul termination in SSID.. */ 279 if (len > 0 && ssid[len - 1] == '\0') 280 len--; 281 282 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 283 if (sdata->vif.type == NL80211_IFTYPE_STATION || 284 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 285 int ret; 286 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 287 if (len > IEEE80211_MAX_SSID_LEN) 288 return -EINVAL; 289 memcpy(sdata->u.sta.ssid, ssid, len); 290 sdata->u.sta.ssid_len = len; 291 return 0; 292 } 293 if (data->flags) 294 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 295 else 296 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL; 297 ret = ieee80211_sta_set_ssid(sdata, ssid, len); 298 if (ret) 299 return ret; 300 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 301 return 0; 302 } 303 304 return -EOPNOTSUPP; 305} 306 307 308static int ieee80211_ioctl_giwessid(struct net_device *dev, 309 struct iw_request_info *info, 310 struct iw_point *data, char *ssid) 311{ 312 size_t len; 313 314 struct ieee80211_sub_if_data *sdata; 315 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 316 if (sdata->vif.type == NL80211_IFTYPE_STATION || 317 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 318 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 319 if (res == 0) { 320 data->length = len; 321 data->flags = 1; 322 } else 323 data->flags = 0; 324 return res; 325 } 326 327 return -EOPNOTSUPP; 328} 329 330 331static int ieee80211_ioctl_siwap(struct net_device *dev, 332 struct iw_request_info *info, 333 struct sockaddr *ap_addr, char *extra) 334{ 335 struct ieee80211_sub_if_data *sdata; 336 337 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 338 if (sdata->vif.type == NL80211_IFTYPE_STATION || 339 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 340 int ret; 341 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 342 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data, 343 ETH_ALEN); 344 return 0; 345 } 346 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) 347 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL | 348 IEEE80211_STA_AUTO_CHANNEL_SEL; 349 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data)) 350 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL; 351 else 352 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 353 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); 354 if (ret) 355 return ret; 356 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 357 return 0; 358 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 359 /* 360 * If it is necessary to update the WDS peer address 361 * while the interface is running, then we need to do 362 * more work here, namely if it is running we need to 363 * add a new and remove the old STA entry, this is 364 * normally handled by _open() and _stop(). 365 */ 366 if (netif_running(dev)) 367 return -EBUSY; 368 369 memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data, 370 ETH_ALEN); 371 372 return 0; 373 } 374 375 return -EOPNOTSUPP; 376} 377 378 379static int ieee80211_ioctl_giwap(struct net_device *dev, 380 struct iw_request_info *info, 381 struct sockaddr *ap_addr, char *extra) 382{ 383 struct ieee80211_sub_if_data *sdata; 384 385 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 386 if (sdata->vif.type == NL80211_IFTYPE_STATION || 387 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 388 if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATED || 389 sdata->u.sta.state == IEEE80211_STA_MLME_IBSS_JOINED) { 390 ap_addr->sa_family = ARPHRD_ETHER; 391 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); 392 return 0; 393 } else { 394 memset(&ap_addr->sa_data, 0, ETH_ALEN); 395 return 0; 396 } 397 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 398 ap_addr->sa_family = ARPHRD_ETHER; 399 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 400 return 0; 401 } 402 403 return -EOPNOTSUPP; 404} 405 406 407static int ieee80211_ioctl_siwscan(struct net_device *dev, 408 struct iw_request_info *info, 409 union iwreq_data *wrqu, char *extra) 410{ 411 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 412 struct iw_scan_req *req = NULL; 413 u8 *ssid = NULL; 414 size_t ssid_len = 0; 415 416 if (!netif_running(dev)) 417 return -ENETDOWN; 418 419 if (sdata->vif.type != NL80211_IFTYPE_STATION && 420 sdata->vif.type != NL80211_IFTYPE_ADHOC && 421 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 422 return -EOPNOTSUPP; 423 424 /* if SSID was specified explicitly then use that */ 425 if (wrqu->data.length == sizeof(struct iw_scan_req) && 426 wrqu->data.flags & IW_SCAN_THIS_ESSID) { 427 req = (struct iw_scan_req *)extra; 428 ssid = req->essid; 429 ssid_len = req->essid_len; 430 } 431 432 return ieee80211_request_scan(sdata, ssid, ssid_len); 433} 434 435 436static int ieee80211_ioctl_giwscan(struct net_device *dev, 437 struct iw_request_info *info, 438 struct iw_point *data, char *extra) 439{ 440 int res; 441 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 442 struct ieee80211_sub_if_data *sdata; 443 444 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 445 446 if (local->sw_scanning || local->hw_scanning) 447 return -EAGAIN; 448 449 res = ieee80211_scan_results(local, info, extra, data->length); 450 if (res >= 0) { 451 data->length = res; 452 return 0; 453 } 454 data->length = 0; 455 return res; 456} 457 458 459static int ieee80211_ioctl_siwrate(struct net_device *dev, 460 struct iw_request_info *info, 461 struct iw_param *rate, char *extra) 462{ 463 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 464 int i, err = -EINVAL; 465 u32 target_rate = rate->value / 100000; 466 struct ieee80211_sub_if_data *sdata; 467 struct ieee80211_supported_band *sband; 468 469 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 470 471 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 472 473 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 474 * target_rate = X, rate->fixed = 1 means only rate X 475 * target_rate = X, rate->fixed = 0 means all rates <= X */ 476 sdata->max_ratectrl_rateidx = -1; 477 sdata->force_unicast_rateidx = -1; 478 if (rate->value < 0) 479 return 0; 480 481 for (i=0; i< sband->n_bitrates; i++) { 482 struct ieee80211_rate *brate = &sband->bitrates[i]; 483 int this_rate = brate->bitrate; 484 485 if (target_rate == this_rate) { 486 sdata->max_ratectrl_rateidx = i; 487 if (rate->fixed) 488 sdata->force_unicast_rateidx = i; 489 err = 0; 490 break; 491 } 492 } 493 return err; 494} 495 496static int ieee80211_ioctl_giwrate(struct net_device *dev, 497 struct iw_request_info *info, 498 struct iw_param *rate, char *extra) 499{ 500 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 501 struct sta_info *sta; 502 struct ieee80211_sub_if_data *sdata; 503 struct ieee80211_supported_band *sband; 504 505 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 506 507 if (sdata->vif.type != NL80211_IFTYPE_STATION) 508 return -EOPNOTSUPP; 509 510 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 511 512 rcu_read_lock(); 513 514 sta = sta_info_get(local, sdata->u.sta.bssid); 515 516 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) 517 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; 518 else 519 rate->value = 0; 520 521 rcu_read_unlock(); 522 523 if (!sta) 524 return -ENODEV; 525 526 rate->value *= 100000; 527 528 return 0; 529} 530 531static int ieee80211_ioctl_siwtxpower(struct net_device *dev, 532 struct iw_request_info *info, 533 union iwreq_data *data, char *extra) 534{ 535 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 536 struct ieee80211_channel* chan = local->hw.conf.channel; 537 u32 reconf_flags = 0; 538 int new_power_level; 539 540 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 541 return -EINVAL; 542 if (data->txpower.flags & IW_TXPOW_RANGE) 543 return -EINVAL; 544 if (!chan) 545 return -EINVAL; 546 547 if (data->txpower.fixed) 548 new_power_level = min(data->txpower.value, chan->max_power); 549 else /* Automatic power level setting */ 550 new_power_level = chan->max_power; 551 552 if (local->hw.conf.power_level != new_power_level) { 553 local->hw.conf.power_level = new_power_level; 554 reconf_flags |= IEEE80211_CONF_CHANGE_POWER; 555 } 556 557 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { 558 local->hw.conf.radio_enabled = !(data->txpower.disabled); 559 reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED; 560 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 561 } 562 563 if (reconf_flags) 564 ieee80211_hw_config(local, reconf_flags); 565 566 return 0; 567} 568 569static int ieee80211_ioctl_giwtxpower(struct net_device *dev, 570 struct iw_request_info *info, 571 union iwreq_data *data, char *extra) 572{ 573 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 574 575 data->txpower.fixed = 1; 576 data->txpower.disabled = !(local->hw.conf.radio_enabled); 577 data->txpower.value = local->hw.conf.power_level; 578 data->txpower.flags = IW_TXPOW_DBM; 579 580 return 0; 581} 582 583static int ieee80211_ioctl_siwrts(struct net_device *dev, 584 struct iw_request_info *info, 585 struct iw_param *rts, char *extra) 586{ 587 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 588 589 if (rts->disabled) 590 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 591 else if (!rts->fixed) 592 /* if the rts value is not fixed, then take default */ 593 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 594 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) 595 return -EINVAL; 596 else 597 local->rts_threshold = rts->value; 598 599 /* If the wlan card performs RTS/CTS in hardware/firmware, 600 * configure it here */ 601 602 if (local->ops->set_rts_threshold) 603 local->ops->set_rts_threshold(local_to_hw(local), 604 local->rts_threshold); 605 606 return 0; 607} 608 609static int ieee80211_ioctl_giwrts(struct net_device *dev, 610 struct iw_request_info *info, 611 struct iw_param *rts, char *extra) 612{ 613 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 614 615 rts->value = local->rts_threshold; 616 rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD); 617 rts->fixed = 1; 618 619 return 0; 620} 621 622 623static int ieee80211_ioctl_siwfrag(struct net_device *dev, 624 struct iw_request_info *info, 625 struct iw_param *frag, char *extra) 626{ 627 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 628 629 if (frag->disabled) 630 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 631 else if (!frag->fixed) 632 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 633 else if (frag->value < 256 || 634 frag->value > IEEE80211_MAX_FRAG_THRESHOLD) 635 return -EINVAL; 636 else { 637 /* Fragment length must be even, so strip LSB. */ 638 local->fragmentation_threshold = frag->value & ~0x1; 639 } 640 641 return 0; 642} 643 644static int ieee80211_ioctl_giwfrag(struct net_device *dev, 645 struct iw_request_info *info, 646 struct iw_param *frag, char *extra) 647{ 648 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 649 650 frag->value = local->fragmentation_threshold; 651 frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD); 652 frag->fixed = 1; 653 654 return 0; 655} 656 657 658static int ieee80211_ioctl_siwretry(struct net_device *dev, 659 struct iw_request_info *info, 660 struct iw_param *retry, char *extra) 661{ 662 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 663 664 if (retry->disabled || 665 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) 666 return -EINVAL; 667 668 if (retry->flags & IW_RETRY_MAX) { 669 local->hw.conf.long_frame_max_tx_count = retry->value; 670 } else if (retry->flags & IW_RETRY_MIN) { 671 local->hw.conf.short_frame_max_tx_count = retry->value; 672 } else { 673 local->hw.conf.long_frame_max_tx_count = retry->value; 674 local->hw.conf.short_frame_max_tx_count = retry->value; 675 } 676 677 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 678 679 return 0; 680} 681 682 683static int ieee80211_ioctl_giwretry(struct net_device *dev, 684 struct iw_request_info *info, 685 struct iw_param *retry, char *extra) 686{ 687 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 688 689 retry->disabled = 0; 690 if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) { 691 /* first return min value, iwconfig will ask max value 692 * later if needed */ 693 retry->flags |= IW_RETRY_LIMIT; 694 retry->value = local->hw.conf.short_frame_max_tx_count; 695 if (local->hw.conf.long_frame_max_tx_count != 696 local->hw.conf.short_frame_max_tx_count) 697 retry->flags |= IW_RETRY_MIN; 698 return 0; 699 } 700 if (retry->flags & IW_RETRY_MAX) { 701 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 702 retry->value = local->hw.conf.long_frame_max_tx_count; 703 } 704 705 return 0; 706} 707 708static int ieee80211_ioctl_siwmlme(struct net_device *dev, 709 struct iw_request_info *info, 710 struct iw_point *data, char *extra) 711{ 712 struct ieee80211_sub_if_data *sdata; 713 struct iw_mlme *mlme = (struct iw_mlme *) extra; 714 715 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 716 if (sdata->vif.type != NL80211_IFTYPE_STATION && 717 sdata->vif.type != NL80211_IFTYPE_ADHOC) 718 return -EINVAL; 719 720 switch (mlme->cmd) { 721 case IW_MLME_DEAUTH: 722 /* TODO: mlme->addr.sa_data */ 723 return ieee80211_sta_deauthenticate(sdata, mlme->reason_code); 724 case IW_MLME_DISASSOC: 725 /* TODO: mlme->addr.sa_data */ 726 return ieee80211_sta_disassociate(sdata, mlme->reason_code); 727 default: 728 return -EOPNOTSUPP; 729 } 730} 731 732 733static int ieee80211_ioctl_siwencode(struct net_device *dev, 734 struct iw_request_info *info, 735 struct iw_point *erq, char *keybuf) 736{ 737 struct ieee80211_sub_if_data *sdata; 738 int idx, i, alg = ALG_WEP; 739 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 740 int remove = 0; 741 742 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 743 744 idx = erq->flags & IW_ENCODE_INDEX; 745 if (idx == 0) { 746 if (sdata->default_key) 747 for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 748 if (sdata->default_key == sdata->keys[i]) { 749 idx = i; 750 break; 751 } 752 } 753 } else if (idx < 1 || idx > 4) 754 return -EINVAL; 755 else 756 idx--; 757 758 if (erq->flags & IW_ENCODE_DISABLED) 759 remove = 1; 760 else if (erq->length == 0) { 761 /* No key data - just set the default TX key index */ 762 ieee80211_set_default_key(sdata, idx); 763 return 0; 764 } 765 766 return ieee80211_set_encryption( 767 sdata, bcaddr, 768 idx, alg, remove, 769 !sdata->default_key, 770 keybuf, erq->length); 771} 772 773 774static int ieee80211_ioctl_giwencode(struct net_device *dev, 775 struct iw_request_info *info, 776 struct iw_point *erq, char *key) 777{ 778 struct ieee80211_sub_if_data *sdata; 779 int idx, i; 780 781 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 782 783 idx = erq->flags & IW_ENCODE_INDEX; 784 if (idx < 1 || idx > 4) { 785 idx = -1; 786 if (!sdata->default_key) 787 idx = 0; 788 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 789 if (sdata->default_key == sdata->keys[i]) { 790 idx = i; 791 break; 792 } 793 } 794 if (idx < 0) 795 return -EINVAL; 796 } else 797 idx--; 798 799 erq->flags = idx + 1; 800 801 if (!sdata->keys[idx]) { 802 erq->length = 0; 803 erq->flags |= IW_ENCODE_DISABLED; 804 return 0; 805 } 806 807 memcpy(key, sdata->keys[idx]->conf.key, 808 min_t(int, erq->length, sdata->keys[idx]->conf.keylen)); 809 erq->length = sdata->keys[idx]->conf.keylen; 810 erq->flags |= IW_ENCODE_ENABLED; 811 812 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 813 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 814 switch (ifsta->auth_alg) { 815 case WLAN_AUTH_OPEN: 816 case WLAN_AUTH_LEAP: 817 erq->flags |= IW_ENCODE_OPEN; 818 break; 819 case WLAN_AUTH_SHARED_KEY: 820 erq->flags |= IW_ENCODE_RESTRICTED; 821 break; 822 } 823 } 824 825 return 0; 826} 827 828static int ieee80211_ioctl_siwpower(struct net_device *dev, 829 struct iw_request_info *info, 830 struct iw_param *wrq, 831 char *extra) 832{ 833 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 834 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 835 struct ieee80211_conf *conf = &local->hw.conf; 836 int ret = 0, timeout = 0; 837 bool ps; 838 839 if (sdata->vif.type != NL80211_IFTYPE_STATION) 840 return -EINVAL; 841 842 if (wrq->disabled) { 843 ps = false; 844 timeout = 0; 845 goto set; 846 } 847 848 switch (wrq->flags & IW_POWER_MODE) { 849 case IW_POWER_ON: /* If not specified */ 850 case IW_POWER_MODE: /* If set all mask */ 851 case IW_POWER_ALL_R: /* If explicitely state all */ 852 ps = true; 853 break; 854 default: /* Otherwise we ignore */ 855 break; 856 } 857 858 if (wrq->flags & IW_POWER_TIMEOUT) 859 timeout = wrq->value / 1000; 860 861set: 862 if (ps == local->powersave && timeout == local->dynamic_ps_timeout) 863 return ret; 864 865 local->powersave = ps; 866 local->dynamic_ps_timeout = timeout; 867 868 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) { 869 if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) && 870 local->dynamic_ps_timeout > 0) 871 mod_timer(&local->dynamic_ps_timer, jiffies + 872 msecs_to_jiffies(local->dynamic_ps_timeout)); 873 else { 874 if (local->powersave) 875 conf->flags |= IEEE80211_CONF_PS; 876 else 877 conf->flags &= ~IEEE80211_CONF_PS; 878 } 879 ret = ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 880 } 881 882 return ret; 883} 884 885static int ieee80211_ioctl_giwpower(struct net_device *dev, 886 struct iw_request_info *info, 887 union iwreq_data *wrqu, 888 char *extra) 889{ 890 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 891 892 wrqu->power.disabled = !local->powersave; 893 894 return 0; 895} 896 897static int ieee80211_ioctl_siwauth(struct net_device *dev, 898 struct iw_request_info *info, 899 struct iw_param *data, char *extra) 900{ 901 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 902 int ret = 0; 903 904 switch (data->flags & IW_AUTH_INDEX) { 905 case IW_AUTH_WPA_VERSION: 906 case IW_AUTH_CIPHER_PAIRWISE: 907 case IW_AUTH_CIPHER_GROUP: 908 case IW_AUTH_WPA_ENABLED: 909 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 910 case IW_AUTH_KEY_MGMT: 911 break; 912 case IW_AUTH_DROP_UNENCRYPTED: 913 sdata->drop_unencrypted = !!data->value; 914 break; 915 case IW_AUTH_PRIVACY_INVOKED: 916 if (sdata->vif.type != NL80211_IFTYPE_STATION) 917 ret = -EINVAL; 918 else { 919 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; 920 /* 921 * Privacy invoked by wpa_supplicant, store the 922 * value and allow associating to a protected 923 * network without having a key up front. 924 */ 925 if (data->value) 926 sdata->u.sta.flags |= 927 IEEE80211_STA_PRIVACY_INVOKED; 928 } 929 break; 930 case IW_AUTH_80211_AUTH_ALG: 931 if (sdata->vif.type == NL80211_IFTYPE_STATION || 932 sdata->vif.type == NL80211_IFTYPE_ADHOC) 933 sdata->u.sta.auth_algs = data->value; 934 else 935 ret = -EOPNOTSUPP; 936 break; 937 default: 938 ret = -EOPNOTSUPP; 939 break; 940 } 941 return ret; 942} 943 944/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 945static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) 946{ 947 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 948 struct iw_statistics *wstats = &local->wstats; 949 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 950 struct sta_info *sta = NULL; 951 952 rcu_read_lock(); 953 954 if (sdata->vif.type == NL80211_IFTYPE_STATION || 955 sdata->vif.type == NL80211_IFTYPE_ADHOC) 956 sta = sta_info_get(local, sdata->u.sta.bssid); 957 if (!sta) { 958 wstats->discard.fragment = 0; 959 wstats->discard.misc = 0; 960 wstats->qual.qual = 0; 961 wstats->qual.level = 0; 962 wstats->qual.noise = 0; 963 wstats->qual.updated = IW_QUAL_ALL_INVALID; 964 } else { 965 wstats->qual.level = sta->last_signal; 966 wstats->qual.qual = sta->last_qual; 967 wstats->qual.noise = sta->last_noise; 968 wstats->qual.updated = local->wstats_flags; 969 } 970 971 rcu_read_unlock(); 972 973 return wstats; 974} 975 976static int ieee80211_ioctl_giwauth(struct net_device *dev, 977 struct iw_request_info *info, 978 struct iw_param *data, char *extra) 979{ 980 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 981 int ret = 0; 982 983 switch (data->flags & IW_AUTH_INDEX) { 984 case IW_AUTH_80211_AUTH_ALG: 985 if (sdata->vif.type == NL80211_IFTYPE_STATION || 986 sdata->vif.type == NL80211_IFTYPE_ADHOC) 987 data->value = sdata->u.sta.auth_algs; 988 else 989 ret = -EOPNOTSUPP; 990 break; 991 default: 992 ret = -EOPNOTSUPP; 993 break; 994 } 995 return ret; 996} 997 998 999static int ieee80211_ioctl_siwencodeext(struct net_device *dev, 1000 struct iw_request_info *info, 1001 struct iw_point *erq, char *extra) 1002{ 1003 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1004 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; 1005 int uninitialized_var(alg), idx, i, remove = 0; 1006 1007 switch (ext->alg) { 1008 case IW_ENCODE_ALG_NONE: 1009 remove = 1; 1010 break; 1011 case IW_ENCODE_ALG_WEP: 1012 alg = ALG_WEP; 1013 break; 1014 case IW_ENCODE_ALG_TKIP: 1015 alg = ALG_TKIP; 1016 break; 1017 case IW_ENCODE_ALG_CCMP: 1018 alg = ALG_CCMP; 1019 break; 1020 default: 1021 return -EOPNOTSUPP; 1022 } 1023 1024 if (erq->flags & IW_ENCODE_DISABLED) 1025 remove = 1; 1026 1027 idx = erq->flags & IW_ENCODE_INDEX; 1028 if (idx < 1 || idx > 4) { 1029 idx = -1; 1030 if (!sdata->default_key) 1031 idx = 0; 1032 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 1033 if (sdata->default_key == sdata->keys[i]) { 1034 idx = i; 1035 break; 1036 } 1037 } 1038 if (idx < 0) 1039 return -EINVAL; 1040 } else 1041 idx--; 1042 1043 return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg, 1044 remove, 1045 ext->ext_flags & 1046 IW_ENCODE_EXT_SET_TX_KEY, 1047 ext->key, ext->key_len); 1048} 1049 1050 1051/* Structures to export the Wireless Handlers */ 1052 1053static const iw_handler ieee80211_handler[] = 1054{ 1055 (iw_handler) NULL, /* SIOCSIWCOMMIT */ 1056 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ 1057 (iw_handler) NULL, /* SIOCSIWNWID */ 1058 (iw_handler) NULL, /* SIOCGIWNWID */ 1059 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ 1060 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ 1061 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ 1062 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ 1063 (iw_handler) NULL, /* SIOCSIWSENS */ 1064 (iw_handler) NULL, /* SIOCGIWSENS */ 1065 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ 1066 (iw_handler) ieee80211_ioctl_giwrange, /* SIOCGIWRANGE */ 1067 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ 1068 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ 1069 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ 1070 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ 1071 (iw_handler) NULL, /* SIOCSIWSPY */ 1072 (iw_handler) NULL, /* SIOCGIWSPY */ 1073 (iw_handler) NULL, /* SIOCSIWTHRSPY */ 1074 (iw_handler) NULL, /* SIOCGIWTHRSPY */ 1075 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ 1076 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 1077 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ 1078 (iw_handler) NULL, /* SIOCGIWAPLIST */ 1079 (iw_handler) ieee80211_ioctl_siwscan, /* SIOCSIWSCAN */ 1080 (iw_handler) ieee80211_ioctl_giwscan, /* SIOCGIWSCAN */ 1081 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */ 1082 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */ 1083 (iw_handler) NULL, /* SIOCSIWNICKN */ 1084 (iw_handler) NULL, /* SIOCGIWNICKN */ 1085 (iw_handler) NULL, /* -- hole -- */ 1086 (iw_handler) NULL, /* -- hole -- */ 1087 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ 1088 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ 1089 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ 1090 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ 1091 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ 1092 (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */ 1093 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ 1094 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 1095 (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */ 1096 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ 1097 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 1098 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 1099 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 1100 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ 1101 (iw_handler) NULL, /* -- hole -- */ 1102 (iw_handler) NULL, /* -- hole -- */ 1103 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ 1104 (iw_handler) NULL, /* SIOCGIWGENIE */ 1105 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */ 1106 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */ 1107 (iw_handler) ieee80211_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ 1108 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 1109 (iw_handler) NULL, /* SIOCSIWPMKSA */ 1110 (iw_handler) NULL, /* -- hole -- */ 1111}; 1112 1113const struct iw_handler_def ieee80211_iw_handler_def = 1114{ 1115 .num_standard = ARRAY_SIZE(ieee80211_handler), 1116 .standard = (iw_handler *) ieee80211_handler, 1117 .get_wireless_stats = ieee80211_get_wireless_stats, 1118};