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