1/****************************************************************************** 2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. 3 * 4 * This program is distributed in the hope that it will be useful, but WITHOUT 5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 7 * more details. 8 * 9 * You should have received a copy of the GNU General Public License along with 10 * this program; if not, write to the Free Software Foundation, Inc., 11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 12 * 13 * The full GNU General Public License is included in this distribution in the 14 * file called LICENSE. 15 * 16 * Contact Information: 17 * wlanfae <wlanfae@realtek.com> 18******************************************************************************/ 19 20#include <linux/string.h> 21#include "rtl_core.h" 22 23#define RATE_COUNT 12 24static u32 rtl8192_rates[] = { 25 1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, 26 18000000, 24000000, 36000000, 48000000, 54000000 27}; 28 29#ifndef ENETDOWN 30#define ENETDOWN 1 31#endif 32 33static int r8192_wx_get_freq(struct net_device *dev, 34 struct iw_request_info *a, 35 union iwreq_data *wrqu, char *b) 36{ 37 struct r8192_priv *priv = rtllib_priv(dev); 38 39 return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b); 40} 41 42 43static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 44 union iwreq_data *wrqu, char *b) 45{ 46 struct r8192_priv *priv = rtllib_priv(dev); 47 48 return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b); 49} 50 51static int r8192_wx_get_rate(struct net_device *dev, 52 struct iw_request_info *info, 53 union iwreq_data *wrqu, char *extra) 54{ 55 struct r8192_priv *priv = rtllib_priv(dev); 56 return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra); 57} 58 59 60 61static int r8192_wx_set_rate(struct net_device *dev, 62 struct iw_request_info *info, 63 union iwreq_data *wrqu, char *extra) 64{ 65 int ret; 66 struct r8192_priv *priv = rtllib_priv(dev); 67 68 if (priv->bHwRadioOff == true) 69 return 0; 70 71 down(&priv->wx_sem); 72 73 ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra); 74 75 up(&priv->wx_sem); 76 77 return ret; 78} 79 80 81static int r8192_wx_set_rts(struct net_device *dev, 82 struct iw_request_info *info, 83 union iwreq_data *wrqu, char *extra) 84{ 85 int ret; 86 struct r8192_priv *priv = rtllib_priv(dev); 87 88 if (priv->bHwRadioOff == true) 89 return 0; 90 91 down(&priv->wx_sem); 92 93 ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra); 94 95 up(&priv->wx_sem); 96 97 return ret; 98} 99 100static int r8192_wx_get_rts(struct net_device *dev, 101 struct iw_request_info *info, 102 union iwreq_data *wrqu, char *extra) 103{ 104 struct r8192_priv *priv = rtllib_priv(dev); 105 return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra); 106} 107 108static int r8192_wx_set_power(struct net_device *dev, 109 struct iw_request_info *info, 110 union iwreq_data *wrqu, char *extra) 111{ 112 int ret; 113 struct r8192_priv *priv = rtllib_priv(dev); 114 115 if (priv->bHwRadioOff == true) { 116 RT_TRACE(COMP_ERR, "%s():Hw is Radio Off, we can't set " 117 "Power,return\n", __func__); 118 return 0; 119 } 120 down(&priv->wx_sem); 121 122 ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra); 123 124 up(&priv->wx_sem); 125 126 return ret; 127} 128 129static int r8192_wx_get_power(struct net_device *dev, 130 struct iw_request_info *info, 131 union iwreq_data *wrqu, char *extra) 132{ 133 struct r8192_priv *priv = rtllib_priv(dev); 134 return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra); 135} 136 137static int r8192_wx_set_rawtx(struct net_device *dev, 138 struct iw_request_info *info, 139 union iwreq_data *wrqu, char *extra) 140{ 141 struct r8192_priv *priv = rtllib_priv(dev); 142 int ret; 143 144 if (priv->bHwRadioOff == true) 145 return 0; 146 147 down(&priv->wx_sem); 148 149 ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra); 150 151 up(&priv->wx_sem); 152 153 return ret; 154 155} 156 157static int r8192_wx_force_reset(struct net_device *dev, 158 struct iw_request_info *info, 159 union iwreq_data *wrqu, char *extra) 160{ 161 struct r8192_priv *priv = rtllib_priv(dev); 162 163 down(&priv->wx_sem); 164 165 RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n", 166 __func__, *extra); 167 priv->force_reset = *extra; 168 up(&priv->wx_sem); 169 return 0; 170 171} 172 173static int r8192_wx_force_mic_error(struct net_device *dev, 174 struct iw_request_info *info, 175 union iwreq_data *wrqu, char *extra) 176{ 177 struct r8192_priv *priv = rtllib_priv(dev); 178 struct rtllib_device *ieee = priv->rtllib; 179 180 down(&priv->wx_sem); 181 182 RT_TRACE(COMP_DBG, "%s(): force mic error !\n", __func__); 183 ieee->force_mic_error = true; 184 up(&priv->wx_sem); 185 return 0; 186 187} 188 189#define MAX_ADHOC_PEER_NUM 64 190struct adhoc_peer_entry { 191 unsigned char MacAddr[ETH_ALEN]; 192 unsigned char WirelessMode; 193 unsigned char bCurTxBW40MHz; 194}; 195struct adhoc_peers_info { 196 struct adhoc_peer_entry Entry[MAX_ADHOC_PEER_NUM]; 197 unsigned char num; 198}; 199 200static int r8192_wx_get_adhoc_peers(struct net_device *dev, 201 struct iw_request_info *info, 202 union iwreq_data *wrqu, char *extra) 203{ 204 return 0; 205} 206 207 208static int r8191se_wx_get_firm_version(struct net_device *dev, 209 struct iw_request_info *info, 210 struct iw_param *wrqu, char *extra) 211{ 212 return 0; 213} 214 215static int r8192_wx_adapter_power_status(struct net_device *dev, 216 struct iw_request_info *info, 217 union iwreq_data *wrqu, char *extra) 218{ 219 struct r8192_priv *priv = rtllib_priv(dev); 220 struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) 221 (&(priv->rtllib->PowerSaveControl)); 222 struct rtllib_device *ieee = priv->rtllib; 223 224 down(&priv->wx_sem); 225 226 RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ? 227 "DC power" : "AC power"); 228 if (*extra || priv->force_lps) { 229 priv->ps_force = false; 230 pPSC->bLeisurePs = true; 231 } else { 232 if (priv->rtllib->state == RTLLIB_LINKED) 233 LeisurePSLeave(dev); 234 235 priv->ps_force = true; 236 pPSC->bLeisurePs = false; 237 ieee->ps = *extra; 238 } 239 240 up(&priv->wx_sem); 241 242 return 0; 243} 244 245static int r8192se_wx_set_radio(struct net_device *dev, 246 struct iw_request_info *info, 247 union iwreq_data *wrqu, char *extra) 248{ 249 struct r8192_priv *priv = rtllib_priv(dev); 250 251 down(&priv->wx_sem); 252 253 printk(KERN_INFO "%s(): set radio ! extra is %d\n", __func__, *extra); 254 if ((*extra != 0) && (*extra != 1)) { 255 RT_TRACE(COMP_ERR, "%s(): set radio an err value,must 0(radio " 256 "off) or 1(radio on)\n", __func__); 257 up(&priv->wx_sem); 258 return -1; 259 } 260 priv->sw_radio_on = *extra; 261 up(&priv->wx_sem); 262 return 0; 263 264} 265 266static int r8192se_wx_set_lps_awake_interval(struct net_device *dev, 267 struct iw_request_info *info, 268 union iwreq_data *wrqu, char *extra) 269{ 270 struct r8192_priv *priv = rtllib_priv(dev); 271 struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) 272 (&(priv->rtllib->PowerSaveControl)); 273 274 down(&priv->wx_sem); 275 276 printk(KERN_INFO "%s(): set lps awake interval ! extra is %d\n", 277 __func__, *extra); 278 279 pPSC->RegMaxLPSAwakeIntvl = *extra; 280 up(&priv->wx_sem); 281 return 0; 282} 283 284static int r8192se_wx_set_force_lps(struct net_device *dev, 285 struct iw_request_info *info, 286 union iwreq_data *wrqu, char *extra) 287{ 288 struct r8192_priv *priv = rtllib_priv(dev); 289 290 down(&priv->wx_sem); 291 292 printk(KERN_INFO "%s(): force LPS ! extra is %d (1 is open 0 is " 293 "close)\n", __func__, *extra); 294 priv->force_lps = *extra; 295 up(&priv->wx_sem); 296 return 0; 297 298} 299 300static int r8192_wx_set_debugflag(struct net_device *dev, 301 struct iw_request_info *info, 302 union iwreq_data *wrqu, char *extra) 303{ 304 struct r8192_priv *priv = rtllib_priv(dev); 305 u8 c = *extra; 306 307 if (priv->bHwRadioOff == true) 308 return 0; 309 310 printk(KERN_INFO "=====>%s(), *extra:%x, debugflag:%x\n", __func__, 311 *extra, rt_global_debug_component); 312 if (c > 0) 313 rt_global_debug_component |= (1<<c); 314 else 315 rt_global_debug_component &= BIT31; 316 return 0; 317} 318 319static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 320 union iwreq_data *wrqu, char *b) 321{ 322 struct r8192_priv *priv = rtllib_priv(dev); 323 struct rtllib_device *ieee = netdev_priv_rsl(dev); 324 325 enum rt_rf_power_state rtState; 326 int ret; 327 328 if (priv->bHwRadioOff == true) 329 return 0; 330 rtState = priv->rtllib->eRFPowerState; 331 down(&priv->wx_sem); 332 if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR || 333 ieee->bNetPromiscuousMode) { 334 if (priv->rtllib->PowerSaveControl.bInactivePs) { 335 if (rtState == eRfOff) { 336 if (priv->rtllib->RfOffReason > 337 RF_CHANGE_BY_IPS) { 338 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", 339 __func__); 340 up(&priv->wx_sem); 341 return -1; 342 } else { 343 printk(KERN_INFO "=========>%s(): " 344 "IPSLeave\n", __func__); 345 down(&priv->rtllib->ips_sem); 346 IPSLeave(dev); 347 up(&priv->rtllib->ips_sem); 348 } 349 } 350 } 351 } 352 ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b); 353 354 up(&priv->wx_sem); 355 return ret; 356} 357 358struct iw_range_with_scan_capa { 359 /* Informative stuff (to choose between different interface) */ 360 __u32 throughput; /* To give an idea... */ 361 /* In theory this value should be the maximum benchmarked 362 * TCP/IP throughput, because with most of these devices the 363 * bit rate is meaningless (overhead an co) to estimate how 364 * fast the connection will go and pick the fastest one. 365 * I suggest people to play with Netperf or any benchmark... 366 */ 367 368 /* NWID (or domain id) */ 369 __u32 min_nwid; /* Minimal NWID we are able to set */ 370 __u32 max_nwid; /* Maximal NWID we are able to set */ 371 372 /* Old Frequency (backward compat - moved lower ) */ 373 __u16 old_num_channels; 374 __u8 old_num_frequency; 375 376 /* Scan capabilities */ 377 __u8 scan_capa; 378}; 379 380static int rtl8192_wx_get_range(struct net_device *dev, 381 struct iw_request_info *info, 382 union iwreq_data *wrqu, char *extra) 383{ 384 struct iw_range *range = (struct iw_range *)extra; 385 struct r8192_priv *priv = rtllib_priv(dev); 386 u16 val; 387 int i; 388 389 wrqu->data.length = sizeof(*range); 390 memset(range, 0, sizeof(*range)); 391 392 /* ~130 Mb/s real (802.11n) */ 393 range->throughput = 130 * 1000 * 1000; 394 395 if (priv->rf_set_sens != NULL) { 396 /* signal level threshold range */ 397 range->sensitivity = priv->max_sens; 398 } 399 400 range->max_qual.qual = 100; 401 range->max_qual.level = 0; 402 range->max_qual.noise = 0; 403 range->max_qual.updated = 7; /* Updated all three */ 404 405 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ 406 range->avg_qual.level = 0; 407 range->avg_qual.noise = 0; 408 range->avg_qual.updated = 7; /* Updated all three */ 409 410 range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES); 411 412 for (i = 0; i < range->num_bitrates; i++) 413 range->bitrate[i] = rtl8192_rates[i]; 414 415 range->max_rts = DEFAULT_RTS_THRESHOLD; 416 range->min_frag = MIN_FRAG_THRESHOLD; 417 range->max_frag = MAX_FRAG_THRESHOLD; 418 419 range->min_pmp = 0; 420 range->max_pmp = 5000000; 421 range->min_pmt = 0; 422 range->max_pmt = 65535*1000; 423 range->pmp_flags = IW_POWER_PERIOD; 424 range->pmt_flags = IW_POWER_TIMEOUT; 425 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; 426 range->we_version_compiled = WIRELESS_EXT; 427 range->we_version_source = 18; 428 429 for (i = 0, val = 0; i < 14; i++) { 430 if ((priv->rtllib->active_channel_map)[i+1]) { 431 range->freq[val].i = i + 1; 432 range->freq[val].m = rtllib_wlan_frequencies[i] * 433 100000; 434 range->freq[val].e = 1; 435 val++; 436 } 437 438 if (val == IW_MAX_FREQUENCIES) 439 break; 440 } 441 range->num_frequency = val; 442 range->num_channels = val; 443 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| 444 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; 445 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE; 446 447 /* Event capability (kernel + driver) */ 448 449 return 0; 450} 451 452static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 453 union iwreq_data *wrqu, char *b) 454{ 455 struct r8192_priv *priv = rtllib_priv(dev); 456 struct rtllib_device *ieee = priv->rtllib; 457 enum rt_rf_power_state rtState; 458 int ret; 459 460 if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) { 461 if ((ieee->state >= RTLLIB_ASSOCIATING) && 462 (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED)) 463 return 0; 464 if ((priv->rtllib->state == RTLLIB_LINKED) && 465 (priv->rtllib->CntAfterLink < 2)) 466 return 0; 467 } 468 469 if (priv->bHwRadioOff == true) { 470 printk(KERN_INFO "================>%s(): hwradio off\n", 471 __func__); 472 return 0; 473 } 474 rtState = priv->rtllib->eRFPowerState; 475 if (!priv->up) 476 return -ENETDOWN; 477 if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true) 478 return -EAGAIN; 479 480 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 481 struct iw_scan_req *req = (struct iw_scan_req *)b; 482 if (req->essid_len) { 483 ieee->current_network.ssid_len = req->essid_len; 484 memcpy(ieee->current_network.ssid, req->essid, 485 req->essid_len); 486 } 487 } 488 489 down(&priv->wx_sem); 490 491 priv->rtllib->FirstIe_InScan = true; 492 493 if (priv->rtllib->state != RTLLIB_LINKED) { 494 if (priv->rtllib->PowerSaveControl.bInactivePs) { 495 if (rtState == eRfOff) { 496 if (priv->rtllib->RfOffReason > 497 RF_CHANGE_BY_IPS) { 498 RT_TRACE(COMP_ERR, "%s(): RF is " 499 "OFF.\n", __func__); 500 up(&priv->wx_sem); 501 return -1; 502 } else { 503 RT_TRACE(COMP_PS, "=========>%s(): " 504 "IPSLeave\n", __func__); 505 down(&priv->rtllib->ips_sem); 506 IPSLeave(dev); 507 up(&priv->rtllib->ips_sem); 508 } 509 } 510 } 511 rtllib_stop_scan(priv->rtllib); 512 if (priv->rtllib->LedControlHandler) 513 priv->rtllib->LedControlHandler(dev, 514 LED_CTL_SITE_SURVEY); 515 516 if (priv->rtllib->eRFPowerState != eRfOff) { 517 priv->rtllib->actscanning = true; 518 519 if (ieee->ScanOperationBackupHandler) 520 ieee->ScanOperationBackupHandler(ieee->dev, 521 SCAN_OPT_BACKUP); 522 523 rtllib_start_scan_syncro(priv->rtllib, 0); 524 525 if (ieee->ScanOperationBackupHandler) 526 ieee->ScanOperationBackupHandler(ieee->dev, 527 SCAN_OPT_RESTORE); 528 } 529 ret = 0; 530 } else { 531 priv->rtllib->actscanning = true; 532 ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b); 533 } 534 535 up(&priv->wx_sem); 536 return ret; 537} 538 539 540static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 541 union iwreq_data *wrqu, char *b) 542{ 543 544 int ret; 545 struct r8192_priv *priv = rtllib_priv(dev); 546 547 if (!priv->up) 548 return -ENETDOWN; 549 550 if (priv->bHwRadioOff == true) 551 return 0; 552 553 554 down(&priv->wx_sem); 555 556 ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b); 557 558 up(&priv->wx_sem); 559 560 return ret; 561} 562 563static int r8192_wx_set_essid(struct net_device *dev, 564 struct iw_request_info *a, 565 union iwreq_data *wrqu, char *b) 566{ 567 struct r8192_priv *priv = rtllib_priv(dev); 568 int ret; 569 570 if ((rtllib_act_scanning(priv->rtllib, false)) && 571 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { 572 ; /* TODO - get rid of if */ 573 } 574 if (priv->bHwRadioOff == true) { 575 printk(KERN_INFO "=========>%s():hw radio off,or Rf state is " 576 "eRfOff, return\n", __func__); 577 return 0; 578 } 579 down(&priv->wx_sem); 580 ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b); 581 582 up(&priv->wx_sem); 583 584 return ret; 585} 586 587static int r8192_wx_get_essid(struct net_device *dev, 588 struct iw_request_info *a, 589 union iwreq_data *wrqu, char *b) 590{ 591 int ret; 592 struct r8192_priv *priv = rtllib_priv(dev); 593 594 down(&priv->wx_sem); 595 596 ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b); 597 598 up(&priv->wx_sem); 599 600 return ret; 601} 602 603static int r8192_wx_set_nick(struct net_device *dev, 604 struct iw_request_info *info, 605 union iwreq_data *wrqu, char *extra) 606{ 607 struct r8192_priv *priv = rtllib_priv(dev); 608 609 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 610 return -E2BIG; 611 down(&priv->wx_sem); 612 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 613 memset(priv->nick, 0, sizeof(priv->nick)); 614 memcpy(priv->nick, extra, wrqu->data.length); 615 up(&priv->wx_sem); 616 return 0; 617 618} 619 620static int r8192_wx_get_nick(struct net_device *dev, 621 struct iw_request_info *info, 622 union iwreq_data *wrqu, char *extra) 623{ 624 struct r8192_priv *priv = rtllib_priv(dev); 625 626 down(&priv->wx_sem); 627 wrqu->data.length = strlen(priv->nick); 628 memcpy(extra, priv->nick, wrqu->data.length); 629 wrqu->data.flags = 1; /* active */ 630 up(&priv->wx_sem); 631 return 0; 632} 633 634static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, 635 union iwreq_data *wrqu, char *b) 636{ 637 int ret; 638 struct r8192_priv *priv = rtllib_priv(dev); 639 640 if (priv->bHwRadioOff == true) 641 return 0; 642 643 down(&priv->wx_sem); 644 645 ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b); 646 647 up(&priv->wx_sem); 648 return ret; 649} 650 651static int r8192_wx_get_name(struct net_device *dev, 652 struct iw_request_info *info, 653 union iwreq_data *wrqu, char *extra) 654{ 655 struct r8192_priv *priv = rtllib_priv(dev); 656 return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra); 657} 658 659 660static int r8192_wx_set_frag(struct net_device *dev, 661 struct iw_request_info *info, 662 union iwreq_data *wrqu, char *extra) 663{ 664 struct r8192_priv *priv = rtllib_priv(dev); 665 666 if (priv->bHwRadioOff == true) 667 return 0; 668 669 if (wrqu->frag.disabled) 670 priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; 671 else { 672 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 673 wrqu->frag.value > MAX_FRAG_THRESHOLD) 674 return -EINVAL; 675 676 priv->rtllib->fts = wrqu->frag.value & ~0x1; 677 } 678 679 return 0; 680} 681 682 683static int r8192_wx_get_frag(struct net_device *dev, 684 struct iw_request_info *info, 685 union iwreq_data *wrqu, char *extra) 686{ 687 struct r8192_priv *priv = rtllib_priv(dev); 688 689 wrqu->frag.value = priv->rtllib->fts; 690 wrqu->frag.fixed = 0; /* no auto select */ 691 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); 692 693 return 0; 694} 695 696 697static int r8192_wx_set_wap(struct net_device *dev, 698 struct iw_request_info *info, 699 union iwreq_data *awrq, 700 char *extra) 701{ 702 int ret; 703 struct r8192_priv *priv = rtllib_priv(dev); 704 705 if ((rtllib_act_scanning(priv->rtllib, false)) && 706 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { 707 ; /* TODO - get rid of if */ 708 } 709 710 if (priv->bHwRadioOff == true) 711 return 0; 712 713 down(&priv->wx_sem); 714 715 ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra); 716 717 up(&priv->wx_sem); 718 719 return ret; 720 721} 722 723 724static int r8192_wx_get_wap(struct net_device *dev, 725 struct iw_request_info *info, 726 union iwreq_data *wrqu, char *extra) 727{ 728 struct r8192_priv *priv = rtllib_priv(dev); 729 730 return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra); 731} 732 733 734static int r8192_wx_get_enc(struct net_device *dev, 735 struct iw_request_info *info, 736 union iwreq_data *wrqu, char *key) 737{ 738 struct r8192_priv *priv = rtllib_priv(dev); 739 740 return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key); 741} 742 743static int r8192_wx_set_enc(struct net_device *dev, 744 struct iw_request_info *info, 745 union iwreq_data *wrqu, char *key) 746{ 747 struct r8192_priv *priv = rtllib_priv(dev); 748 int ret; 749 750 struct rtllib_device *ieee = priv->rtllib; 751 u32 hwkey[4] = {0, 0, 0, 0}; 752 u8 mask = 0xff; 753 u32 key_idx = 0; 754 u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 755 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 756 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 757 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; 758 int i; 759 760 if ((rtllib_act_scanning(priv->rtllib, false)) && 761 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) 762 ; /* TODO - get rid of if */ 763 if (priv->bHwRadioOff == true) 764 return 0; 765 766 if (!priv->up) 767 return -ENETDOWN; 768 769 priv->rtllib->wx_set_enc = 1; 770 down(&priv->rtllib->ips_sem); 771 IPSLeave(dev); 772 up(&priv->rtllib->ips_sem); 773 down(&priv->wx_sem); 774 775 RT_TRACE(COMP_SEC, "Setting SW wep key"); 776 ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key); 777 up(&priv->wx_sem); 778 779 780 if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { 781 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; 782 CamResetAllEntry(dev); 783 memset(priv->rtllib->swcamtable, 0, 784 sizeof(struct sw_cam_table) * 32); 785 goto end_hw_sec; 786 } 787 if (wrqu->encoding.length != 0) { 788 789 for (i = 0; i < 4; i++) { 790 hwkey[i] |= key[4*i+0]&mask; 791 if (i == 1 && (4 * i + 1) == wrqu->encoding.length) 792 mask = 0x00; 793 if (i == 3 && (4 * i + 1) == wrqu->encoding.length) 794 mask = 0x00; 795 hwkey[i] |= (key[4 * i + 1] & mask) << 8; 796 hwkey[i] |= (key[4 * i + 2] & mask) << 16; 797 hwkey[i] |= (key[4 * i + 3] & mask) << 24; 798 } 799 800 #define CONF_WEP40 0x4 801 #define CONF_WEP104 0x14 802 803 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) { 804 case 0: 805 key_idx = ieee->crypt_info.tx_keyidx; 806 break; 807 case 1: 808 key_idx = 0; 809 break; 810 case 2: 811 key_idx = 1; 812 break; 813 case 3: 814 key_idx = 2; 815 break; 816 case 4: 817 key_idx = 3; 818 break; 819 default: 820 break; 821 } 822 if (wrqu->encoding.length == 0x5) { 823 ieee->pairwise_key_type = KEY_TYPE_WEP40; 824 EnableHWSecurityConfig8192(dev); 825 } 826 827 else if (wrqu->encoding.length == 0xd) { 828 ieee->pairwise_key_type = KEY_TYPE_WEP104; 829 EnableHWSecurityConfig8192(dev); 830 setKey(dev, key_idx, key_idx, KEY_TYPE_WEP104, 831 zero_addr[key_idx], 0, hwkey); 832 set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104, 833 zero_addr[key_idx], 0, hwkey, 0); 834 } else { 835 printk(KERN_INFO "wrong type in WEP, not WEP40 and WEP104\n"); 836 } 837 } 838 839end_hw_sec: 840 priv->rtllib->wx_set_enc = 0; 841 return ret; 842} 843 844static int r8192_wx_set_scan_type(struct net_device *dev, 845 struct iw_request_info *aa, 846 union iwreq_data *wrqu, char *p) 847{ 848 struct r8192_priv *priv = rtllib_priv(dev); 849 int *parms = (int *)p; 850 int mode = parms[0]; 851 852 if (priv->bHwRadioOff == true) 853 return 0; 854 855 priv->rtllib->active_scan = mode; 856 857 return 1; 858} 859 860 861 862#define R8192_MAX_RETRY 255 863static int r8192_wx_set_retry(struct net_device *dev, 864 struct iw_request_info *info, 865 union iwreq_data *wrqu, char *extra) 866{ 867 struct r8192_priv *priv = rtllib_priv(dev); 868 int err = 0; 869 870 if (priv->bHwRadioOff == true) 871 return 0; 872 873 down(&priv->wx_sem); 874 875 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 876 wrqu->retry.disabled) { 877 err = -EINVAL; 878 goto exit; 879 } 880 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { 881 err = -EINVAL; 882 goto exit; 883 } 884 885 if (wrqu->retry.value > R8192_MAX_RETRY) { 886 err = -EINVAL; 887 goto exit; 888 } 889 if (wrqu->retry.flags & IW_RETRY_MAX) { 890 priv->retry_rts = wrqu->retry.value; 891 DMESG("Setting retry for RTS/CTS data to %d", 892 wrqu->retry.value); 893 894 } else { 895 priv->retry_data = wrqu->retry.value; 896 DMESG("Setting retry for non RTS/CTS data to %d", 897 wrqu->retry.value); 898 } 899 900 901 rtl8192_commit(dev); 902exit: 903 up(&priv->wx_sem); 904 905 return err; 906} 907 908static int r8192_wx_get_retry(struct net_device *dev, 909 struct iw_request_info *info, 910 union iwreq_data *wrqu, char *extra) 911{ 912 struct r8192_priv *priv = rtllib_priv(dev); 913 914 915 wrqu->retry.disabled = 0; /* can't be disabled */ 916 917 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 918 IW_RETRY_LIFETIME) 919 return -EINVAL; 920 921 if (wrqu->retry.flags & IW_RETRY_MAX) { 922 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 923 wrqu->retry.value = priv->retry_rts; 924 } else { 925 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; 926 wrqu->retry.value = priv->retry_data; 927 } 928 return 0; 929} 930 931static int r8192_wx_get_sens(struct net_device *dev, 932 struct iw_request_info *info, 933 union iwreq_data *wrqu, char *extra) 934{ 935 struct r8192_priv *priv = rtllib_priv(dev); 936 if (priv->rf_set_sens == NULL) 937 return -1; /* we have not this support for this radio */ 938 wrqu->sens.value = priv->sens; 939 return 0; 940} 941 942 943static int r8192_wx_set_sens(struct net_device *dev, 944 struct iw_request_info *info, 945 union iwreq_data *wrqu, char *extra) 946{ 947 948 struct r8192_priv *priv = rtllib_priv(dev); 949 950 short err = 0; 951 952 if (priv->bHwRadioOff == true) 953 return 0; 954 955 down(&priv->wx_sem); 956 if (priv->rf_set_sens == NULL) { 957 err = -1; /* we have not this support for this radio */ 958 goto exit; 959 } 960 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) 961 priv->sens = wrqu->sens.value; 962 else 963 err = -EINVAL; 964 965exit: 966 up(&priv->wx_sem); 967 968 return err; 969} 970 971static int r8192_wx_set_enc_ext(struct net_device *dev, 972 struct iw_request_info *info, 973 union iwreq_data *wrqu, char *extra) 974{ 975 int ret = 0; 976 struct r8192_priv *priv = rtllib_priv(dev); 977 struct rtllib_device *ieee = priv->rtllib; 978 979 if (priv->bHwRadioOff == true) 980 return 0; 981 982 down(&priv->wx_sem); 983 984 priv->rtllib->wx_set_enc = 1; 985 down(&priv->rtllib->ips_sem); 986 IPSLeave(dev); 987 up(&priv->rtllib->ips_sem); 988 989 ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra); 990 { 991 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 992 u8 zero[6] = {0}; 993 u32 key[4] = {0}; 994 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 995 struct iw_point *encoding = &wrqu->encoding; 996 u8 idx = 0, alg = 0, group = 0; 997 if ((encoding->flags & IW_ENCODE_DISABLED) || 998 ext->alg == IW_ENCODE_ALG_NONE) { 999 ieee->pairwise_key_type = ieee->group_key_type 1000 = KEY_TYPE_NA; 1001 CamResetAllEntry(dev); 1002 memset(priv->rtllib->swcamtable, 0, 1003 sizeof(struct sw_cam_table) * 32); 1004 goto end_hw_sec; 1005 } 1006 alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP : 1007 ext->alg; 1008 idx = encoding->flags & IW_ENCODE_INDEX; 1009 if (idx) 1010 idx--; 1011 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; 1012 1013 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || 1014 (alg == KEY_TYPE_WEP40)) { 1015 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) 1016 alg = KEY_TYPE_WEP104; 1017 ieee->pairwise_key_type = alg; 1018 EnableHWSecurityConfig8192(dev); 1019 } 1020 memcpy((u8 *)key, ext->key, 16); 1021 1022 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { 1023 if (ext->key_len == 13) 1024 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; 1025 setKey(dev, idx, idx, alg, zero, 0, key); 1026 set_swcam(dev, idx, idx, alg, zero, 0, key, 0); 1027 } else if (group) { 1028 ieee->group_key_type = alg; 1029 setKey(dev, idx, idx, alg, broadcast_addr, 0, key); 1030 set_swcam(dev, idx, idx, alg, broadcast_addr, 0, 1031 key, 0); 1032 } else { 1033 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && 1034 ieee->pHTInfo->bCurrentHTSupport) 1035 write_nic_byte(dev, 0x173, 1); 1036 setKey(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, 1037 0, key); 1038 set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, 1039 0, key, 0); 1040 } 1041 1042 1043 } 1044 1045end_hw_sec: 1046 priv->rtllib->wx_set_enc = 0; 1047 up(&priv->wx_sem); 1048 return ret; 1049 1050} 1051static int r8192_wx_set_auth(struct net_device *dev, 1052 struct iw_request_info *info, 1053 union iwreq_data *data, char *extra) 1054{ 1055 int ret = 0; 1056 1057 struct r8192_priv *priv = rtllib_priv(dev); 1058 1059 if (priv->bHwRadioOff == true) 1060 return 0; 1061 1062 down(&priv->wx_sem); 1063 ret = rtllib_wx_set_auth(priv->rtllib, info, &(data->param), extra); 1064 up(&priv->wx_sem); 1065 return ret; 1066} 1067 1068static int r8192_wx_set_mlme(struct net_device *dev, 1069 struct iw_request_info *info, 1070 union iwreq_data *wrqu, char *extra) 1071{ 1072 1073 int ret = 0; 1074 1075 struct r8192_priv *priv = rtllib_priv(dev); 1076 1077 if (priv->bHwRadioOff == true) 1078 return 0; 1079 1080 down(&priv->wx_sem); 1081 ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra); 1082 up(&priv->wx_sem); 1083 return ret; 1084} 1085 1086static int r8192_wx_set_gen_ie(struct net_device *dev, 1087 struct iw_request_info *info, 1088 union iwreq_data *data, char *extra) 1089{ 1090 int ret = 0; 1091 1092 struct r8192_priv *priv = rtllib_priv(dev); 1093 1094 if (priv->bHwRadioOff == true) 1095 return 0; 1096 1097 down(&priv->wx_sem); 1098 ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length); 1099 up(&priv->wx_sem); 1100 return ret; 1101} 1102 1103static int r8192_wx_get_gen_ie(struct net_device *dev, 1104 struct iw_request_info *info, 1105 union iwreq_data *data, char *extra) 1106{ 1107 int ret = 0; 1108 struct r8192_priv *priv = rtllib_priv(dev); 1109 struct rtllib_device *ieee = priv->rtllib; 1110 1111 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { 1112 data->data.length = 0; 1113 return 0; 1114 } 1115 1116 if (data->data.length < ieee->wpa_ie_len) 1117 return -E2BIG; 1118 1119 data->data.length = ieee->wpa_ie_len; 1120 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); 1121 return ret; 1122} 1123 1124#define OID_RT_INTEL_PROMISCUOUS_MODE 0xFF0101F6 1125 1126static int r8192_wx_set_PromiscuousMode(struct net_device *dev, 1127 struct iw_request_info *info, 1128 union iwreq_data *wrqu, char *extra) 1129{ 1130 struct r8192_priv *priv = rtllib_priv(dev); 1131 struct rtllib_device *ieee = priv->rtllib; 1132 1133 u32 *info_buf = (u32 *)(wrqu->data.pointer); 1134 1135 u32 oid = info_buf[0]; 1136 u32 bPromiscuousOn = info_buf[1]; 1137 u32 bFilterSourceStationFrame = info_buf[2]; 1138 1139 if (OID_RT_INTEL_PROMISCUOUS_MODE == oid) { 1140 ieee->IntelPromiscuousModeInfo.bPromiscuousOn = 1141 (bPromiscuousOn) ? (true) : (false); 1142 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame = 1143 (bFilterSourceStationFrame) ? (true) : (false); 1144 (bPromiscuousOn) ? 1145 (rtllib_EnableIntelPromiscuousMode(dev, false)) : 1146 (rtllib_DisableIntelPromiscuousMode(dev, false)); 1147 1148 printk(KERN_INFO "=======>%s(), on = %d, filter src sta = %d\n", 1149 __func__, bPromiscuousOn, bFilterSourceStationFrame); 1150 } else { 1151 return -1; 1152 } 1153 1154 return 0; 1155} 1156 1157 1158static int r8192_wx_get_PromiscuousMode(struct net_device *dev, 1159 struct iw_request_info *info, 1160 union iwreq_data *wrqu, char *extra) 1161{ 1162 struct r8192_priv *priv = rtllib_priv(dev); 1163 struct rtllib_device *ieee = priv->rtllib; 1164 1165 down(&priv->wx_sem); 1166 1167 snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d", 1168 ieee->IntelPromiscuousModeInfo.bPromiscuousOn, 1169 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame); 1170 wrqu->data.length = strlen(extra) + 1; 1171 1172 up(&priv->wx_sem); 1173 1174 return 0; 1175} 1176 1177 1178#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 1179static iw_handler r8192_wx_handlers[] = { 1180 IW_IOCTL(SIOCGIWNAME) = r8192_wx_get_name, 1181 IW_IOCTL(SIOCSIWFREQ) = r8192_wx_set_freq, 1182 IW_IOCTL(SIOCGIWFREQ) = r8192_wx_get_freq, 1183 IW_IOCTL(SIOCSIWMODE) = r8192_wx_set_mode, 1184 IW_IOCTL(SIOCGIWMODE) = r8192_wx_get_mode, 1185 IW_IOCTL(SIOCSIWSENS) = r8192_wx_set_sens, 1186 IW_IOCTL(SIOCGIWSENS) = r8192_wx_get_sens, 1187 IW_IOCTL(SIOCGIWRANGE) = rtl8192_wx_get_range, 1188 IW_IOCTL(SIOCSIWAP) = r8192_wx_set_wap, 1189 IW_IOCTL(SIOCGIWAP) = r8192_wx_get_wap, 1190 IW_IOCTL(SIOCSIWSCAN) = r8192_wx_set_scan, 1191 IW_IOCTL(SIOCGIWSCAN) = r8192_wx_get_scan, 1192 IW_IOCTL(SIOCSIWESSID) = r8192_wx_set_essid, 1193 IW_IOCTL(SIOCGIWESSID) = r8192_wx_get_essid, 1194 IW_IOCTL(SIOCSIWNICKN) = r8192_wx_set_nick, 1195 IW_IOCTL(SIOCGIWNICKN) = r8192_wx_get_nick, 1196 IW_IOCTL(SIOCSIWRATE) = r8192_wx_set_rate, 1197 IW_IOCTL(SIOCGIWRATE) = r8192_wx_get_rate, 1198 IW_IOCTL(SIOCSIWRTS) = r8192_wx_set_rts, 1199 IW_IOCTL(SIOCGIWRTS) = r8192_wx_get_rts, 1200 IW_IOCTL(SIOCSIWFRAG) = r8192_wx_set_frag, 1201 IW_IOCTL(SIOCGIWFRAG) = r8192_wx_get_frag, 1202 IW_IOCTL(SIOCSIWRETRY) = r8192_wx_set_retry, 1203 IW_IOCTL(SIOCGIWRETRY) = r8192_wx_get_retry, 1204 IW_IOCTL(SIOCSIWENCODE) = r8192_wx_set_enc, 1205 IW_IOCTL(SIOCGIWENCODE) = r8192_wx_get_enc, 1206 IW_IOCTL(SIOCSIWPOWER) = r8192_wx_set_power, 1207 IW_IOCTL(SIOCGIWPOWER) = r8192_wx_get_power, 1208 IW_IOCTL(SIOCSIWGENIE) = r8192_wx_set_gen_ie, 1209 IW_IOCTL(SIOCGIWGENIE) = r8192_wx_get_gen_ie, 1210 IW_IOCTL(SIOCSIWMLME) = r8192_wx_set_mlme, 1211 IW_IOCTL(SIOCSIWAUTH) = r8192_wx_set_auth, 1212 IW_IOCTL(SIOCSIWENCODEEXT) = r8192_wx_set_enc_ext, 1213}; 1214 1215/* 1216 * the following rule need to be follwing, 1217 * Odd : get (world access), 1218 * even : set (root access) 1219 * */ 1220static const struct iw_priv_args r8192_private_args[] = { 1221 { 1222 SIOCIWFIRSTPRIV + 0x0, 1223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag" 1224 }, { 1225 SIOCIWFIRSTPRIV + 0x1, 1226 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" 1227 }, { 1228 SIOCIWFIRSTPRIV + 0x2, 1229 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 1230 }, { 1231 SIOCIWFIRSTPRIV + 0x3, 1232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" 1233 }, { 1234 SIOCIWFIRSTPRIV + 0x4, 1235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_mic_error" 1236 }, { 1237 SIOCIWFIRSTPRIV + 0x5, 1238 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1, 1239 "firm_ver" 1240 }, { 1241 SIOCIWFIRSTPRIV + 0x6, 1242 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, 1243 "set_power" 1244 }, { 1245 SIOCIWFIRSTPRIV + 0x9, 1246 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, 1247 "radio" 1248 }, { 1249 SIOCIWFIRSTPRIV + 0xa, 1250 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, 1251 "lps_interv" 1252 }, { 1253 SIOCIWFIRSTPRIV + 0xb, 1254 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, 1255 "lps_force" 1256 }, { 1257 SIOCIWFIRSTPRIV + 0xc, 1258 0, IW_PRIV_TYPE_CHAR|2047, "adhoc_peer_list" 1259 }, { 1260 SIOCIWFIRSTPRIV + 0x16, 1261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc" 1262 }, { 1263 SIOCIWFIRSTPRIV + 0x17, 1264 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc" 1265 } 1266 1267}; 1268 1269static iw_handler r8192_private_handler[] = { 1270 (iw_handler)r8192_wx_set_debugflag, /*SIOCIWSECONDPRIV*/ 1271 (iw_handler)r8192_wx_set_scan_type, 1272 (iw_handler)r8192_wx_set_rawtx, 1273 (iw_handler)r8192_wx_force_reset, 1274 (iw_handler)r8192_wx_force_mic_error, 1275 (iw_handler)r8191se_wx_get_firm_version, 1276 (iw_handler)r8192_wx_adapter_power_status, 1277 (iw_handler)NULL, 1278 (iw_handler)NULL, 1279 (iw_handler)r8192se_wx_set_radio, 1280 (iw_handler)r8192se_wx_set_lps_awake_interval, 1281 (iw_handler)r8192se_wx_set_force_lps, 1282 (iw_handler)r8192_wx_get_adhoc_peers, 1283 (iw_handler)NULL, 1284 (iw_handler)NULL, 1285 (iw_handler)NULL, 1286 (iw_handler)NULL, 1287 (iw_handler)NULL, 1288 (iw_handler)NULL, 1289 (iw_handler)NULL, 1290 (iw_handler)NULL, 1291 (iw_handler)NULL, 1292 (iw_handler)r8192_wx_set_PromiscuousMode, 1293 (iw_handler)r8192_wx_get_PromiscuousMode, 1294}; 1295 1296static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) 1297{ 1298 struct r8192_priv *priv = rtllib_priv(dev); 1299 struct rtllib_device *ieee = priv->rtllib; 1300 struct iw_statistics *wstats = &priv->wstats; 1301 int tmp_level = 0; 1302 int tmp_qual = 0; 1303 int tmp_noise = 0; 1304 if (ieee->state < RTLLIB_LINKED) { 1305 wstats->qual.qual = 10; 1306 wstats->qual.level = 0; 1307 wstats->qual.noise = -100; 1308 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 1309 return wstats; 1310 } 1311 1312 tmp_level = (&ieee->current_network)->stats.rssi; 1313 tmp_qual = (&ieee->current_network)->stats.signal; 1314 tmp_noise = (&ieee->current_network)->stats.noise; 1315 1316 wstats->qual.level = tmp_level; 1317 wstats->qual.qual = tmp_qual; 1318 wstats->qual.noise = tmp_noise; 1319 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 1320 return wstats; 1321} 1322 1323struct iw_handler_def r8192_wx_handlers_def = { 1324 .standard = r8192_wx_handlers, 1325 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), 1326 .private = r8192_private_handler, 1327 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), 1328 .num_private_args = sizeof(r8192_private_args) / 1329 sizeof(struct iw_priv_args), 1330 .get_wireless_stats = r8192_get_wireless_stats, 1331 .private_args = (struct iw_priv_args *)r8192_private_args, 1332}; 1333