1/* 2 This file contains wireless extension handlers. 3 4 This is part of rtl8180 OpenSource driver. 5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> 6 Released under the terms of GPL (General Public Licence) 7 8 Parts of this driver are based on the GPL part 9 of the official realtek driver. 10 11 Parts of this driver are based on the rtl8180 driver skeleton 12 from Patric Schenke & Andres Salomon. 13 14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. 15 16 We want to tanks the Authors of those projects and the Ndiswrapper 17 project Authors. 18*/ 19 20 21#include "r8180.h" 22#include "r8180_hw.h" 23 24#include "ieee80211/dot11d.h" 25 26u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, 27 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; 28 29#define RATE_COUNT ARRAY_SIZE(rtl8180_rates) 30 31static CHANNEL_LIST DefaultChannelPlan[] = { 32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */ 33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */ 34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */ 35 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Spain. Change to ETSI. */ 36 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* France. Change to ETSI. */ 37 {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */ 38 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */ 39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */ 40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */ 41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} /* For Global Domain. 1-11:active scan, 12-14 passive scan.*/ /* +YJ, 080626 */ 42}; 43static int r8180_wx_get_freq(struct net_device *dev, 44 struct iw_request_info *a, 45 union iwreq_data *wrqu, char *b) 46{ 47 struct r8180_priv *priv = ieee80211_priv(dev); 48 49 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b); 50} 51 52 53int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info, 54 union iwreq_data *wrqu, char *key) 55{ 56 struct r8180_priv *priv = ieee80211_priv(dev); 57 struct iw_point *erq = &(wrqu->encoding); 58 59 if (priv->ieee80211->bHwRadioOff) 60 return 0; 61 62 if (erq->flags & IW_ENCODE_DISABLED) 63 64 if (erq->length > 0) { 65 u32* tkey = (u32*) key; 66 priv->key0[0] = tkey[0]; 67 priv->key0[1] = tkey[1]; 68 priv->key0[2] = tkey[2]; 69 priv->key0[3] = tkey[3] & 0xff; 70 DMESG("Setting wep key to %x %x %x %x", 71 tkey[0], tkey[1], tkey[2], tkey[3]); 72 rtl8180_set_hw_wep(dev); 73 } 74 return 0; 75} 76 77 78static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa, 79 union iwreq_data *wrqu, char *b) 80{ 81 int *parms = (int *)b; 82 int bi = parms[0]; 83 84 struct r8180_priv *priv = ieee80211_priv(dev); 85 86 if (priv->ieee80211->bHwRadioOff) 87 return 0; 88 89 down(&priv->wx_sem); 90 DMESG("setting beacon interval to %x", bi); 91 92 priv->ieee80211->current_network.beacon_interval = bi; 93 rtl8180_commit(dev); 94 up(&priv->wx_sem); 95 96 return 0; 97} 98 99 100 101static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a, 102 union iwreq_data *wrqu, char *b) 103{ 104 struct r8180_priv *priv = ieee80211_priv(dev); 105 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b); 106} 107 108 109 110static int r8180_wx_get_rate(struct net_device *dev, 111 struct iw_request_info *info, 112 union iwreq_data *wrqu, char *extra) 113{ 114 struct r8180_priv *priv = ieee80211_priv(dev); 115 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra); 116} 117 118 119 120static int r8180_wx_set_rate(struct net_device *dev, 121 struct iw_request_info *info, 122 union iwreq_data *wrqu, char *extra) 123{ 124 int ret; 125 struct r8180_priv *priv = ieee80211_priv(dev); 126 127 128 if (priv->ieee80211->bHwRadioOff) 129 return 0; 130 131 down(&priv->wx_sem); 132 133 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra); 134 135 up(&priv->wx_sem); 136 137 return ret; 138} 139 140 141static int r8180_wx_set_crcmon(struct net_device *dev, 142 struct iw_request_info *info, 143 union iwreq_data *wrqu, char *extra) 144{ 145 struct r8180_priv *priv = ieee80211_priv(dev); 146 int *parms = (int *)extra; 147 int enable = (parms[0] > 0); 148 short prev = priv->crcmon; 149 150 151 if (priv->ieee80211->bHwRadioOff) 152 return 0; 153 154 down(&priv->wx_sem); 155 156 if (enable) 157 priv->crcmon = 1; 158 else 159 priv->crcmon = 0; 160 161 DMESG("bad CRC in monitor mode are %s", 162 priv->crcmon ? "accepted" : "rejected"); 163 164 if (prev != priv->crcmon && priv->up) { 165 rtl8180_down(dev); 166 rtl8180_up(dev); 167 } 168 169 up(&priv->wx_sem); 170 171 return 0; 172} 173 174 175static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 176 union iwreq_data *wrqu, char *b) 177{ 178 struct r8180_priv *priv = ieee80211_priv(dev); 179 int ret; 180 181 182 if (priv->ieee80211->bHwRadioOff) 183 return 0; 184 185 down(&priv->wx_sem); 186 if (priv->bInactivePs) { 187 if (wrqu->mode == IW_MODE_ADHOC) 188 IPSLeave(dev); 189 } 190 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b); 191 192 up(&priv->wx_sem); 193 return ret; 194} 195 196/* YJ,add,080819,for hidden ap */ 197struct iw_range_with_scan_capa { 198 /* Informative stuff (to choose between different interface) */ 199 200 __u32 throughput; /* To give an idea... */ 201 202 /* In theory this value should be the maximum benchmarked 203 * TCP/IP throughput, because with most of these devices the 204 * bit rate is meaningless (overhead an co) to estimate how 205 * fast the connection will go and pick the fastest one. 206 * I suggest people to play with Netperf or any benchmark... 207 */ 208 209 /* NWID (or domain id) */ 210 __u32 min_nwid; /* Minimal NWID we are able to set */ 211 __u32 max_nwid; /* Maximal NWID we are able to set */ 212 213 /* Old Frequency (backward compat - moved lower ) */ 214 __u16 old_num_channels; 215 __u8 old_num_frequency; 216 217 /* Scan capabilities */ 218 __u8 scan_capa; 219}; 220/* YJ,add,080819,for hidden ap */ 221 222 223static int rtl8180_wx_get_range(struct net_device *dev, 224 struct iw_request_info *info, 225 union iwreq_data *wrqu, char *extra) 226{ 227 struct iw_range *range = (struct iw_range *)extra; 228 struct r8180_priv *priv = ieee80211_priv(dev); 229 u16 val; 230 int i; 231 232 wrqu->data.length = sizeof(*range); 233 memset(range, 0, sizeof(*range)); 234 235 /* Let's try to keep this struct in the same order as in 236 * linux/include/wireless.h 237 */ 238 239 /* TODO: See what values we can set, and remove the ones we can't 240 * set, or fill them with some default data. 241 */ 242 243 /* ~5 Mb/s real (802.11b) */ 244 range->throughput = 5 * 1000 * 1000; 245 246 /* TODO: Not used in 802.11b? */ 247/* range->min_nwid; */ /* Minimal NWID we are able to set */ 248 /* TODO: Not used in 802.11b? */ 249/* range->max_nwid; */ /* Maximal NWID we are able to set */ 250 251 /* Old Frequency (backward compat - moved lower ) */ 252/* range->old_num_channels; */ 253/* range->old_num_frequency; */ 254/* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */ 255 if (priv->rf_set_sens != NULL) 256 range->sensitivity = priv->max_sens; /* signal level threshold range */ 257 258 range->max_qual.qual = 100; 259 /* TODO: Find real max RSSI and stick here */ 260 range->max_qual.level = 0; 261 range->max_qual.noise = -98; 262 range->max_qual.updated = 7; /* Updated all three */ 263 264 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 265 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ 266 range->avg_qual.level = 20 + -98; 267 range->avg_qual.noise = 0; 268 range->avg_qual.updated = 7; /* Updated all three */ 269 270 range->num_bitrates = RATE_COUNT; 271 272 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) 273 range->bitrate[i] = rtl8180_rates[i]; 274 275 range->min_frag = MIN_FRAG_THRESHOLD; 276 range->max_frag = MAX_FRAG_THRESHOLD; 277 278 range->pm_capa = 0; 279 280 range->we_version_compiled = WIRELESS_EXT; 281 range->we_version_source = 16; 282 283 range->num_channels = 14; 284 285 for (i = 0, val = 0; i < 14; i++) { 286 287 /* Include only legal frequencies for some countries */ 288 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { 289 range->freq[val].i = i + 1; 290 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; 291 range->freq[val].e = 1; 292 val++; 293 } else { 294 /* FIXME: do we need to set anything for channels */ 295 /* we don't use ? */ 296 } 297 298 if (val == IW_MAX_FREQUENCIES) 299 break; 300 } 301 302 range->num_frequency = val; 303 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 304 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 305 306 return 0; 307} 308 309 310static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 311 union iwreq_data *wrqu, char *b) 312{ 313 struct r8180_priv *priv = ieee80211_priv(dev); 314 int ret; 315 struct ieee80211_device* ieee = priv->ieee80211; 316 317 318 if (priv->ieee80211->bHwRadioOff) 319 return 0; 320 321 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 322 struct iw_scan_req* req = (struct iw_scan_req*)b; 323 if (req->essid_len) { 324 ieee->current_network.ssid_len = req->essid_len; 325 memcpy(ieee->current_network.ssid, req->essid, req->essid_len); 326 } 327 } 328 329 down(&priv->wx_sem); 330 if (priv->up) { 331 priv->ieee80211->actscanning = true; 332 if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) { 333 IPSLeave(dev); 334 ieee80211_softmac_ips_scan_syncro(priv->ieee80211); 335 ret = 0; 336 } else { 337 /* prevent scan in BusyTraffic */ 338 /* FIXME: Need to consider last scan time */ 339 if ((priv->link_detect.bBusyTraffic) && (true)) { 340 ret = 0; 341 printk("Now traffic is busy, please try later!\n"); 342 } else 343 /* prevent scan in BusyTraffic,end */ 344 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b); 345 } 346 } else 347 ret = -1; 348 349 up(&priv->wx_sem); 350 351 return ret; 352} 353 354 355static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 356 union iwreq_data *wrqu, char *b) 357{ 358 359 int ret; 360 struct r8180_priv *priv = ieee80211_priv(dev); 361 362 down(&priv->wx_sem); 363 if (priv->up) 364 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b); 365 else 366 ret = -1; 367 368 up(&priv->wx_sem); 369 return ret; 370} 371 372 373static int r8180_wx_set_essid(struct net_device *dev, 374 struct iw_request_info *a, 375 union iwreq_data *wrqu, char *b) 376{ 377 struct r8180_priv *priv = ieee80211_priv(dev); 378 379 int ret; 380 381 if (priv->ieee80211->bHwRadioOff) 382 return 0; 383 384 down(&priv->wx_sem); 385 if (priv->bInactivePs) 386 IPSLeave(dev); 387 388 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b); 389 390 up(&priv->wx_sem); 391 return ret; 392} 393 394 395static int r8180_wx_get_essid(struct net_device *dev, 396 struct iw_request_info *a, 397 union iwreq_data *wrqu, char *b) 398{ 399 int ret; 400 struct r8180_priv *priv = ieee80211_priv(dev); 401 402 down(&priv->wx_sem); 403 404 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); 405 406 up(&priv->wx_sem); 407 408 return ret; 409} 410 411 412static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a, 413 union iwreq_data *wrqu, char *b) 414{ 415 int ret; 416 struct r8180_priv *priv = ieee80211_priv(dev); 417 418 419 if (priv->ieee80211->bHwRadioOff) 420 return 0; 421 422 down(&priv->wx_sem); 423 424 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); 425 426 up(&priv->wx_sem); 427 return ret; 428} 429 430 431static int r8180_wx_get_name(struct net_device *dev, 432 struct iw_request_info *info, 433 union iwreq_data *wrqu, char *extra) 434{ 435 struct r8180_priv *priv = ieee80211_priv(dev); 436 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); 437} 438 439static int r8180_wx_set_frag(struct net_device *dev, 440 struct iw_request_info *info, 441 union iwreq_data *wrqu, char *extra) 442{ 443 struct r8180_priv *priv = ieee80211_priv(dev); 444 445 if (priv->ieee80211->bHwRadioOff) 446 return 0; 447 448 if (wrqu->frag.disabled) 449 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; 450 else { 451 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 452 wrqu->frag.value > MAX_FRAG_THRESHOLD) 453 return -EINVAL; 454 455 priv->ieee80211->fts = wrqu->frag.value & ~0x1; 456 } 457 458 return 0; 459} 460 461 462static int r8180_wx_get_frag(struct net_device *dev, 463 struct iw_request_info *info, 464 union iwreq_data *wrqu, char *extra) 465{ 466 struct r8180_priv *priv = ieee80211_priv(dev); 467 468 wrqu->frag.value = priv->ieee80211->fts; 469 wrqu->frag.fixed = 0; /* no auto select */ 470 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); 471 472 return 0; 473} 474 475 476static int r8180_wx_set_wap(struct net_device *dev, 477 struct iw_request_info *info, 478 union iwreq_data *awrq, 479 char *extra) 480{ 481 int ret; 482 struct r8180_priv *priv = ieee80211_priv(dev); 483 484 if (priv->ieee80211->bHwRadioOff) 485 return 0; 486 487 down(&priv->wx_sem); 488 489 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra); 490 491 up(&priv->wx_sem); 492 return ret; 493 494} 495 496 497static int r8180_wx_get_wap(struct net_device *dev, 498 struct iw_request_info *info, 499 union iwreq_data *wrqu, char *extra) 500{ 501 struct r8180_priv *priv = ieee80211_priv(dev); 502 503 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra); 504} 505 506 507static int r8180_wx_set_enc(struct net_device *dev, 508 struct iw_request_info *info, 509 union iwreq_data *wrqu, char *key) 510{ 511 struct r8180_priv *priv = ieee80211_priv(dev); 512 int ret; 513 514 if (priv->ieee80211->bHwRadioOff) 515 return 0; 516 517 518 down(&priv->wx_sem); 519 520 if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key); 521 else { 522 DMESG("Setting SW wep key"); 523 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key); 524 } 525 526 up(&priv->wx_sem); 527 return ret; 528} 529 530 531static int r8180_wx_get_enc(struct net_device *dev, 532 struct iw_request_info *info, 533 union iwreq_data *wrqu, char *key) 534{ 535 struct r8180_priv *priv = ieee80211_priv(dev); 536 537 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); 538} 539 540 541static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union 542 iwreq_data *wrqu, char *p) { 543 544 struct r8180_priv *priv = ieee80211_priv(dev); 545 int *parms = (int*)p; 546 int mode = parms[0]; 547 548 if (priv->ieee80211->bHwRadioOff) 549 return 0; 550 551 priv->ieee80211->active_scan = mode; 552 553 return 1; 554} 555 556static int r8180_wx_set_retry(struct net_device *dev, 557 struct iw_request_info *info, 558 union iwreq_data *wrqu, char *extra) 559{ 560 struct r8180_priv *priv = ieee80211_priv(dev); 561 int err = 0; 562 563 if (priv->ieee80211->bHwRadioOff) 564 return 0; 565 566 down(&priv->wx_sem); 567 568 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 569 wrqu->retry.disabled) { 570 err = -EINVAL; 571 goto exit; 572 } 573 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { 574 err = -EINVAL; 575 goto exit; 576 } 577 578 if (wrqu->retry.value > R8180_MAX_RETRY) { 579 err = -EINVAL; 580 goto exit; 581 } 582 if (wrqu->retry.flags & IW_RETRY_MAX) { 583 priv->retry_rts = wrqu->retry.value; 584 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); 585 586 } else { 587 priv->retry_data = wrqu->retry.value; 588 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); 589 } 590 591 /* FIXME ! 592 * We might try to write directly the TX config register 593 * or to restart just the (R)TX process. 594 * I'm unsure if whole reset is really needed 595 */ 596 597 rtl8180_commit(dev); 598exit: 599 up(&priv->wx_sem); 600 601 return err; 602} 603 604static int r8180_wx_get_retry(struct net_device *dev, 605 struct iw_request_info *info, 606 union iwreq_data *wrqu, char *extra) 607{ 608 struct r8180_priv *priv = ieee80211_priv(dev); 609 610 611 wrqu->retry.disabled = 0; /* can't be disabled */ 612 613 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 614 IW_RETRY_LIFETIME) 615 return -EINVAL; 616 617 if (wrqu->retry.flags & IW_RETRY_MAX) { 618 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 619 wrqu->retry.value = priv->retry_rts; 620 } else { 621 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; 622 wrqu->retry.value = priv->retry_data; 623 } 624 625 return 0; 626} 627 628static int r8180_wx_get_sens(struct net_device *dev, 629 struct iw_request_info *info, 630 union iwreq_data *wrqu, char *extra) 631{ 632 struct r8180_priv *priv = ieee80211_priv(dev); 633 if (priv->rf_set_sens == NULL) 634 return -1; /* we have not this support for this radio */ 635 wrqu->sens.value = priv->sens; 636 return 0; 637} 638 639 640static int r8180_wx_set_sens(struct net_device *dev, 641 struct iw_request_info *info, 642 union iwreq_data *wrqu, char *extra) 643{ 644 645 struct r8180_priv *priv = ieee80211_priv(dev); 646 647 short err = 0; 648 649 if (priv->ieee80211->bHwRadioOff) 650 return 0; 651 652 down(&priv->wx_sem); 653 if (priv->rf_set_sens == NULL) { 654 err = -1; /* we have not this support for this radio */ 655 goto exit; 656 } 657 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) 658 priv->sens = wrqu->sens.value; 659 else 660 err = -EINVAL; 661 662exit: 663 up(&priv->wx_sem); 664 665 return err; 666} 667 668 669static int r8180_wx_set_rawtx(struct net_device *dev, 670 struct iw_request_info *info, 671 union iwreq_data *wrqu, char *extra) 672{ 673 struct r8180_priv *priv = ieee80211_priv(dev); 674 int ret; 675 676 if (priv->ieee80211->bHwRadioOff) 677 return 0; 678 679 down(&priv->wx_sem); 680 681 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); 682 683 up(&priv->wx_sem); 684 685 return ret; 686 687} 688 689static int r8180_wx_get_power(struct net_device *dev, 690 struct iw_request_info *info, 691 union iwreq_data *wrqu, char *extra) 692{ 693 int ret; 694 struct r8180_priv *priv = ieee80211_priv(dev); 695 696 down(&priv->wx_sem); 697 698 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra); 699 700 up(&priv->wx_sem); 701 702 return ret; 703} 704 705static int r8180_wx_set_power(struct net_device *dev, 706 struct iw_request_info *info, 707 union iwreq_data *wrqu, char *extra) 708{ 709 int ret; 710 struct r8180_priv *priv = ieee80211_priv(dev); 711 712 713 if (priv->ieee80211->bHwRadioOff) 714 return 0; 715 716 down(&priv->wx_sem); 717 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags); 718 if (wrqu->power.disabled == 0) { 719 wrqu->power.flags |= IW_POWER_ALL_R; 720 wrqu->power.flags |= IW_POWER_TIMEOUT; 721 wrqu->power.value = 1000; 722 } 723 724 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra); 725 726 up(&priv->wx_sem); 727 728 return ret; 729} 730 731static int r8180_wx_set_rts(struct net_device *dev, 732 struct iw_request_info *info, 733 union iwreq_data *wrqu, char *extra) 734{ 735 struct r8180_priv *priv = ieee80211_priv(dev); 736 737 738 if (priv->ieee80211->bHwRadioOff) 739 return 0; 740 741 if (wrqu->rts.disabled) 742 priv->rts = DEFAULT_RTS_THRESHOLD; 743 else { 744 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 745 wrqu->rts.value > MAX_RTS_THRESHOLD) 746 return -EINVAL; 747 748 priv->rts = wrqu->rts.value; 749 } 750 751 return 0; 752} 753static int r8180_wx_get_rts(struct net_device *dev, 754 struct iw_request_info *info, 755 union iwreq_data *wrqu, char *extra) 756{ 757 struct r8180_priv *priv = ieee80211_priv(dev); 758 759 760 761 wrqu->rts.value = priv->rts; 762 wrqu->rts.fixed = 0; /* no auto select */ 763 wrqu->rts.disabled = (wrqu->rts.value == 0); 764 765 return 0; 766} 767static int dummy(struct net_device *dev, struct iw_request_info *a, 768 union iwreq_data *wrqu, char *b) 769{ 770 return -1; 771} 772 773static int r8180_wx_get_iwmode(struct net_device *dev, 774 struct iw_request_info *info, 775 union iwreq_data *wrqu, char *extra) 776{ 777 struct r8180_priv *priv = ieee80211_priv(dev); 778 struct ieee80211_device *ieee; 779 int ret = 0; 780 781 782 783 down(&priv->wx_sem); 784 785 ieee = priv->ieee80211; 786 787 strcpy(extra, "802.11"); 788 if (ieee->modulation & IEEE80211_CCK_MODULATION) { 789 strcat(extra, "b"); 790 if (ieee->modulation & IEEE80211_OFDM_MODULATION) 791 strcat(extra, "/g"); 792 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) 793 strcat(extra, "g"); 794 795 up(&priv->wx_sem); 796 797 return ret; 798} 799static int r8180_wx_set_iwmode(struct net_device *dev, 800 struct iw_request_info *info, 801 union iwreq_data *wrqu, char *extra) 802{ 803 struct r8180_priv *priv = ieee80211_priv(dev); 804 struct ieee80211_device *ieee = priv->ieee80211; 805 int *param = (int *)extra; 806 int ret = 0; 807 int modulation = 0, mode = 0; 808 809 810 if (priv->ieee80211->bHwRadioOff) 811 return 0; 812 813 down(&priv->wx_sem); 814 815 if (*param == 1) { 816 modulation |= IEEE80211_CCK_MODULATION; 817 mode = IEEE_B; 818 printk(KERN_INFO "B mode!\n"); 819 } else if (*param == 2) { 820 modulation |= IEEE80211_OFDM_MODULATION; 821 mode = IEEE_G; 822 printk(KERN_INFO "G mode!\n"); 823 } else if (*param == 3) { 824 modulation |= IEEE80211_CCK_MODULATION; 825 modulation |= IEEE80211_OFDM_MODULATION; 826 mode = IEEE_B|IEEE_G; 827 printk(KERN_INFO "B/G mode!\n"); 828 } 829 830 if (ieee->proto_started) { 831 ieee80211_stop_protocol(ieee); 832 ieee->mode = mode; 833 ieee->modulation = modulation; 834 ieee80211_start_protocol(ieee); 835 } else { 836 ieee->mode = mode; 837 ieee->modulation = modulation; 838 } 839 840 up(&priv->wx_sem); 841 842 return ret; 843} 844static int r8180_wx_get_preamble(struct net_device *dev, 845 struct iw_request_info *info, 846 union iwreq_data *wrqu, char *extra) 847{ 848 struct r8180_priv *priv = ieee80211_priv(dev); 849 850 851 852 down(&priv->wx_sem); 853 854 855 856 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */ 857 up(&priv->wx_sem); 858 859 return 0; 860} 861static int r8180_wx_set_preamble(struct net_device *dev, 862 struct iw_request_info *info, 863 union iwreq_data *wrqu, char *extra) 864{ 865 struct r8180_priv *priv = ieee80211_priv(dev); 866 int ret = 0; 867 868 869 if (priv->ieee80211->bHwRadioOff) 870 return 0; 871 872 down(&priv->wx_sem); 873 if (*extra < 0 || *extra > 2) 874 ret = -1; 875 else 876 priv->plcp_preamble_mode = *((short *)extra) ; 877 878 879 880 up(&priv->wx_sem); 881 882 return ret; 883} 884static int r8180_wx_get_siglevel(struct net_device *dev, 885 struct iw_request_info *info, 886 union iwreq_data *wrqu, char *extra) 887{ 888 struct r8180_priv *priv = ieee80211_priv(dev); 889 int ret = 0; 890 891 892 893 down(&priv->wx_sem); 894 /* Modify by hikaru 6.5 */ 895 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */ 896 897 898 899 up(&priv->wx_sem); 900 901 return ret; 902} 903static int r8180_wx_get_sigqual(struct net_device *dev, 904 struct iw_request_info *info, 905 union iwreq_data *wrqu, char *extra) 906{ 907 struct r8180_priv *priv = ieee80211_priv(dev); 908 int ret = 0; 909 910 911 912 down(&priv->wx_sem); 913 /* Modify by hikaru 6.5 */ 914 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */ 915 916 917 918 up(&priv->wx_sem); 919 920 return ret; 921} 922static int r8180_wx_reset_stats(struct net_device *dev, 923 struct iw_request_info *info, 924 union iwreq_data *wrqu, char *extra) 925{ 926 struct r8180_priv *priv = ieee80211_priv(dev); 927 down(&priv->wx_sem); 928 929 priv->stats.txrdu = 0; 930 priv->stats.rxrdu = 0; 931 priv->stats.rxnolast = 0; 932 priv->stats.rxnodata = 0; 933 priv->stats.rxnopointer = 0; 934 priv->stats.txnperr = 0; 935 priv->stats.txresumed = 0; 936 priv->stats.rxerr = 0; 937 priv->stats.rxoverflow = 0; 938 priv->stats.rxint = 0; 939 940 priv->stats.txnpokint = 0; 941 priv->stats.txhpokint = 0; 942 priv->stats.txhperr = 0; 943 priv->stats.ints = 0; 944 priv->stats.shints = 0; 945 priv->stats.txoverflow = 0; 946 priv->stats.rxdmafail = 0; 947 priv->stats.txbeacon = 0; 948 priv->stats.txbeaconerr = 0; 949 priv->stats.txlpokint = 0; 950 priv->stats.txlperr = 0; 951 priv->stats.txretry = 0;/* 20060601 */ 952 priv->stats.rxcrcerrmin = 0 ; 953 priv->stats.rxcrcerrmid = 0; 954 priv->stats.rxcrcerrmax = 0; 955 priv->stats.rxicverr = 0; 956 957 up(&priv->wx_sem); 958 959 return 0; 960 961} 962static int r8180_wx_radio_on(struct net_device *dev, 963 struct iw_request_info *info, 964 union iwreq_data *wrqu, char *extra) 965{ 966 struct r8180_priv *priv = ieee80211_priv(dev); 967 968 if (priv->ieee80211->bHwRadioOff) 969 return 0; 970 971 972 down(&priv->wx_sem); 973 priv->rf_wakeup(dev); 974 975 up(&priv->wx_sem); 976 977 return 0; 978 979} 980 981static int r8180_wx_radio_off(struct net_device *dev, 982 struct iw_request_info *info, 983 union iwreq_data *wrqu, char *extra) 984{ 985 struct r8180_priv *priv = ieee80211_priv(dev); 986 987 if (priv->ieee80211->bHwRadioOff) 988 return 0; 989 990 991 down(&priv->wx_sem); 992 priv->rf_sleep(dev); 993 994 up(&priv->wx_sem); 995 996 return 0; 997 998} 999static int r8180_wx_get_channelplan(struct net_device *dev, 1000 struct iw_request_info *info, 1001 union iwreq_data *wrqu, char *extra) 1002{ 1003 struct r8180_priv *priv = ieee80211_priv(dev); 1004 1005 1006 1007 down(&priv->wx_sem); 1008 *extra = priv->channel_plan; 1009 1010 1011 1012 up(&priv->wx_sem); 1013 1014 return 0; 1015} 1016static int r8180_wx_set_channelplan(struct net_device *dev, 1017 struct iw_request_info *info, 1018 union iwreq_data *wrqu, char *extra) 1019{ 1020 struct r8180_priv *priv = ieee80211_priv(dev); 1021 int *val = (int *)extra; 1022 int i; 1023 printk("-----in fun %s\n", __func__); 1024 1025 if (priv->ieee80211->bHwRadioOff) 1026 return 0; 1027 1028 /* unsigned long flags; */ 1029 down(&priv->wx_sem); 1030 if (DefaultChannelPlan[*val].Len != 0) { 1031 priv->channel_plan = *val; 1032 /* Clear old channel map 8 */ 1033 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) 1034 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0; 1035 1036 /* Set new channel map */ 1037 for (i = 1; i <= DefaultChannelPlan[*val].Len; i++) 1038 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1; 1039 1040 } 1041 up(&priv->wx_sem); 1042 1043 return 0; 1044} 1045 1046static int r8180_wx_get_version(struct net_device *dev, 1047 struct iw_request_info *info, 1048 union iwreq_data *wrqu, char *extra) 1049{ 1050 struct r8180_priv *priv = ieee80211_priv(dev); 1051 /* struct ieee80211_device *ieee; */ 1052 1053 down(&priv->wx_sem); 1054 strcpy(extra, "1020.0808"); 1055 up(&priv->wx_sem); 1056 1057 return 0; 1058} 1059 1060/* added by amy 080818 */ 1061/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */ 1062static int r8180_wx_set_forcerate(struct net_device *dev, 1063 struct iw_request_info *info, 1064 union iwreq_data *wrqu, char *extra) 1065{ 1066 struct r8180_priv *priv = ieee80211_priv(dev); 1067 u8 forcerate = *extra; 1068 1069 down(&priv->wx_sem); 1070 1071 printk("==============>%s(): forcerate is %d\n", __func__, forcerate); 1072 if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) || 1073 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) || 1074 (forcerate == 96) || (forcerate == 108)) 1075 { 1076 priv->ForcedDataRate = 1; 1077 priv->ieee80211->rate = forcerate * 5; 1078 } else if (forcerate == 0) { 1079 priv->ForcedDataRate = 0; 1080 printk("OK! return rate adaptive\n"); 1081 } else 1082 printk("ERR: wrong rate\n"); 1083 up(&priv->wx_sem); 1084 return 0; 1085} 1086 1087static int r8180_wx_set_enc_ext(struct net_device *dev, 1088 struct iw_request_info *info, 1089 union iwreq_data *wrqu, char *extra) 1090{ 1091 1092 struct r8180_priv *priv = ieee80211_priv(dev); 1093 1094 int ret = 0; 1095 1096 if (priv->ieee80211->bHwRadioOff) 1097 return 0; 1098 1099 down(&priv->wx_sem); 1100 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); 1101 up(&priv->wx_sem); 1102 return ret; 1103 1104} 1105static int r8180_wx_set_auth(struct net_device *dev, 1106 struct iw_request_info *info, 1107 union iwreq_data *wrqu, char *extra) 1108{ 1109 struct r8180_priv *priv = ieee80211_priv(dev); 1110 int ret = 0; 1111 1112 if (priv->ieee80211->bHwRadioOff) 1113 return 0; 1114 1115 down(&priv->wx_sem); 1116 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra); 1117 up(&priv->wx_sem); 1118 return ret; 1119} 1120 1121static int r8180_wx_set_mlme(struct net_device *dev, 1122 struct iw_request_info *info, 1123 union iwreq_data *wrqu, char *extra) 1124{ 1125 int ret = 0; 1126 struct r8180_priv *priv = ieee80211_priv(dev); 1127 1128 1129 if (priv->ieee80211->bHwRadioOff) 1130 return 0; 1131 1132 1133 down(&priv->wx_sem); 1134#if 1 1135 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); 1136#endif 1137 up(&priv->wx_sem); 1138 return ret; 1139} 1140static int r8180_wx_set_gen_ie(struct net_device *dev, 1141 struct iw_request_info *info, 1142 union iwreq_data *wrqu, char *extra) 1143{ 1144 int ret = 0; 1145 struct r8180_priv *priv = ieee80211_priv(dev); 1146 1147 1148 if (priv->ieee80211->bHwRadioOff) 1149 return 0; 1150 1151 down(&priv->wx_sem); 1152#if 1 1153 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length); 1154#endif 1155 up(&priv->wx_sem); 1156 return ret; 1157 1158 1159} 1160static iw_handler r8180_wx_handlers[] = { 1161 NULL, /* SIOCSIWCOMMIT */ 1162 r8180_wx_get_name, /* SIOCGIWNAME */ 1163 dummy, /* SIOCSIWNWID */ 1164 dummy, /* SIOCGIWNWID */ 1165 r8180_wx_set_freq, /* SIOCSIWFREQ */ 1166 r8180_wx_get_freq, /* SIOCGIWFREQ */ 1167 r8180_wx_set_mode, /* SIOCSIWMODE */ 1168 r8180_wx_get_mode, /* SIOCGIWMODE */ 1169 r8180_wx_set_sens, /* SIOCSIWSENS */ 1170 r8180_wx_get_sens, /* SIOCGIWSENS */ 1171 NULL, /* SIOCSIWRANGE */ 1172 rtl8180_wx_get_range, /* SIOCGIWRANGE */ 1173 NULL, /* SIOCSIWPRIV */ 1174 NULL, /* SIOCGIWPRIV */ 1175 NULL, /* SIOCSIWSTATS */ 1176 NULL, /* SIOCGIWSTATS */ 1177 dummy, /* SIOCSIWSPY */ 1178 dummy, /* SIOCGIWSPY */ 1179 NULL, /* SIOCGIWTHRSPY */ 1180 NULL, /* SIOCWIWTHRSPY */ 1181 r8180_wx_set_wap, /* SIOCSIWAP */ 1182 r8180_wx_get_wap, /* SIOCGIWAP */ 1183 r8180_wx_set_mlme, /* SIOCSIWMLME*/ 1184 dummy, /* SIOCGIWAPLIST -- depricated */ 1185 r8180_wx_set_scan, /* SIOCSIWSCAN */ 1186 r8180_wx_get_scan, /* SIOCGIWSCAN */ 1187 r8180_wx_set_essid, /* SIOCSIWESSID */ 1188 r8180_wx_get_essid, /* SIOCGIWESSID */ 1189 dummy, /* SIOCSIWNICKN */ 1190 dummy, /* SIOCGIWNICKN */ 1191 NULL, /* -- hole -- */ 1192 NULL, /* -- hole -- */ 1193 r8180_wx_set_rate, /* SIOCSIWRATE */ 1194 r8180_wx_get_rate, /* SIOCGIWRATE */ 1195 r8180_wx_set_rts, /* SIOCSIWRTS */ 1196 r8180_wx_get_rts, /* SIOCGIWRTS */ 1197 r8180_wx_set_frag, /* SIOCSIWFRAG */ 1198 r8180_wx_get_frag, /* SIOCGIWFRAG */ 1199 dummy, /* SIOCSIWTXPOW */ 1200 dummy, /* SIOCGIWTXPOW */ 1201 r8180_wx_set_retry, /* SIOCSIWRETRY */ 1202 r8180_wx_get_retry, /* SIOCGIWRETRY */ 1203 r8180_wx_set_enc, /* SIOCSIWENCODE */ 1204 r8180_wx_get_enc, /* SIOCGIWENCODE */ 1205 r8180_wx_set_power, /* SIOCSIWPOWER */ 1206 r8180_wx_get_power, /* SIOCGIWPOWER */ 1207 NULL, /*---hole---*/ 1208 NULL, /*---hole---*/ 1209 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */ 1210 NULL, /* SIOCSIWGENIE */ 1211 r8180_wx_set_auth, /* SIOCSIWAUTH */ 1212 NULL, /* SIOCSIWAUTH */ 1213 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 1214 NULL, /* SIOCSIWENCODEEXT */ 1215 NULL, /* SIOCSIWPMKSA */ 1216 NULL, /*---hole---*/ 1217}; 1218 1219 1220static const struct iw_priv_args r8180_private_args[] = { 1221 { 1222 SIOCIWFIRSTPRIV + 0x0, 1223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" 1224 }, 1225 { SIOCIWFIRSTPRIV + 0x1, 1226 0, 0, "dummy" 1227 1228 }, 1229 { 1230 SIOCIWFIRSTPRIV + 0x2, 1231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint" 1232 }, 1233 { SIOCIWFIRSTPRIV + 0x3, 1234 0, 0, "dummy" 1235 1236 }, 1237 { 1238 SIOCIWFIRSTPRIV + 0x4, 1239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" 1240 1241 }, 1242 { SIOCIWFIRSTPRIV + 0x5, 1243 0, 0, "dummy" 1244 1245 }, 1246 { 1247 SIOCIWFIRSTPRIV + 0x6, 1248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 1249 1250 }, 1251 { SIOCIWFIRSTPRIV + 0x7, 1252 0, 0, "dummy" 1253 1254 }, 1255 { 1256 SIOCIWFIRSTPRIV + 0x8, 1257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode" 1258 }, 1259 { 1260 SIOCIWFIRSTPRIV + 0x9, 1261 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode" 1262 }, 1263 { 1264 SIOCIWFIRSTPRIV + 0xA, 1265 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble" 1266 }, 1267 { 1268 SIOCIWFIRSTPRIV + 0xB, 1269 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble" 1270 }, 1271 { SIOCIWFIRSTPRIV + 0xC, 1272 0, 0, "dummy" 1273 }, 1274 { 1275 SIOCIWFIRSTPRIV + 0xD, 1276 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi" 1277 }, 1278 { SIOCIWFIRSTPRIV + 0xE, 1279 0, 0, "dummy" 1280 }, 1281 { 1282 SIOCIWFIRSTPRIV + 0xF, 1283 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual" 1284 }, 1285 { 1286 SIOCIWFIRSTPRIV + 0x10, 1287 0, 0, "resetstats" 1288 }, 1289 { 1290 SIOCIWFIRSTPRIV + 0x11, 1291 0, 0, "dummy" 1292 }, 1293 { 1294 SIOCIWFIRSTPRIV + 0x12, 1295 0, 0, "radioon" 1296 }, 1297 { 1298 SIOCIWFIRSTPRIV + 0x13, 1299 0, 0, "radiooff" 1300 }, 1301 { 1302 SIOCIWFIRSTPRIV + 0x14, 1303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel" 1304 }, 1305 { 1306 SIOCIWFIRSTPRIV + 0x15, 1307 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" 1308 }, 1309 { 1310 SIOCIWFIRSTPRIV + 0x16, 1311 0, 0, "dummy" 1312 }, 1313 { 1314 SIOCIWFIRSTPRIV + 0x17, 1315 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion" 1316 }, 1317 { 1318 SIOCIWFIRSTPRIV + 0x18, 1319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate" 1320 }, 1321}; 1322 1323 1324static iw_handler r8180_private_handler[] = { 1325 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ 1326 dummy, 1327 r8180_wx_set_beaconinterval, 1328 dummy, 1329 /* r8180_wx_set_monitor_type, */ 1330 r8180_wx_set_scan_type, 1331 dummy, 1332 r8180_wx_set_rawtx, 1333 dummy, 1334 r8180_wx_set_iwmode, 1335 r8180_wx_get_iwmode, 1336 r8180_wx_set_preamble, 1337 r8180_wx_get_preamble, 1338 dummy, 1339 r8180_wx_get_siglevel, 1340 dummy, 1341 r8180_wx_get_sigqual, 1342 r8180_wx_reset_stats, 1343 dummy,/* r8180_wx_get_stats */ 1344 r8180_wx_radio_on, 1345 r8180_wx_radio_off, 1346 r8180_wx_set_channelplan, 1347 r8180_wx_get_channelplan, 1348 dummy, 1349 r8180_wx_get_version, 1350 r8180_wx_set_forcerate, 1351}; 1352 1353static inline int is_same_network(struct ieee80211_network *src, 1354 struct ieee80211_network *dst, 1355 struct ieee80211_device *ieee) 1356{ 1357 /* A network is only a duplicate if the channel, BSSID, ESSID 1358 * and the capability field (in particular IBSS and BSS) all match. 1359 * We treat all <hidden> with the same BSSID and channel 1360 * as one network 1361 */ 1362 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */ 1363 (src->channel == dst->channel) && 1364 !memcmp(src->bssid, dst->bssid, ETH_ALEN) && 1365 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */ 1366 ((src->capability & WLAN_CAPABILITY_IBSS) == 1367 (dst->capability & WLAN_CAPABILITY_IBSS)) && 1368 ((src->capability & WLAN_CAPABILITY_BSS) == 1369 (dst->capability & WLAN_CAPABILITY_BSS))); 1370} 1371 1372/* WB modefied to show signal to GUI on 18-01-2008 */ 1373static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) 1374{ 1375 struct r8180_priv *priv = ieee80211_priv(dev); 1376 struct ieee80211_device* ieee = priv->ieee80211; 1377 struct iw_statistics* wstats = &priv->wstats; 1378 int tmp_level = 0; 1379 int tmp_qual = 0; 1380 int tmp_noise = 0; 1381 1382 if (ieee->state < IEEE80211_LINKED) { 1383 wstats->qual.qual = 0; 1384 wstats->qual.level = 0; 1385 wstats->qual.noise = 0; 1386 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 1387 return wstats; 1388 } 1389 1390 tmp_level = (&ieee->current_network)->stats.signal; 1391 tmp_qual = (&ieee->current_network)->stats.signalstrength; 1392 tmp_noise = (&ieee->current_network)->stats.noise; 1393 1394 wstats->qual.level = tmp_level; 1395 wstats->qual.qual = tmp_qual; 1396 wstats->qual.noise = tmp_noise; 1397 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 1398 return wstats; 1399} 1400 1401struct iw_handler_def r8180_wx_handlers_def = { 1402 .standard = r8180_wx_handlers, 1403 .num_standard = ARRAY_SIZE(r8180_wx_handlers), 1404 .private = r8180_private_handler, 1405 .num_private = ARRAY_SIZE(r8180_private_handler), 1406 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args), 1407 .get_wireless_stats = r8180_get_wireless_stats, 1408 .private_args = (struct iw_priv_args *)r8180_private_args, 1409}; 1410 1411 1412