1 /* 2 * cfg80211 - wext compat code 3 * 4 * This is temporary code until all wireless functionality is migrated 5 * into cfg80211, when that happens all the exports here go away and 6 * we directly assign the wireless handlers of wireless interfaces. 7 * 8 * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net> 9 */ 10 11 #include <linux/wireless.h> 12 #include <linux/nl80211.h> 13 #include <linux/if_arp.h> 14 #include <linux/etherdevice.h> 15 #include <linux/slab.h> 16 #include <net/iw_handler.h> 17 #include <net/cfg80211.h> 18 #include "wext-compat.h" 19 #include "core.h" 20 21 int cfg80211_wext_giwname(struct net_device *dev, 22 struct iw_request_info *info, 23 char *name, char *extra) 24 { 25 struct wireless_dev *wdev = dev->ieee80211_ptr; 26 struct ieee80211_supported_band *sband; 27 bool is_ht = false, is_a = false, is_b = false, is_g = false; 28 29 if (!wdev) 30 return -EOPNOTSUPP; 31 32 sband = wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; 33 if (sband) { 34 is_a = true; 35 is_ht |= sband->ht_cap.ht_supported; 36 } 37 38 sband = wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; 39 if (sband) { 40 int i; 41 /* Check for mandatory rates */ 42 for (i = 0; i < sband->n_bitrates; i++) { 43 if (sband->bitrates[i].bitrate == 10) 44 is_b = true; 45 if (sband->bitrates[i].bitrate == 60) 46 is_g = true; 47 } 48 is_ht |= sband->ht_cap.ht_supported; 49 } 50 51 strcpy(name, "IEEE 802.11"); 52 if (is_a) 53 strcat(name, "a"); 54 if (is_b) 55 strcat(name, "b"); 56 if (is_g) 57 strcat(name, "g"); 58 if (is_ht) 59 strcat(name, "n"); 60 61 return 0; 62 } 63 EXPORT_SYMBOL_GPL(cfg80211_wext_giwname); 64 65 int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, 66 u32 *mode, char *extra) 67 { 68 struct wireless_dev *wdev = dev->ieee80211_ptr; 69 struct cfg80211_registered_device *rdev; 70 struct vif_params vifparams; 71 enum nl80211_iftype type; 72 int ret; 73 74 rdev = wiphy_to_dev(wdev->wiphy); 75 76 switch (*mode) { 77 case IW_MODE_INFRA: 78 type = NL80211_IFTYPE_STATION; 79 break; 80 case IW_MODE_ADHOC: 81 type = NL80211_IFTYPE_ADHOC; 82 break; 83 case IW_MODE_REPEAT: 84 type = NL80211_IFTYPE_WDS; 85 break; 86 case IW_MODE_MONITOR: 87 type = NL80211_IFTYPE_MONITOR; 88 break; 89 default: 90 return -EINVAL; 91 } 92 93 if (type == wdev->iftype) 94 return 0; 95 96 memset(&vifparams, 0, sizeof(vifparams)); 97 98 cfg80211_lock_rdev(rdev); 99 ret = cfg80211_change_iface(rdev, dev, type, NULL, &vifparams); 100 cfg80211_unlock_rdev(rdev); 101 102 return ret; 103 } 104 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode); 105 106 int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, 107 u32 *mode, char *extra) 108 { 109 struct wireless_dev *wdev = dev->ieee80211_ptr; 110 111 if (!wdev) 112 return -EOPNOTSUPP; 113 114 switch (wdev->iftype) { 115 case NL80211_IFTYPE_AP: 116 *mode = IW_MODE_MASTER; 117 break; 118 case NL80211_IFTYPE_STATION: 119 *mode = IW_MODE_INFRA; 120 break; 121 case NL80211_IFTYPE_ADHOC: 122 *mode = IW_MODE_ADHOC; 123 break; 124 case NL80211_IFTYPE_MONITOR: 125 *mode = IW_MODE_MONITOR; 126 break; 127 case NL80211_IFTYPE_WDS: 128 *mode = IW_MODE_REPEAT; 129 break; 130 case NL80211_IFTYPE_AP_VLAN: 131 *mode = IW_MODE_SECOND; /* FIXME */ 132 break; 133 default: 134 *mode = IW_MODE_AUTO; 135 break; 136 } 137 return 0; 138 } 139 EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode); 140 141 142 int cfg80211_wext_giwrange(struct net_device *dev, 143 struct iw_request_info *info, 144 struct iw_point *data, char *extra) 145 { 146 struct wireless_dev *wdev = dev->ieee80211_ptr; 147 struct iw_range *range = (struct iw_range *) extra; 148 enum ieee80211_band band; 149 int i, c = 0; 150 151 if (!wdev) 152 return -EOPNOTSUPP; 153 154 data->length = sizeof(struct iw_range); 155 memset(range, 0, sizeof(struct iw_range)); 156 157 range->we_version_compiled = WIRELESS_EXT; 158 range->we_version_source = 21; 159 range->retry_capa = IW_RETRY_LIMIT; 160 range->retry_flags = IW_RETRY_LIMIT; 161 range->min_retry = 0; 162 range->max_retry = 255; 163 range->min_rts = 0; 164 range->max_rts = 2347; 165 range->min_frag = 256; 166 range->max_frag = 2346; 167 168 range->max_encoding_tokens = 4; 169 170 range->max_qual.updated = IW_QUAL_NOISE_INVALID; 171 172 switch (wdev->wiphy->signal_type) { 173 case CFG80211_SIGNAL_TYPE_NONE: 174 break; 175 case CFG80211_SIGNAL_TYPE_MBM: 176 range->max_qual.level = -110; 177 range->max_qual.qual = 70; 178 range->avg_qual.qual = 35; 179 range->max_qual.updated |= IW_QUAL_DBM; 180 range->max_qual.updated |= IW_QUAL_QUAL_UPDATED; 181 range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED; 182 break; 183 case CFG80211_SIGNAL_TYPE_UNSPEC: 184 range->max_qual.level = 100; 185 range->max_qual.qual = 100; 186 range->avg_qual.qual = 50; 187 range->max_qual.updated |= IW_QUAL_QUAL_UPDATED; 188 range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED; 189 break; 190 } 191 192 range->avg_qual.level = range->max_qual.level / 2; 193 range->avg_qual.noise = range->max_qual.noise / 2; 194 range->avg_qual.updated = range->max_qual.updated; 195 196 for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) { 197 switch (wdev->wiphy->cipher_suites[i]) { 198 case WLAN_CIPHER_SUITE_TKIP: 199 range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP | 200 IW_ENC_CAPA_WPA); 201 break; 202 203 case WLAN_CIPHER_SUITE_CCMP: 204 range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP | 205 IW_ENC_CAPA_WPA2); 206 break; 207 208 case WLAN_CIPHER_SUITE_WEP40: 209 range->encoding_size[range->num_encoding_sizes++] = 210 WLAN_KEY_LEN_WEP40; 211 break; 212 213 case WLAN_CIPHER_SUITE_WEP104: 214 range->encoding_size[range->num_encoding_sizes++] = 215 WLAN_KEY_LEN_WEP104; 216 break; 217 } 218 } 219 220 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { 221 struct ieee80211_supported_band *sband; 222 223 sband = wdev->wiphy->bands[band]; 224 225 if (!sband) 226 continue; 227 228 for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) { 229 struct ieee80211_channel *chan = &sband->channels[i]; 230 231 if (!(chan->flags & IEEE80211_CHAN_DISABLED)) { 232 range->freq[c].i = 233 ieee80211_frequency_to_channel( 234 chan->center_freq); 235 range->freq[c].m = chan->center_freq; 236 range->freq[c].e = 6; 237 c++; 238 } 239 } 240 } 241 range->num_channels = c; 242 range->num_frequency = c; 243 244 IW_EVENT_CAPA_SET_KERNEL(range->event_capa); 245 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); 246 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); 247 248 if (wdev->wiphy->max_scan_ssids > 0) 249 range->scan_capa |= IW_SCAN_CAPA_ESSID; 250 251 return 0; 252 } 253 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange); 254 255 256 /** 257 * cfg80211_wext_freq - get wext frequency for non-"auto" 258 * @wiphy: the wiphy 259 * @freq: the wext freq encoding 260 * 261 * Returns a frequency, or a negative error code, or 0 for auto. 262 */ 263 int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq) 264 { 265 /* 266 * Parse frequency - return 0 for auto and 267 * -EINVAL for impossible things. 268 */ 269 if (freq->e == 0) { 270 enum ieee80211_band band = IEEE80211_BAND_2GHZ; 271 if (freq->m < 0) 272 return 0; 273 if (freq->m > 14) 274 band = IEEE80211_BAND_5GHZ; 275 return ieee80211_channel_to_frequency(freq->m, band); 276 } else { 277 int i, div = 1000000; 278 for (i = 0; i < freq->e; i++) 279 div /= 10; 280 if (div <= 0) 281 return -EINVAL; 282 return freq->m / div; 283 } 284 } 285 286 int cfg80211_wext_siwrts(struct net_device *dev, 287 struct iw_request_info *info, 288 struct iw_param *rts, char *extra) 289 { 290 struct wireless_dev *wdev = dev->ieee80211_ptr; 291 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 292 u32 orts = wdev->wiphy->rts_threshold; 293 int err; 294 295 if (rts->disabled || !rts->fixed) 296 wdev->wiphy->rts_threshold = (u32) -1; 297 else if (rts->value < 0) 298 return -EINVAL; 299 else 300 wdev->wiphy->rts_threshold = rts->value; 301 302 err = rdev->ops->set_wiphy_params(wdev->wiphy, 303 WIPHY_PARAM_RTS_THRESHOLD); 304 if (err) 305 wdev->wiphy->rts_threshold = orts; 306 307 return err; 308 } 309 EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts); 310 311 int cfg80211_wext_giwrts(struct net_device *dev, 312 struct iw_request_info *info, 313 struct iw_param *rts, char *extra) 314 { 315 struct wireless_dev *wdev = dev->ieee80211_ptr; 316 317 rts->value = wdev->wiphy->rts_threshold; 318 rts->disabled = rts->value == (u32) -1; 319 rts->fixed = 1; 320 321 return 0; 322 } 323 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts); 324 325 int cfg80211_wext_siwfrag(struct net_device *dev, 326 struct iw_request_info *info, 327 struct iw_param *frag, char *extra) 328 { 329 struct wireless_dev *wdev = dev->ieee80211_ptr; 330 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 331 u32 ofrag = wdev->wiphy->frag_threshold; 332 int err; 333 334 if (frag->disabled || !frag->fixed) 335 wdev->wiphy->frag_threshold = (u32) -1; 336 else if (frag->value < 256) 337 return -EINVAL; 338 else { 339 /* Fragment length must be even, so strip LSB. */ 340 wdev->wiphy->frag_threshold = frag->value & ~0x1; 341 } 342 343 err = rdev->ops->set_wiphy_params(wdev->wiphy, 344 WIPHY_PARAM_FRAG_THRESHOLD); 345 if (err) 346 wdev->wiphy->frag_threshold = ofrag; 347 348 return err; 349 } 350 EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag); 351 352 int cfg80211_wext_giwfrag(struct net_device *dev, 353 struct iw_request_info *info, 354 struct iw_param *frag, char *extra) 355 { 356 struct wireless_dev *wdev = dev->ieee80211_ptr; 357 358 frag->value = wdev->wiphy->frag_threshold; 359 frag->disabled = frag->value == (u32) -1; 360 frag->fixed = 1; 361 362 return 0; 363 } 364 EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); 365 366 int cfg80211_wext_siwretry(struct net_device *dev, 367 struct iw_request_info *info, 368 struct iw_param *retry, char *extra) 369 { 370 struct wireless_dev *wdev = dev->ieee80211_ptr; 371 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 372 u32 changed = 0; 373 u8 olong = wdev->wiphy->retry_long; 374 u8 oshort = wdev->wiphy->retry_short; 375 int err; 376 377 if (retry->disabled || 378 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) 379 return -EINVAL; 380 381 if (retry->flags & IW_RETRY_LONG) { 382 wdev->wiphy->retry_long = retry->value; 383 changed |= WIPHY_PARAM_RETRY_LONG; 384 } else if (retry->flags & IW_RETRY_SHORT) { 385 wdev->wiphy->retry_short = retry->value; 386 changed |= WIPHY_PARAM_RETRY_SHORT; 387 } else { 388 wdev->wiphy->retry_short = retry->value; 389 wdev->wiphy->retry_long = retry->value; 390 changed |= WIPHY_PARAM_RETRY_LONG; 391 changed |= WIPHY_PARAM_RETRY_SHORT; 392 } 393 394 if (!changed) 395 return 0; 396 397 err = rdev->ops->set_wiphy_params(wdev->wiphy, changed); 398 if (err) { 399 wdev->wiphy->retry_short = oshort; 400 wdev->wiphy->retry_long = olong; 401 } 402 403 return err; 404 } 405 EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry); 406 407 int cfg80211_wext_giwretry(struct net_device *dev, 408 struct iw_request_info *info, 409 struct iw_param *retry, char *extra) 410 { 411 struct wireless_dev *wdev = dev->ieee80211_ptr; 412 413 retry->disabled = 0; 414 415 if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) { 416 /* 417 * First return short value, iwconfig will ask long value 418 * later if needed 419 */ 420 retry->flags |= IW_RETRY_LIMIT; 421 retry->value = wdev->wiphy->retry_short; 422 if (wdev->wiphy->retry_long != wdev->wiphy->retry_short) 423 retry->flags |= IW_RETRY_LONG; 424 425 return 0; 426 } 427 428 if (retry->flags & IW_RETRY_LONG) { 429 retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; 430 retry->value = wdev->wiphy->retry_long; 431 } 432 433 return 0; 434 } 435 EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); 436 437 static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 438 struct net_device *dev, bool pairwise, 439 const u8 *addr, bool remove, bool tx_key, 440 int idx, struct key_params *params) 441 { 442 struct wireless_dev *wdev = dev->ieee80211_ptr; 443 int err, i; 444 bool rejoin = false; 445 446 if (pairwise && !addr) 447 return -EINVAL; 448 449 if (!wdev->wext.keys) { 450 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), 451 GFP_KERNEL); 452 if (!wdev->wext.keys) 453 return -ENOMEM; 454 for (i = 0; i < 6; i++) 455 wdev->wext.keys->params[i].key = 456 wdev->wext.keys->data[i]; 457 } 458 459 if (wdev->iftype != NL80211_IFTYPE_ADHOC && 460 wdev->iftype != NL80211_IFTYPE_STATION) 461 return -EOPNOTSUPP; 462 463 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { 464 if (!wdev->current_bss) 465 return -ENOLINK; 466 467 if (!rdev->ops->set_default_mgmt_key) 468 return -EOPNOTSUPP; 469 470 if (idx < 4 || idx > 5) 471 return -EINVAL; 472 } else if (idx < 0 || idx > 3) 473 return -EINVAL; 474 475 if (remove) { 476 err = 0; 477 if (wdev->current_bss) { 478 /* 479 * If removing the current TX key, we will need to 480 * join a new IBSS without the privacy bit clear. 481 */ 482 if (idx == wdev->wext.default_key && 483 wdev->iftype == NL80211_IFTYPE_ADHOC) { 484 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 485 rejoin = true; 486 } 487 488 if (!pairwise && addr && 489 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) 490 err = -ENOENT; 491 else 492 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, 493 pairwise, addr); 494 } 495 wdev->wext.connect.privacy = false; 496 /* 497 * Applications using wireless extensions expect to be 498 * able to delete keys that don't exist, so allow that. 499 */ 500 if (err == -ENOENT) 501 err = 0; 502 if (!err) { 503 if (!addr) { 504 wdev->wext.keys->params[idx].key_len = 0; 505 wdev->wext.keys->params[idx].cipher = 0; 506 } 507 if (idx == wdev->wext.default_key) 508 wdev->wext.default_key = -1; 509 else if (idx == wdev->wext.default_mgmt_key) 510 wdev->wext.default_mgmt_key = -1; 511 } 512 513 if (!err && rejoin) 514 err = cfg80211_ibss_wext_join(rdev, wdev); 515 516 return err; 517 } 518 519 if (addr) 520 tx_key = false; 521 522 if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr)) 523 return -EINVAL; 524 525 err = 0; 526 if (wdev->current_bss) 527 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, 528 pairwise, addr, params); 529 if (err) 530 return err; 531 532 if (!addr) { 533 wdev->wext.keys->params[idx] = *params; 534 memcpy(wdev->wext.keys->data[idx], 535 params->key, params->key_len); 536 wdev->wext.keys->params[idx].key = 537 wdev->wext.keys->data[idx]; 538 } 539 540 if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || 541 params->cipher == WLAN_CIPHER_SUITE_WEP104) && 542 (tx_key || (!addr && wdev->wext.default_key == -1))) { 543 if (wdev->current_bss) { 544 /* 545 * If we are getting a new TX key from not having 546 * had one before we need to join a new IBSS with 547 * the privacy bit set. 548 */ 549 if (wdev->iftype == NL80211_IFTYPE_ADHOC && 550 wdev->wext.default_key == -1) { 551 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 552 rejoin = true; 553 } 554 err = rdev->ops->set_default_key(&rdev->wiphy, dev, 555 idx, true, true); 556 } 557 if (!err) { 558 wdev->wext.default_key = idx; 559 if (rejoin) 560 err = cfg80211_ibss_wext_join(rdev, wdev); 561 } 562 return err; 563 } 564 565 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && 566 (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { 567 if (wdev->current_bss) 568 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, 569 dev, idx); 570 if (!err) 571 wdev->wext.default_mgmt_key = idx; 572 return err; 573 } 574 575 return 0; 576 } 577 578 static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 579 struct net_device *dev, bool pairwise, 580 const u8 *addr, bool remove, bool tx_key, 581 int idx, struct key_params *params) 582 { 583 int err; 584 585 /* devlist mutex needed for possible IBSS re-join */ 586 mutex_lock(&rdev->devlist_mtx); 587 wdev_lock(dev->ieee80211_ptr); 588 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr, 589 remove, tx_key, idx, params); 590 wdev_unlock(dev->ieee80211_ptr); 591 mutex_unlock(&rdev->devlist_mtx); 592 593 return err; 594 } 595 596 int cfg80211_wext_siwencode(struct net_device *dev, 597 struct iw_request_info *info, 598 struct iw_point *erq, char *keybuf) 599 { 600 struct wireless_dev *wdev = dev->ieee80211_ptr; 601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 602 int idx, err; 603 bool remove = false; 604 struct key_params params; 605 606 if (wdev->iftype != NL80211_IFTYPE_STATION && 607 wdev->iftype != NL80211_IFTYPE_ADHOC) 608 return -EOPNOTSUPP; 609 610 /* no use -- only MFP (set_default_mgmt_key) is optional */ 611 if (!rdev->ops->del_key || 612 !rdev->ops->add_key || 613 !rdev->ops->set_default_key) 614 return -EOPNOTSUPP; 615 616 idx = erq->flags & IW_ENCODE_INDEX; 617 if (idx == 0) { 618 idx = wdev->wext.default_key; 619 if (idx < 0) 620 idx = 0; 621 } else if (idx < 1 || idx > 4) 622 return -EINVAL; 623 else 624 idx--; 625 626 if (erq->flags & IW_ENCODE_DISABLED) 627 remove = true; 628 else if (erq->length == 0) { 629 /* No key data - just set the default TX key index */ 630 err = 0; 631 wdev_lock(wdev); 632 if (wdev->current_bss) 633 err = rdev->ops->set_default_key(&rdev->wiphy, dev, 634 idx, true, true); 635 if (!err) 636 wdev->wext.default_key = idx; 637 wdev_unlock(wdev); 638 return err; 639 } 640 641 memset(¶ms, 0, sizeof(params)); 642 params.key = keybuf; 643 params.key_len = erq->length; 644 if (erq->length == 5) 645 params.cipher = WLAN_CIPHER_SUITE_WEP40; 646 else if (erq->length == 13) 647 params.cipher = WLAN_CIPHER_SUITE_WEP104; 648 else if (!remove) 649 return -EINVAL; 650 651 return cfg80211_set_encryption(rdev, dev, false, NULL, remove, 652 wdev->wext.default_key == -1, 653 idx, ¶ms); 654 } 655 EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode); 656 657 int cfg80211_wext_siwencodeext(struct net_device *dev, 658 struct iw_request_info *info, 659 struct iw_point *erq, char *extra) 660 { 661 struct wireless_dev *wdev = dev->ieee80211_ptr; 662 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 663 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; 664 const u8 *addr; 665 int idx; 666 bool remove = false; 667 struct key_params params; 668 u32 cipher; 669 670 if (wdev->iftype != NL80211_IFTYPE_STATION && 671 wdev->iftype != NL80211_IFTYPE_ADHOC) 672 return -EOPNOTSUPP; 673 674 /* no use -- only MFP (set_default_mgmt_key) is optional */ 675 if (!rdev->ops->del_key || 676 !rdev->ops->add_key || 677 !rdev->ops->set_default_key) 678 return -EOPNOTSUPP; 679 680 switch (ext->alg) { 681 case IW_ENCODE_ALG_NONE: 682 remove = true; 683 cipher = 0; 684 break; 685 case IW_ENCODE_ALG_WEP: 686 if (ext->key_len == 5) 687 cipher = WLAN_CIPHER_SUITE_WEP40; 688 else if (ext->key_len == 13) 689 cipher = WLAN_CIPHER_SUITE_WEP104; 690 else 691 return -EINVAL; 692 break; 693 case IW_ENCODE_ALG_TKIP: 694 cipher = WLAN_CIPHER_SUITE_TKIP; 695 break; 696 case IW_ENCODE_ALG_CCMP: 697 cipher = WLAN_CIPHER_SUITE_CCMP; 698 break; 699 case IW_ENCODE_ALG_AES_CMAC: 700 cipher = WLAN_CIPHER_SUITE_AES_CMAC; 701 break; 702 default: 703 return -EOPNOTSUPP; 704 } 705 706 if (erq->flags & IW_ENCODE_DISABLED) 707 remove = true; 708 709 idx = erq->flags & IW_ENCODE_INDEX; 710 if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) { 711 if (idx < 4 || idx > 5) { 712 idx = wdev->wext.default_mgmt_key; 713 if (idx < 0) 714 return -EINVAL; 715 } else 716 idx--; 717 } else { 718 if (idx < 1 || idx > 4) { 719 idx = wdev->wext.default_key; 720 if (idx < 0) 721 return -EINVAL; 722 } else 723 idx--; 724 } 725 726 addr = ext->addr.sa_data; 727 if (is_broadcast_ether_addr(addr)) 728 addr = NULL; 729 730 memset(¶ms, 0, sizeof(params)); 731 params.key = ext->key; 732 params.key_len = ext->key_len; 733 params.cipher = cipher; 734 735 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { 736 params.seq = ext->rx_seq; 737 params.seq_len = 6; 738 } 739 740 return cfg80211_set_encryption( 741 rdev, dev, 742 !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY), 743 addr, remove, 744 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 745 idx, ¶ms); 746 } 747 EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext); 748 749 int cfg80211_wext_giwencode(struct net_device *dev, 750 struct iw_request_info *info, 751 struct iw_point *erq, char *keybuf) 752 { 753 struct wireless_dev *wdev = dev->ieee80211_ptr; 754 int idx; 755 756 if (wdev->iftype != NL80211_IFTYPE_STATION && 757 wdev->iftype != NL80211_IFTYPE_ADHOC) 758 return -EOPNOTSUPP; 759 760 idx = erq->flags & IW_ENCODE_INDEX; 761 if (idx == 0) { 762 idx = wdev->wext.default_key; 763 if (idx < 0) 764 idx = 0; 765 } else if (idx < 1 || idx > 4) 766 return -EINVAL; 767 else 768 idx--; 769 770 erq->flags = idx + 1; 771 772 if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) { 773 erq->flags |= IW_ENCODE_DISABLED; 774 erq->length = 0; 775 return 0; 776 } 777 778 erq->length = min_t(size_t, erq->length, 779 wdev->wext.keys->params[idx].key_len); 780 memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length); 781 erq->flags |= IW_ENCODE_ENABLED; 782 783 return 0; 784 } 785 EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); 786 787 int cfg80211_wext_siwfreq(struct net_device *dev, 788 struct iw_request_info *info, 789 struct iw_freq *wextfreq, char *extra) 790 { 791 struct wireless_dev *wdev = dev->ieee80211_ptr; 792 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 793 int freq, err; 794 795 switch (wdev->iftype) { 796 case NL80211_IFTYPE_STATION: 797 return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra); 798 case NL80211_IFTYPE_ADHOC: 799 return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); 800 case NL80211_IFTYPE_MONITOR: 801 case NL80211_IFTYPE_WDS: 802 case NL80211_IFTYPE_MESH_POINT: 803 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); 804 if (freq < 0) 805 return freq; 806 if (freq == 0) 807 return -EINVAL; 808 mutex_lock(&rdev->devlist_mtx); 809 wdev_lock(wdev); 810 err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT); 811 wdev_unlock(wdev); 812 mutex_unlock(&rdev->devlist_mtx); 813 return err; 814 default: 815 return -EOPNOTSUPP; 816 } 817 } 818 EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); 819 820 int cfg80211_wext_giwfreq(struct net_device *dev, 821 struct iw_request_info *info, 822 struct iw_freq *freq, char *extra) 823 { 824 struct wireless_dev *wdev = dev->ieee80211_ptr; 825 826 switch (wdev->iftype) { 827 case NL80211_IFTYPE_STATION: 828 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); 829 case NL80211_IFTYPE_ADHOC: 830 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 831 default: 832 if (!wdev->channel) 833 return -EINVAL; 834 freq->m = wdev->channel->center_freq; 835 freq->e = 6; 836 return 0; 837 } 838 } 839 EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq); 840 841 int cfg80211_wext_siwtxpower(struct net_device *dev, 842 struct iw_request_info *info, 843 union iwreq_data *data, char *extra) 844 { 845 struct wireless_dev *wdev = dev->ieee80211_ptr; 846 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 847 enum nl80211_tx_power_setting type; 848 int dbm = 0; 849 850 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 851 return -EINVAL; 852 if (data->txpower.flags & IW_TXPOW_RANGE) 853 return -EINVAL; 854 855 if (!rdev->ops->set_tx_power) 856 return -EOPNOTSUPP; 857 858 /* only change when not disabling */ 859 if (!data->txpower.disabled) { 860 rfkill_set_sw_state(rdev->rfkill, false); 861 862 if (data->txpower.fixed) { 863 /* 864 * wext doesn't support negative values, see 865 * below where it's for automatic 866 */ 867 if (data->txpower.value < 0) 868 return -EINVAL; 869 dbm = data->txpower.value; 870 type = NL80211_TX_POWER_FIXED; 871 /* TODO: do regulatory check! */ 872 } else { 873 /* 874 * Automatic power level setting, max being the value 875 * passed in from userland. 876 */ 877 if (data->txpower.value < 0) { 878 type = NL80211_TX_POWER_AUTOMATIC; 879 } else { 880 dbm = data->txpower.value; 881 type = NL80211_TX_POWER_LIMITED; 882 } 883 } 884 } else { 885 rfkill_set_sw_state(rdev->rfkill, true); 886 schedule_work(&rdev->rfkill_sync); 887 return 0; 888 } 889 890 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); 891 } 892 EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); 893 894 int cfg80211_wext_giwtxpower(struct net_device *dev, 895 struct iw_request_info *info, 896 union iwreq_data *data, char *extra) 897 { 898 struct wireless_dev *wdev = dev->ieee80211_ptr; 899 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 900 int err, val; 901 902 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 903 return -EINVAL; 904 if (data->txpower.flags & IW_TXPOW_RANGE) 905 return -EINVAL; 906 907 if (!rdev->ops->get_tx_power) 908 return -EOPNOTSUPP; 909 910 err = rdev->ops->get_tx_power(wdev->wiphy, &val); 911 if (err) 912 return err; 913 914 /* well... oh well */ 915 data->txpower.fixed = 1; 916 data->txpower.disabled = rfkill_blocked(rdev->rfkill); 917 data->txpower.value = val; 918 data->txpower.flags = IW_TXPOW_DBM; 919 920 return 0; 921 } 922 EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower); 923 924 static int cfg80211_set_auth_alg(struct wireless_dev *wdev, 925 s32 auth_alg) 926 { 927 int nr_alg = 0; 928 929 if (!auth_alg) 930 return -EINVAL; 931 932 if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM | 933 IW_AUTH_ALG_SHARED_KEY | 934 IW_AUTH_ALG_LEAP)) 935 return -EINVAL; 936 937 if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) { 938 nr_alg++; 939 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; 940 } 941 942 if (auth_alg & IW_AUTH_ALG_SHARED_KEY) { 943 nr_alg++; 944 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY; 945 } 946 947 if (auth_alg & IW_AUTH_ALG_LEAP) { 948 nr_alg++; 949 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP; 950 } 951 952 if (nr_alg > 1) 953 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 954 955 return 0; 956 } 957 958 static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions) 959 { 960 if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA | 961 IW_AUTH_WPA_VERSION_WPA2| 962 IW_AUTH_WPA_VERSION_DISABLED)) 963 return -EINVAL; 964 965 if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) && 966 (wpa_versions & (IW_AUTH_WPA_VERSION_WPA| 967 IW_AUTH_WPA_VERSION_WPA2))) 968 return -EINVAL; 969 970 if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) 971 wdev->wext.connect.crypto.wpa_versions &= 972 ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2); 973 974 if (wpa_versions & IW_AUTH_WPA_VERSION_WPA) 975 wdev->wext.connect.crypto.wpa_versions |= 976 NL80211_WPA_VERSION_1; 977 978 if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2) 979 wdev->wext.connect.crypto.wpa_versions |= 980 NL80211_WPA_VERSION_2; 981 982 return 0; 983 } 984 985 static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher) 986 { 987 if (cipher & IW_AUTH_CIPHER_WEP40) 988 wdev->wext.connect.crypto.cipher_group = 989 WLAN_CIPHER_SUITE_WEP40; 990 else if (cipher & IW_AUTH_CIPHER_WEP104) 991 wdev->wext.connect.crypto.cipher_group = 992 WLAN_CIPHER_SUITE_WEP104; 993 else if (cipher & IW_AUTH_CIPHER_TKIP) 994 wdev->wext.connect.crypto.cipher_group = 995 WLAN_CIPHER_SUITE_TKIP; 996 else if (cipher & IW_AUTH_CIPHER_CCMP) 997 wdev->wext.connect.crypto.cipher_group = 998 WLAN_CIPHER_SUITE_CCMP; 999 else if (cipher & IW_AUTH_CIPHER_AES_CMAC) 1000 wdev->wext.connect.crypto.cipher_group = 1001 WLAN_CIPHER_SUITE_AES_CMAC; 1002 else if (cipher & IW_AUTH_CIPHER_NONE) 1003 wdev->wext.connect.crypto.cipher_group = 0; 1004 else 1005 return -EINVAL; 1006 1007 return 0; 1008 } 1009 1010 static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher) 1011 { 1012 int nr_ciphers = 0; 1013 u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise; 1014 1015 if (cipher & IW_AUTH_CIPHER_WEP40) { 1016 ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40; 1017 nr_ciphers++; 1018 } 1019 1020 if (cipher & IW_AUTH_CIPHER_WEP104) { 1021 ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104; 1022 nr_ciphers++; 1023 } 1024 1025 if (cipher & IW_AUTH_CIPHER_TKIP) { 1026 ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP; 1027 nr_ciphers++; 1028 } 1029 1030 if (cipher & IW_AUTH_CIPHER_CCMP) { 1031 ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP; 1032 nr_ciphers++; 1033 } 1034 1035 if (cipher & IW_AUTH_CIPHER_AES_CMAC) { 1036 ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC; 1037 nr_ciphers++; 1038 } 1039 1040 BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5); 1041 1042 wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers; 1043 1044 return 0; 1045 } 1046 1047 1048 static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt) 1049 { 1050 int nr_akm_suites = 0; 1051 1052 if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X | 1053 IW_AUTH_KEY_MGMT_PSK)) 1054 return -EINVAL; 1055 1056 if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) { 1057 wdev->wext.connect.crypto.akm_suites[nr_akm_suites] = 1058 WLAN_AKM_SUITE_8021X; 1059 nr_akm_suites++; 1060 } 1061 1062 if (key_mgt & IW_AUTH_KEY_MGMT_PSK) { 1063 wdev->wext.connect.crypto.akm_suites[nr_akm_suites] = 1064 WLAN_AKM_SUITE_PSK; 1065 nr_akm_suites++; 1066 } 1067 1068 wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites; 1069 1070 return 0; 1071 } 1072 1073 int cfg80211_wext_siwauth(struct net_device *dev, 1074 struct iw_request_info *info, 1075 struct iw_param *data, char *extra) 1076 { 1077 struct wireless_dev *wdev = dev->ieee80211_ptr; 1078 1079 if (wdev->iftype != NL80211_IFTYPE_STATION) 1080 return -EOPNOTSUPP; 1081 1082 switch (data->flags & IW_AUTH_INDEX) { 1083 case IW_AUTH_PRIVACY_INVOKED: 1084 wdev->wext.connect.privacy = data->value; 1085 return 0; 1086 case IW_AUTH_WPA_VERSION: 1087 return cfg80211_set_wpa_version(wdev, data->value); 1088 case IW_AUTH_CIPHER_GROUP: 1089 return cfg80211_set_cipher_group(wdev, data->value); 1090 case IW_AUTH_KEY_MGMT: 1091 return cfg80211_set_key_mgt(wdev, data->value); 1092 case IW_AUTH_CIPHER_PAIRWISE: 1093 return cfg80211_set_cipher_pairwise(wdev, data->value); 1094 case IW_AUTH_80211_AUTH_ALG: 1095 return cfg80211_set_auth_alg(wdev, data->value); 1096 case IW_AUTH_WPA_ENABLED: 1097 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1098 case IW_AUTH_DROP_UNENCRYPTED: 1099 case IW_AUTH_MFP: 1100 return 0; 1101 default: 1102 return -EOPNOTSUPP; 1103 } 1104 } 1105 EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth); 1106 1107 int cfg80211_wext_giwauth(struct net_device *dev, 1108 struct iw_request_info *info, 1109 struct iw_param *data, char *extra) 1110 { 1111 /* XXX: what do we need? */ 1112 1113 return -EOPNOTSUPP; 1114 } 1115 EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth); 1116 1117 int cfg80211_wext_siwpower(struct net_device *dev, 1118 struct iw_request_info *info, 1119 struct iw_param *wrq, char *extra) 1120 { 1121 struct wireless_dev *wdev = dev->ieee80211_ptr; 1122 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1123 bool ps = wdev->ps; 1124 int timeout = wdev->ps_timeout; 1125 int err; 1126 1127 if (wdev->iftype != NL80211_IFTYPE_STATION) 1128 return -EINVAL; 1129 1130 if (!rdev->ops->set_power_mgmt) 1131 return -EOPNOTSUPP; 1132 1133 if (wrq->disabled) { 1134 ps = false; 1135 } else { 1136 switch (wrq->flags & IW_POWER_MODE) { 1137 case IW_POWER_ON: /* If not specified */ 1138 case IW_POWER_MODE: /* If set all mask */ 1139 case IW_POWER_ALL_R: /* If explicitely state all */ 1140 ps = true; 1141 break; 1142 default: /* Otherwise we ignore */ 1143 return -EINVAL; 1144 } 1145 1146 if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT)) 1147 return -EINVAL; 1148 1149 if (wrq->flags & IW_POWER_TIMEOUT) 1150 timeout = wrq->value / 1000; 1151 } 1152 1153 err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout); 1154 if (err) 1155 return err; 1156 1157 wdev->ps = ps; 1158 wdev->ps_timeout = timeout; 1159 1160 return 0; 1161 1162 } 1163 EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower); 1164 1165 int cfg80211_wext_giwpower(struct net_device *dev, 1166 struct iw_request_info *info, 1167 struct iw_param *wrq, char *extra) 1168 { 1169 struct wireless_dev *wdev = dev->ieee80211_ptr; 1170 1171 wrq->disabled = !wdev->ps; 1172 1173 return 0; 1174 } 1175 EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); 1176 1177 static int cfg80211_wds_wext_siwap(struct net_device *dev, 1178 struct iw_request_info *info, 1179 struct sockaddr *addr, char *extra) 1180 { 1181 struct wireless_dev *wdev = dev->ieee80211_ptr; 1182 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1183 int err; 1184 1185 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) 1186 return -EINVAL; 1187 1188 if (addr->sa_family != ARPHRD_ETHER) 1189 return -EINVAL; 1190 1191 if (netif_running(dev)) 1192 return -EBUSY; 1193 1194 if (!rdev->ops->set_wds_peer) 1195 return -EOPNOTSUPP; 1196 1197 err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data); 1198 if (err) 1199 return err; 1200 1201 memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN); 1202 1203 return 0; 1204 } 1205 1206 static int cfg80211_wds_wext_giwap(struct net_device *dev, 1207 struct iw_request_info *info, 1208 struct sockaddr *addr, char *extra) 1209 { 1210 struct wireless_dev *wdev = dev->ieee80211_ptr; 1211 1212 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) 1213 return -EINVAL; 1214 1215 addr->sa_family = ARPHRD_ETHER; 1216 memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN); 1217 1218 return 0; 1219 } 1220 1221 int cfg80211_wext_siwrate(struct net_device *dev, 1222 struct iw_request_info *info, 1223 struct iw_param *rate, char *extra) 1224 { 1225 struct wireless_dev *wdev = dev->ieee80211_ptr; 1226 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1227 struct cfg80211_bitrate_mask mask; 1228 u32 fixed, maxrate; 1229 struct ieee80211_supported_band *sband; 1230 int band, ridx; 1231 bool match = false; 1232 1233 if (!rdev->ops->set_bitrate_mask) 1234 return -EOPNOTSUPP; 1235 1236 memset(&mask, 0, sizeof(mask)); 1237 fixed = 0; 1238 maxrate = (u32)-1; 1239 1240 if (rate->value < 0) { 1241 /* nothing */ 1242 } else if (rate->fixed) { 1243 fixed = rate->value / 100000; 1244 } else { 1245 maxrate = rate->value / 100000; 1246 } 1247 1248 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1249 sband = wdev->wiphy->bands[band]; 1250 if (sband == NULL) 1251 continue; 1252 for (ridx = 0; ridx < sband->n_bitrates; ridx++) { 1253 struct ieee80211_rate *srate = &sband->bitrates[ridx]; 1254 if (fixed == srate->bitrate) { 1255 mask.control[band].legacy = 1 << ridx; 1256 match = true; 1257 break; 1258 } 1259 if (srate->bitrate <= maxrate) { 1260 mask.control[band].legacy |= 1 << ridx; 1261 match = true; 1262 } 1263 } 1264 } 1265 1266 if (!match) 1267 return -EINVAL; 1268 1269 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); 1270 } 1271 EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate); 1272 1273 int cfg80211_wext_giwrate(struct net_device *dev, 1274 struct iw_request_info *info, 1275 struct iw_param *rate, char *extra) 1276 { 1277 struct wireless_dev *wdev = dev->ieee80211_ptr; 1278 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1279 /* we are under RTNL - globally locked - so can use a static struct */ 1280 static struct station_info sinfo; 1281 u8 addr[ETH_ALEN]; 1282 int err; 1283 1284 if (wdev->iftype != NL80211_IFTYPE_STATION) 1285 return -EOPNOTSUPP; 1286 1287 if (!rdev->ops->get_station) 1288 return -EOPNOTSUPP; 1289 1290 err = 0; 1291 wdev_lock(wdev); 1292 if (wdev->current_bss) 1293 memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN); 1294 else 1295 err = -EOPNOTSUPP; 1296 wdev_unlock(wdev); 1297 if (err) 1298 return err; 1299 1300 err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo); 1301 if (err) 1302 return err; 1303 1304 if (!(sinfo.filled & STATION_INFO_TX_BITRATE)) 1305 return -EOPNOTSUPP; 1306 1307 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate); 1308 1309 return 0; 1310 } 1311 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate); 1312 1313 /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 1314 struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) 1315 { 1316 struct wireless_dev *wdev = dev->ieee80211_ptr; 1317 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1318 /* we are under RTNL - globally locked - so can use static structs */ 1319 static struct iw_statistics wstats; 1320 static struct station_info sinfo; 1321 u8 bssid[ETH_ALEN]; 1322 1323 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) 1324 return NULL; 1325 1326 if (!rdev->ops->get_station) 1327 return NULL; 1328 1329 /* Grab BSSID of current BSS, if any */ 1330 wdev_lock(wdev); 1331 if (!wdev->current_bss) { 1332 wdev_unlock(wdev); 1333 return NULL; 1334 } 1335 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 1336 wdev_unlock(wdev); 1337 1338 if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo)) 1339 return NULL; 1340 1341 memset(&wstats, 0, sizeof(wstats)); 1342 1343 switch (rdev->wiphy.signal_type) { 1344 case CFG80211_SIGNAL_TYPE_MBM: 1345 if (sinfo.filled & STATION_INFO_SIGNAL) { 1346 int sig = sinfo.signal; 1347 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; 1348 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; 1349 wstats.qual.updated |= IW_QUAL_DBM; 1350 wstats.qual.level = sig; 1351 if (sig < -110) 1352 sig = -110; 1353 else if (sig > -40) 1354 sig = -40; 1355 wstats.qual.qual = sig + 110; 1356 break; 1357 } 1358 case CFG80211_SIGNAL_TYPE_UNSPEC: 1359 if (sinfo.filled & STATION_INFO_SIGNAL) { 1360 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; 1361 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; 1362 wstats.qual.level = sinfo.signal; 1363 wstats.qual.qual = sinfo.signal; 1364 break; 1365 } 1366 default: 1367 wstats.qual.updated |= IW_QUAL_LEVEL_INVALID; 1368 wstats.qual.updated |= IW_QUAL_QUAL_INVALID; 1369 } 1370 1371 wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1372 if (sinfo.filled & STATION_INFO_RX_DROP_MISC) 1373 wstats.discard.misc = sinfo.rx_dropped_misc; 1374 if (sinfo.filled & STATION_INFO_TX_FAILED) 1375 wstats.discard.retries = sinfo.tx_failed; 1376 1377 return &wstats; 1378 } 1379 EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); 1380 1381 int cfg80211_wext_siwap(struct net_device *dev, 1382 struct iw_request_info *info, 1383 struct sockaddr *ap_addr, char *extra) 1384 { 1385 struct wireless_dev *wdev = dev->ieee80211_ptr; 1386 1387 switch (wdev->iftype) { 1388 case NL80211_IFTYPE_ADHOC: 1389 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); 1390 case NL80211_IFTYPE_STATION: 1391 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); 1392 case NL80211_IFTYPE_WDS: 1393 return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra); 1394 default: 1395 return -EOPNOTSUPP; 1396 } 1397 } 1398 EXPORT_SYMBOL_GPL(cfg80211_wext_siwap); 1399 1400 int cfg80211_wext_giwap(struct net_device *dev, 1401 struct iw_request_info *info, 1402 struct sockaddr *ap_addr, char *extra) 1403 { 1404 struct wireless_dev *wdev = dev->ieee80211_ptr; 1405 1406 switch (wdev->iftype) { 1407 case NL80211_IFTYPE_ADHOC: 1408 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); 1409 case NL80211_IFTYPE_STATION: 1410 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); 1411 case NL80211_IFTYPE_WDS: 1412 return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra); 1413 default: 1414 return -EOPNOTSUPP; 1415 } 1416 } 1417 EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); 1418 1419 int cfg80211_wext_siwessid(struct net_device *dev, 1420 struct iw_request_info *info, 1421 struct iw_point *data, char *ssid) 1422 { 1423 struct wireless_dev *wdev = dev->ieee80211_ptr; 1424 1425 switch (wdev->iftype) { 1426 case NL80211_IFTYPE_ADHOC: 1427 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); 1428 case NL80211_IFTYPE_STATION: 1429 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); 1430 default: 1431 return -EOPNOTSUPP; 1432 } 1433 } 1434 EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid); 1435 1436 int cfg80211_wext_giwessid(struct net_device *dev, 1437 struct iw_request_info *info, 1438 struct iw_point *data, char *ssid) 1439 { 1440 struct wireless_dev *wdev = dev->ieee80211_ptr; 1441 1442 data->flags = 0; 1443 data->length = 0; 1444 1445 switch (wdev->iftype) { 1446 case NL80211_IFTYPE_ADHOC: 1447 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); 1448 case NL80211_IFTYPE_STATION: 1449 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); 1450 default: 1451 return -EOPNOTSUPP; 1452 } 1453 } 1454 EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); 1455 1456 int cfg80211_wext_siwpmksa(struct net_device *dev, 1457 struct iw_request_info *info, 1458 struct iw_point *data, char *extra) 1459 { 1460 struct wireless_dev *wdev = dev->ieee80211_ptr; 1461 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1462 struct cfg80211_pmksa cfg_pmksa; 1463 struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; 1464 1465 memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa)); 1466 1467 if (wdev->iftype != NL80211_IFTYPE_STATION) 1468 return -EINVAL; 1469 1470 cfg_pmksa.bssid = pmksa->bssid.sa_data; 1471 cfg_pmksa.pmkid = pmksa->pmkid; 1472 1473 switch (pmksa->cmd) { 1474 case IW_PMKSA_ADD: 1475 if (!rdev->ops->set_pmksa) 1476 return -EOPNOTSUPP; 1477 1478 return rdev->ops->set_pmksa(&rdev->wiphy, dev, &cfg_pmksa); 1479 1480 case IW_PMKSA_REMOVE: 1481 if (!rdev->ops->del_pmksa) 1482 return -EOPNOTSUPP; 1483 1484 return rdev->ops->del_pmksa(&rdev->wiphy, dev, &cfg_pmksa); 1485 1486 case IW_PMKSA_FLUSH: 1487 if (!rdev->ops->flush_pmksa) 1488 return -EOPNOTSUPP; 1489 1490 return rdev->ops->flush_pmksa(&rdev->wiphy, dev); 1491 1492 default: 1493 return -EOPNOTSUPP; 1494 } 1495 } 1496 EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa); 1497 1498 static const iw_handler cfg80211_handlers[] = { 1499 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1500 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq, 1501 [IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq, 1502 [IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode, 1503 [IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode, 1504 [IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) cfg80211_wext_giwrange, 1505 [IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) cfg80211_wext_siwap, 1506 [IW_IOCTL_IDX(SIOCGIWAP)] = (iw_handler) cfg80211_wext_giwap, 1507 [IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme, 1508 [IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan, 1509 [IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan, 1510 [IW_IOCTL_IDX(SIOCSIWESSID)] = (iw_handler) cfg80211_wext_siwessid, 1511 [IW_IOCTL_IDX(SIOCGIWESSID)] = (iw_handler) cfg80211_wext_giwessid, 1512 [IW_IOCTL_IDX(SIOCSIWRATE)] = (iw_handler) cfg80211_wext_siwrate, 1513 [IW_IOCTL_IDX(SIOCGIWRATE)] = (iw_handler) cfg80211_wext_giwrate, 1514 [IW_IOCTL_IDX(SIOCSIWRTS)] = (iw_handler) cfg80211_wext_siwrts, 1515 [IW_IOCTL_IDX(SIOCGIWRTS)] = (iw_handler) cfg80211_wext_giwrts, 1516 [IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag, 1517 [IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag, 1518 [IW_IOCTL_IDX(SIOCSIWTXPOW)] = (iw_handler) cfg80211_wext_siwtxpower, 1519 [IW_IOCTL_IDX(SIOCGIWTXPOW)] = (iw_handler) cfg80211_wext_giwtxpower, 1520 [IW_IOCTL_IDX(SIOCSIWRETRY)] = (iw_handler) cfg80211_wext_siwretry, 1521 [IW_IOCTL_IDX(SIOCGIWRETRY)] = (iw_handler) cfg80211_wext_giwretry, 1522 [IW_IOCTL_IDX(SIOCSIWENCODE)] = (iw_handler) cfg80211_wext_siwencode, 1523 [IW_IOCTL_IDX(SIOCGIWENCODE)] = (iw_handler) cfg80211_wext_giwencode, 1524 [IW_IOCTL_IDX(SIOCSIWPOWER)] = (iw_handler) cfg80211_wext_siwpower, 1525 [IW_IOCTL_IDX(SIOCGIWPOWER)] = (iw_handler) cfg80211_wext_giwpower, 1526 [IW_IOCTL_IDX(SIOCSIWGENIE)] = (iw_handler) cfg80211_wext_siwgenie, 1527 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth, 1528 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth, 1529 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext, 1530 [IW_IOCTL_IDX(SIOCSIWPMKSA)] = (iw_handler) cfg80211_wext_siwpmksa, 1531 }; 1532 1533 const struct iw_handler_def cfg80211_wext_handler = { 1534 .num_standard = ARRAY_SIZE(cfg80211_handlers), 1535 .standard = cfg80211_handlers, 1536 .get_wireless_stats = cfg80211_wireless_stats, 1537 }; 1538