1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * This file contains wireless extension handlers. 5 * 6 * This is part of rtl8180 OpenSource driver. 7 * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com> 8 * 9 * Parts of this driver are based on the GPL part 10 * of the official realtek driver. 11 * 12 * Parts of this driver are based on the rtl8180 driver skeleton 13 * from Patric Schenke & Andres Salomon. 14 * 15 * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. 16 * 17 * We want to thank the Authors of those projects and the Ndiswrapper 18 * project Authors. 19 * 20 *****************************************************************************/ 21 22 #include <linux/string.h> 23 #include "r8192U.h" 24 #include "r8192U_hw.h" 25 26 #include "ieee80211/dot11d.h" 27 #include "r8192U_wx.h" 28 29 #define RATE_COUNT 12 30 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, 31 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; 32 33 #ifndef ENETDOWN 34 #define ENETDOWN 1 35 #endif 36 37 static int r8192_wx_get_freq(struct net_device *dev, 38 struct iw_request_info *a, 39 union iwreq_data *wrqu, char *b) 40 { 41 struct r8192_priv *priv = ieee80211_priv(dev); 42 43 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b); 44 } 45 46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 47 union iwreq_data *wrqu, char *b) 48 { 49 struct r8192_priv *priv = ieee80211_priv(dev); 50 51 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b); 52 } 53 54 static int r8192_wx_get_rate(struct net_device *dev, 55 struct iw_request_info *info, 56 union iwreq_data *wrqu, char *extra) 57 { 58 struct r8192_priv *priv = ieee80211_priv(dev); 59 60 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra); 61 } 62 63 static int r8192_wx_set_rate(struct net_device *dev, 64 struct iw_request_info *info, 65 union iwreq_data *wrqu, char *extra) 66 { 67 int ret; 68 struct r8192_priv *priv = ieee80211_priv(dev); 69 70 mutex_lock(&priv->wx_mutex); 71 72 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra); 73 74 mutex_unlock(&priv->wx_mutex); 75 76 return ret; 77 } 78 79 static int r8192_wx_set_rts(struct net_device *dev, 80 struct iw_request_info *info, 81 union iwreq_data *wrqu, char *extra) 82 { 83 int ret; 84 struct r8192_priv *priv = ieee80211_priv(dev); 85 86 mutex_lock(&priv->wx_mutex); 87 88 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra); 89 90 mutex_unlock(&priv->wx_mutex); 91 92 return ret; 93 } 94 95 static int r8192_wx_get_rts(struct net_device *dev, 96 struct iw_request_info *info, 97 union iwreq_data *wrqu, char *extra) 98 { 99 struct r8192_priv *priv = ieee80211_priv(dev); 100 101 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra); 102 } 103 104 static int r8192_wx_set_power(struct net_device *dev, 105 struct iw_request_info *info, 106 union iwreq_data *wrqu, char *extra) 107 { 108 int ret; 109 struct r8192_priv *priv = ieee80211_priv(dev); 110 111 mutex_lock(&priv->wx_mutex); 112 113 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra); 114 115 mutex_unlock(&priv->wx_mutex); 116 117 return ret; 118 } 119 120 static int r8192_wx_get_power(struct net_device *dev, 121 struct iw_request_info *info, 122 union iwreq_data *wrqu, char *extra) 123 { 124 struct r8192_priv *priv = ieee80211_priv(dev); 125 126 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra); 127 } 128 129 static int r8192_wx_force_reset(struct net_device *dev, 130 struct iw_request_info *info, 131 union iwreq_data *wrqu, char *extra) 132 { 133 struct r8192_priv *priv = ieee80211_priv(dev); 134 135 mutex_lock(&priv->wx_mutex); 136 137 netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra); 138 priv->force_reset = *extra; 139 mutex_unlock(&priv->wx_mutex); 140 return 0; 141 142 } 143 144 static int r8192_wx_set_rawtx(struct net_device *dev, 145 struct iw_request_info *info, 146 union iwreq_data *wrqu, char *extra) 147 { 148 struct r8192_priv *priv = ieee80211_priv(dev); 149 int ret; 150 151 mutex_lock(&priv->wx_mutex); 152 153 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); 154 155 mutex_unlock(&priv->wx_mutex); 156 157 return ret; 158 159 } 160 161 static int r8192_wx_set_crcmon(struct net_device *dev, 162 struct iw_request_info *info, 163 union iwreq_data *wrqu, char *extra) 164 { 165 struct r8192_priv *priv = ieee80211_priv(dev); 166 int *parms = (int *)extra; 167 int enable = (parms[0] > 0); 168 169 mutex_lock(&priv->wx_mutex); 170 171 if (enable) 172 priv->crcmon = 1; 173 else 174 priv->crcmon = 0; 175 176 DMESG("bad CRC in monitor mode are %s", 177 priv->crcmon ? "accepted" : "rejected"); 178 179 mutex_unlock(&priv->wx_mutex); 180 181 return 0; 182 } 183 184 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 185 union iwreq_data *wrqu, char *b) 186 { 187 struct r8192_priv *priv = ieee80211_priv(dev); 188 int ret; 189 190 mutex_lock(&priv->wx_mutex); 191 192 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b); 193 194 rtl8192_set_rxconf(dev); 195 196 mutex_unlock(&priv->wx_mutex); 197 return ret; 198 } 199 200 struct iw_range_with_scan_capa { 201 /* Informative stuff (to choose between different interface) */ 202 __u32 throughput; /* To give an idea... */ 203 /* In theory this value should be the maximum benchmarked 204 * TCP/IP throughput, because with most of these devices the 205 * bit rate is meaningless (overhead an co) to estimate how 206 * fast the connection will go and pick the fastest one. 207 * I suggest people to play with Netperf or any benchmark... 208 */ 209 210 /* NWID (or domain id) */ 211 __u32 min_nwid; /* Minimal NWID we are able to set */ 212 __u32 max_nwid; /* Maximal NWID we are able to set */ 213 214 /* Old Frequency (backward compat - moved lower ) */ 215 __u16 old_num_channels; 216 __u8 old_num_frequency; 217 218 /* Scan capabilities */ 219 __u8 scan_capa; 220 }; 221 static int rtl8180_wx_get_range(struct net_device *dev, 222 struct iw_request_info *info, 223 union iwreq_data *wrqu, char *extra) 224 { 225 struct iw_range *range = (struct iw_range *)extra; 226 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range; 227 struct r8192_priv *priv = ieee80211_priv(dev); 228 u16 val; 229 int i; 230 231 wrqu->data.length = sizeof(*range); 232 memset(range, 0, sizeof(*range)); 233 234 /* Let's try to keep this struct in the same order as in 235 * linux/include/wireless.h 236 */ 237 238 /* TODO: See what values we can set, and remove the ones we can't 239 * set, or fill them with some default data. 240 */ 241 242 /* ~5 Mb/s real (802.11b) */ 243 range->throughput = 5 * 1000 * 1000; 244 245 /* TODO: Not used in 802.11b? */ 246 /* range->min_nwid; */ /* Minimal NWID we are able to set */ 247 /* TODO: Not used in 802.11b? */ 248 /* range->max_nwid; */ /* Maximal NWID we are able to set */ 249 250 /* Old Frequency (backward compat - moved lower ) */ 251 /* range->old_num_channels; */ 252 /* range->old_num_frequency; */ 253 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */ 254 if (priv->rf_set_sens != NULL) 255 range->sensitivity = priv->max_sens; /* signal level threshold range */ 256 257 range->max_qual.qual = 100; 258 /* TODO: Find real max RSSI and stick here */ 259 range->max_qual.level = 0; 260 range->max_qual.noise = 0x100 - 98; 261 range->max_qual.updated = 7; /* Updated all three */ 262 263 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 264 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ 265 range->avg_qual.level = 0x100 - 78; 266 range->avg_qual.noise = 0; 267 range->avg_qual.updated = 7; /* Updated all three */ 268 269 range->num_bitrates = RATE_COUNT; 270 271 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) 272 range->bitrate[i] = rtl8180_rates[i]; 273 274 range->min_frag = MIN_FRAG_THRESHOLD; 275 range->max_frag = MAX_FRAG_THRESHOLD; 276 277 range->min_pmp = 0; 278 range->max_pmp = 5000000; 279 range->min_pmt = 0; 280 range->max_pmt = 65535*1000; 281 range->pmp_flags = IW_POWER_PERIOD; 282 range->pmt_flags = IW_POWER_TIMEOUT; 283 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; 284 285 range->we_version_compiled = WIRELESS_EXT; 286 range->we_version_source = 16; 287 288 /* range->retry_capa; */ /* What retry options are supported */ 289 /* range->retry_flags; */ /* How to decode max/min retry limit */ 290 /* range->r_time_flags; */ /* How to decode max/min retry life */ 291 /* range->min_retry; */ /* Minimal number of retries */ 292 /* range->max_retry; */ /* Maximal number of retries */ 293 /* range->min_r_time; */ /* Minimal retry lifetime */ 294 /* range->max_r_time; */ /* Maximal retry lifetime */ 295 296 for (i = 0, val = 0; i < 14; i++) { 297 298 /* Include only legal frequencies for some countries */ 299 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { 300 range->freq[val].i = i + 1; 301 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; 302 range->freq[val].e = 1; 303 val++; 304 } else { 305 /* FIXME: do we need to set anything for channels */ 306 /* we don't use ? */ 307 } 308 309 if (val == IW_MAX_FREQUENCIES) 310 break; 311 } 312 range->num_frequency = val; 313 range->num_channels = val; 314 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| 315 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; 316 tmp->scan_capa = 0x01; 317 return 0; 318 } 319 320 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 321 union iwreq_data *wrqu, char *b) 322 { 323 struct r8192_priv *priv = ieee80211_priv(dev); 324 struct ieee80211_device *ieee = priv->ieee80211; 325 int ret = 0; 326 327 if (!priv->up) 328 return -ENETDOWN; 329 330 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic) 331 return -EAGAIN; 332 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 333 struct iw_scan_req *req = (struct iw_scan_req *)b; 334 335 if (req->essid_len) { 336 ieee->current_network.ssid_len = req->essid_len; 337 memcpy(ieee->current_network.ssid, req->essid, req->essid_len); 338 } 339 } 340 341 mutex_lock(&priv->wx_mutex); 342 if (priv->ieee80211->state != IEEE80211_LINKED) { 343 priv->ieee80211->scanning = 0; 344 ieee80211_softmac_scan_syncro(priv->ieee80211); 345 ret = 0; 346 } else { 347 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b); 348 } 349 mutex_unlock(&priv->wx_mutex); 350 return ret; 351 } 352 353 354 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 355 union iwreq_data *wrqu, char *b) 356 { 357 358 int ret; 359 struct r8192_priv *priv = ieee80211_priv(dev); 360 361 if (!priv->up) 362 return -ENETDOWN; 363 364 mutex_lock(&priv->wx_mutex); 365 366 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b); 367 368 mutex_unlock(&priv->wx_mutex); 369 370 return ret; 371 } 372 373 static int r8192_wx_set_essid(struct net_device *dev, 374 struct iw_request_info *a, 375 union iwreq_data *wrqu, char *b) 376 { 377 struct r8192_priv *priv = ieee80211_priv(dev); 378 int ret; 379 380 mutex_lock(&priv->wx_mutex); 381 382 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b); 383 384 mutex_unlock(&priv->wx_mutex); 385 386 return ret; 387 } 388 389 static int r8192_wx_get_essid(struct net_device *dev, 390 struct iw_request_info *a, 391 union iwreq_data *wrqu, char *b) 392 { 393 int ret; 394 struct r8192_priv *priv = ieee80211_priv(dev); 395 396 mutex_lock(&priv->wx_mutex); 397 398 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); 399 400 mutex_unlock(&priv->wx_mutex); 401 402 return ret; 403 } 404 405 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, 406 union iwreq_data *wrqu, char *b) 407 { 408 int ret; 409 struct r8192_priv *priv = ieee80211_priv(dev); 410 411 mutex_lock(&priv->wx_mutex); 412 413 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); 414 415 mutex_unlock(&priv->wx_mutex); 416 return ret; 417 } 418 419 static int r8192_wx_get_name(struct net_device *dev, 420 struct iw_request_info *info, 421 union iwreq_data *wrqu, char *extra) 422 { 423 struct r8192_priv *priv = ieee80211_priv(dev); 424 425 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); 426 } 427 428 static int r8192_wx_set_frag(struct net_device *dev, 429 struct iw_request_info *info, 430 union iwreq_data *wrqu, char *extra) 431 { 432 struct r8192_priv *priv = ieee80211_priv(dev); 433 434 if (wrqu->frag.disabled) 435 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; 436 else { 437 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 438 wrqu->frag.value > MAX_FRAG_THRESHOLD) 439 return -EINVAL; 440 441 priv->ieee80211->fts = wrqu->frag.value & ~0x1; 442 } 443 444 return 0; 445 } 446 447 448 static int r8192_wx_get_frag(struct net_device *dev, 449 struct iw_request_info *info, 450 union iwreq_data *wrqu, char *extra) 451 { 452 struct r8192_priv *priv = ieee80211_priv(dev); 453 454 wrqu->frag.value = priv->ieee80211->fts; 455 wrqu->frag.fixed = 0; /* no auto select */ 456 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); 457 458 return 0; 459 } 460 461 462 static int r8192_wx_set_wap(struct net_device *dev, 463 struct iw_request_info *info, 464 union iwreq_data *awrq, 465 char *extra) 466 { 467 468 int ret; 469 struct r8192_priv *priv = ieee80211_priv(dev); 470 /* struct sockaddr *temp = (struct sockaddr *)awrq; */ 471 mutex_lock(&priv->wx_mutex); 472 473 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra); 474 475 mutex_unlock(&priv->wx_mutex); 476 477 return ret; 478 479 } 480 481 static int r8192_wx_get_wap(struct net_device *dev, 482 struct iw_request_info *info, 483 union iwreq_data *wrqu, char *extra) 484 { 485 struct r8192_priv *priv = ieee80211_priv(dev); 486 487 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra); 488 } 489 490 static int r8192_wx_get_enc(struct net_device *dev, 491 struct iw_request_info *info, 492 union iwreq_data *wrqu, char *key) 493 { 494 struct r8192_priv *priv = ieee80211_priv(dev); 495 496 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); 497 } 498 499 static int r8192_wx_set_enc(struct net_device *dev, 500 struct iw_request_info *info, 501 union iwreq_data *wrqu, char *key) 502 { 503 struct r8192_priv *priv = ieee80211_priv(dev); 504 struct ieee80211_device *ieee = priv->ieee80211; 505 int ret; 506 u32 hwkey[4] = {0, 0, 0, 0}; 507 u8 mask = 0xff; 508 u32 key_idx = 0; 509 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 510 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 511 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 512 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; 513 int i; 514 515 if (!priv->up) 516 return -ENETDOWN; 517 518 mutex_lock(&priv->wx_mutex); 519 520 RT_TRACE(COMP_SEC, "Setting SW wep key"); 521 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key); 522 523 mutex_unlock(&priv->wx_mutex); 524 525 526 527 /* sometimes, the length is zero while we do not type key value */ 528 if (wrqu->encoding.length != 0) { 529 530 for (i = 0; i < 4; i++) { 531 hwkey[i] |= key[4*i+0]&mask; 532 if (i == 1 && (4*i+1) == wrqu->encoding.length) 533 mask = 0x00; 534 if (i == 3 && (4*i+1) == wrqu->encoding.length) 535 mask = 0x00; 536 hwkey[i] |= (key[4*i+1]&mask)<<8; 537 hwkey[i] |= (key[4*i+2]&mask)<<16; 538 hwkey[i] |= (key[4*i+3]&mask)<<24; 539 } 540 541 #define CONF_WEP40 0x4 542 #define CONF_WEP104 0x14 543 544 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) { 545 case 0: 546 key_idx = ieee->tx_keyidx; 547 break; 548 case 1: 549 key_idx = 0; 550 break; 551 case 2: 552 key_idx = 1; 553 break; 554 case 3: 555 key_idx = 2; 556 break; 557 case 4: 558 key_idx = 3; 559 break; 560 default: 561 break; 562 } 563 564 if (wrqu->encoding.length == 0x5) { 565 ieee->pairwise_key_type = KEY_TYPE_WEP40; 566 EnableHWSecurityConfig8192(dev); 567 568 setKey(dev, 569 key_idx, /* EntryNo */ 570 key_idx, /* KeyIndex */ 571 KEY_TYPE_WEP40, /* KeyType */ 572 zero_addr[key_idx], 573 0, /* DefaultKey */ 574 hwkey); /* KeyContent */ 575 576 } 577 578 else if (wrqu->encoding.length == 0xd) { 579 ieee->pairwise_key_type = KEY_TYPE_WEP104; 580 EnableHWSecurityConfig8192(dev); 581 582 setKey(dev, 583 key_idx, /* EntryNo */ 584 key_idx, /* KeyIndex */ 585 KEY_TYPE_WEP104, /* KeyType */ 586 zero_addr[key_idx], 587 0, /* DefaultKey */ 588 hwkey); /* KeyContent */ 589 590 } else { 591 printk("wrong type in WEP, not WEP40 and WEP104\n"); 592 } 593 594 } 595 596 return ret; 597 } 598 599 600 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, 601 union iwreq_data *wrqu, char *p) 602 { 603 604 struct r8192_priv *priv = ieee80211_priv(dev); 605 int *parms = (int *)p; 606 int mode = parms[0]; 607 608 priv->ieee80211->active_scan = mode; 609 610 return 1; 611 } 612 613 614 615 static int r8192_wx_set_retry(struct net_device *dev, 616 struct iw_request_info *info, 617 union iwreq_data *wrqu, char *extra) 618 { 619 struct r8192_priv *priv = ieee80211_priv(dev); 620 int err = 0; 621 622 mutex_lock(&priv->wx_mutex); 623 624 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 625 wrqu->retry.disabled){ 626 err = -EINVAL; 627 goto exit; 628 } 629 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { 630 err = -EINVAL; 631 goto exit; 632 } 633 634 if (wrqu->retry.value > R8180_MAX_RETRY) { 635 err = -EINVAL; 636 goto exit; 637 } 638 if (wrqu->retry.flags & IW_RETRY_MAX) { 639 priv->retry_rts = wrqu->retry.value; 640 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); 641 642 } else { 643 priv->retry_data = wrqu->retry.value; 644 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); 645 } 646 647 /* FIXME ! 648 * We might try to write directly the TX config register 649 * or to restart just the (R)TX process. 650 * I'm unsure if whole reset is really needed 651 */ 652 653 rtl8192_commit(dev); 654 exit: 655 mutex_unlock(&priv->wx_mutex); 656 657 return err; 658 } 659 660 static int r8192_wx_get_retry(struct net_device *dev, 661 struct iw_request_info *info, 662 union iwreq_data *wrqu, char *extra) 663 { 664 struct r8192_priv *priv = ieee80211_priv(dev); 665 666 667 wrqu->retry.disabled = 0; /* can't be disabled */ 668 669 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 670 IW_RETRY_LIFETIME) 671 return -EINVAL; 672 673 if (wrqu->retry.flags & IW_RETRY_MAX) { 674 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 675 wrqu->retry.value = priv->retry_rts; 676 } else { 677 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; 678 wrqu->retry.value = priv->retry_data; 679 } 680 681 return 0; 682 } 683 684 static int r8192_wx_get_sens(struct net_device *dev, 685 struct iw_request_info *info, 686 union iwreq_data *wrqu, char *extra) 687 { 688 struct r8192_priv *priv = ieee80211_priv(dev); 689 690 if (priv->rf_set_sens == NULL) 691 return -1; /* we have not this support for this radio */ 692 wrqu->sens.value = priv->sens; 693 return 0; 694 } 695 696 static int r8192_wx_set_sens(struct net_device *dev, 697 struct iw_request_info *info, 698 union iwreq_data *wrqu, char *extra) 699 { 700 701 struct r8192_priv *priv = ieee80211_priv(dev); 702 short err = 0; 703 704 mutex_lock(&priv->wx_mutex); 705 if (priv->rf_set_sens == NULL) { 706 err = -1; /* we have not this support for this radio */ 707 goto exit; 708 } 709 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) 710 priv->sens = wrqu->sens.value; 711 else 712 err = -EINVAL; 713 714 exit: 715 mutex_unlock(&priv->wx_mutex); 716 717 return err; 718 } 719 720 /* hw security need to reorganized. */ 721 static int r8192_wx_set_enc_ext(struct net_device *dev, 722 struct iw_request_info *info, 723 union iwreq_data *wrqu, char *extra) 724 { 725 int ret = 0; 726 struct r8192_priv *priv = ieee80211_priv(dev); 727 struct ieee80211_device *ieee = priv->ieee80211; 728 729 730 mutex_lock(&priv->wx_mutex); 731 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); 732 733 { 734 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 735 u8 zero[6] = {0}; 736 u32 key[4] = {0}; 737 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 738 struct iw_point *encoding = &wrqu->encoding; 739 u8 idx = 0, alg = 0, group = 0; 740 741 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE) 742 /* none is not allowed to use hwsec WB 2008.07.01 */ 743 goto end_hw_sec; 744 745 /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */ 746 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; 747 idx = encoding->flags & IW_ENCODE_INDEX; 748 if (idx) 749 idx--; 750 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; 751 752 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) { 753 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) 754 alg = KEY_TYPE_WEP104; 755 ieee->pairwise_key_type = alg; 756 EnableHWSecurityConfig8192(dev); 757 } 758 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */ 759 760 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { 761 762 setKey(dev, 763 idx, /* EntryNao */ 764 idx, /* KeyIndex */ 765 alg, /* KeyType */ 766 zero, /* MacAddr */ 767 0, /* DefaultKey */ 768 key); /* KeyContent */ 769 } else if (group) { 770 ieee->group_key_type = alg; 771 setKey(dev, 772 idx, /* EntryNo */ 773 idx, /* KeyIndex */ 774 alg, /* KeyType */ 775 broadcast_addr, /* MacAddr */ 776 0, /* DefaultKey */ 777 key); /* KeyContent */ 778 } else { /* pairwise key */ 779 setKey(dev, 780 4, /* EntryNo */ 781 idx, /* KeyIndex */ 782 alg, /* KeyType */ 783 (u8 *)ieee->ap_mac_addr,/* MacAddr */ 784 0, /* DefaultKey */ 785 key); /* KeyContent */ 786 } 787 788 789 } 790 791 end_hw_sec: 792 793 mutex_unlock(&priv->wx_mutex); 794 return ret; 795 796 } 797 static int r8192_wx_set_auth(struct net_device *dev, 798 struct iw_request_info *info, 799 union iwreq_data *data, char *extra) 800 { 801 int ret = 0; 802 struct r8192_priv *priv = ieee80211_priv(dev); 803 804 mutex_lock(&priv->wx_mutex); 805 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); 806 mutex_unlock(&priv->wx_mutex); 807 return ret; 808 } 809 810 static int r8192_wx_set_mlme(struct net_device *dev, 811 struct iw_request_info *info, 812 union iwreq_data *wrqu, char *extra) 813 { 814 815 int ret = 0; 816 struct r8192_priv *priv = ieee80211_priv(dev); 817 818 mutex_lock(&priv->wx_mutex); 819 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); 820 821 mutex_unlock(&priv->wx_mutex); 822 return ret; 823 } 824 825 static int r8192_wx_set_gen_ie(struct net_device *dev, 826 struct iw_request_info *info, 827 union iwreq_data *data, char *extra) 828 { 829 int ret = 0; 830 struct r8192_priv *priv = ieee80211_priv(dev); 831 832 mutex_lock(&priv->wx_mutex); 833 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); 834 mutex_unlock(&priv->wx_mutex); 835 return ret; 836 837 838 } 839 840 static int dummy(struct net_device *dev, struct iw_request_info *a, 841 union iwreq_data *wrqu, char *b) 842 { 843 return -1; 844 } 845 846 static iw_handler r8192_wx_handlers[] = { 847 NULL, /* SIOCSIWCOMMIT */ 848 r8192_wx_get_name, /* SIOCGIWNAME */ 849 dummy, /* SIOCSIWNWID */ 850 dummy, /* SIOCGIWNWID */ 851 r8192_wx_set_freq, /* SIOCSIWFREQ */ 852 r8192_wx_get_freq, /* SIOCGIWFREQ */ 853 r8192_wx_set_mode, /* SIOCSIWMODE */ 854 r8192_wx_get_mode, /* SIOCGIWMODE */ 855 r8192_wx_set_sens, /* SIOCSIWSENS */ 856 r8192_wx_get_sens, /* SIOCGIWSENS */ 857 NULL, /* SIOCSIWRANGE */ 858 rtl8180_wx_get_range, /* SIOCGIWRANGE */ 859 NULL, /* SIOCSIWPRIV */ 860 NULL, /* SIOCGIWPRIV */ 861 NULL, /* SIOCSIWSTATS */ 862 NULL, /* SIOCGIWSTATS */ 863 dummy, /* SIOCSIWSPY */ 864 dummy, /* SIOCGIWSPY */ 865 NULL, /* SIOCGIWTHRSPY */ 866 NULL, /* SIOCWIWTHRSPY */ 867 r8192_wx_set_wap, /* SIOCSIWAP */ 868 r8192_wx_get_wap, /* SIOCGIWAP */ 869 r8192_wx_set_mlme, /* MLME-- */ 870 dummy, /* SIOCGIWAPLIST -- deprecated */ 871 r8192_wx_set_scan, /* SIOCSIWSCAN */ 872 r8192_wx_get_scan, /* SIOCGIWSCAN */ 873 r8192_wx_set_essid, /* SIOCSIWESSID */ 874 r8192_wx_get_essid, /* SIOCGIWESSID */ 875 dummy, /* SIOCSIWNICKN */ 876 dummy, /* SIOCGIWNICKN */ 877 NULL, /* -- hole -- */ 878 NULL, /* -- hole -- */ 879 r8192_wx_set_rate, /* SIOCSIWRATE */ 880 r8192_wx_get_rate, /* SIOCGIWRATE */ 881 r8192_wx_set_rts, /* SIOCSIWRTS */ 882 r8192_wx_get_rts, /* SIOCGIWRTS */ 883 r8192_wx_set_frag, /* SIOCSIWFRAG */ 884 r8192_wx_get_frag, /* SIOCGIWFRAG */ 885 dummy, /* SIOCSIWTXPOW */ 886 dummy, /* SIOCGIWTXPOW */ 887 r8192_wx_set_retry, /* SIOCSIWRETRY */ 888 r8192_wx_get_retry, /* SIOCGIWRETRY */ 889 r8192_wx_set_enc, /* SIOCSIWENCODE */ 890 r8192_wx_get_enc, /* SIOCGIWENCODE */ 891 r8192_wx_set_power, /* SIOCSIWPOWER */ 892 r8192_wx_get_power, /* SIOCGIWPOWER */ 893 NULL, /*---hole---*/ 894 NULL, /*---hole---*/ 895 r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */ 896 NULL, /* SIOCSIWGENIE */ 897 898 r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */ 899 NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */ 900 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 901 NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */ 902 NULL, /* SIOCSIWPMKSA */ 903 NULL, /*---hole---*/ 904 905 }; 906 907 908 static const struct iw_priv_args r8192_private_args[] = { 909 910 { 911 SIOCIWFIRSTPRIV + 0x0, 912 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" 913 }, 914 915 { 916 SIOCIWFIRSTPRIV + 0x1, 917 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" 918 919 }, 920 { 921 SIOCIWFIRSTPRIV + 0x2, 922 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 923 }, 924 { 925 SIOCIWFIRSTPRIV + 0x3, 926 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" 927 928 } 929 930 }; 931 932 static iw_handler r8192_private_handler[] = { 933 r8192_wx_set_crcmon, 934 r8192_wx_set_scan_type, 935 r8192_wx_set_rawtx, 936 r8192_wx_force_reset, 937 }; 938 939 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) 940 { 941 struct r8192_priv *priv = ieee80211_priv(dev); 942 struct ieee80211_device *ieee = priv->ieee80211; 943 struct iw_statistics *wstats = &priv->wstats; 944 int tmp_level = 0; 945 int tmp_qual = 0; 946 int tmp_noise = 0; 947 948 if (ieee->state < IEEE80211_LINKED) { 949 wstats->qual.qual = 0; 950 wstats->qual.level = 0; 951 wstats->qual.noise = 0; 952 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 953 return wstats; 954 } 955 956 tmp_level = (&ieee->current_network)->stats.rssi; 957 tmp_qual = (&ieee->current_network)->stats.signal; 958 tmp_noise = (&ieee->current_network)->stats.noise; 959 960 wstats->qual.level = tmp_level; 961 wstats->qual.qual = tmp_qual; 962 wstats->qual.noise = tmp_noise; 963 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 964 return wstats; 965 } 966 967 const struct iw_handler_def r8192_wx_handlers_def = { 968 .standard = r8192_wx_handlers, 969 .num_standard = ARRAY_SIZE(r8192_wx_handlers), 970 .private = r8192_private_handler, 971 .num_private = ARRAY_SIZE(r8192_private_handler), 972 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), 973 .get_wireless_stats = r8192_get_wireless_stats, 974 .private_args = (struct iw_priv_args *)r8192_private_args, 975 }; 976