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