1/****************************************************************************** 2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. 3 * Linux device driver for RTL8192U 4 * 5 * This program is distributed in the hope that it will be useful, but WITHOUT 6 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 8 * more details. 9 * 10 * You should have received a copy of the GNU General Public License along with 11 * this program; if not, write to the Free Software Foundation, Inc., 12 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 13 * 14 * The full GNU General Public License is included in this distribution in the 15 * file called LICENSE. 16 * 17 * Contact Information: 18 * wlanfae <wlanfae@realtek.com> 19******************************************************************************/ 20 21 22#include <linux/string.h> 23#include "r8192U.h" 24#include "r8192S_hw.h" 25 26#include "ieee80211/dot11d.h" 27 28#define RATE_COUNT 12 29u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000, 30 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; 31 32 33#ifndef ENETDOWN 34#define ENETDOWN 1 35#endif 36 37static 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 46static 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 55 56static int r8192_wx_get_rate(struct net_device *dev, 57 struct iw_request_info *info, 58 union iwreq_data *wrqu, char *extra) 59{ 60 struct r8192_priv *priv = ieee80211_priv(dev); 61 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra); 62} 63 64 65 66static int r8192_wx_set_rate(struct net_device *dev, 67 struct iw_request_info *info, 68 union iwreq_data *wrqu, char *extra) 69{ 70 int ret; 71 struct r8192_priv *priv = ieee80211_priv(dev); 72 73 down(&priv->wx_sem); 74 75 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); 76 77 up(&priv->wx_sem); 78 79 return ret; 80} 81 82 83static int r8192_wx_set_rts(struct net_device *dev, 84 struct iw_request_info *info, 85 union iwreq_data *wrqu, char *extra) 86{ 87 int ret; 88 struct r8192_priv *priv = ieee80211_priv(dev); 89 90 down(&priv->wx_sem); 91 92 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra); 93 94 up(&priv->wx_sem); 95 96 return ret; 97} 98 99static int r8192_wx_get_rts(struct net_device *dev, 100 struct iw_request_info *info, 101 union iwreq_data *wrqu, char *extra) 102{ 103 struct r8192_priv *priv = ieee80211_priv(dev); 104 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra); 105} 106 107static int r8192_wx_set_power(struct net_device *dev, 108 struct iw_request_info *info, 109 union iwreq_data *wrqu, char *extra) 110{ 111 int ret; 112 struct r8192_priv *priv = ieee80211_priv(dev); 113 114 down(&priv->wx_sem); 115 116 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra); 117 118 up(&priv->wx_sem); 119 120 return ret; 121} 122 123static int r8192_wx_get_power(struct net_device *dev, 124 struct iw_request_info *info, 125 union iwreq_data *wrqu, char *extra) 126{ 127 struct r8192_priv *priv = ieee80211_priv(dev); 128 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra); 129} 130 131#ifdef JOHN_IOCTL 132u16 read_rtl8225(struct net_device *dev, u8 addr); 133void write_rtl8225(struct net_device *dev, u8 adr, u16 data); 134u32 john_read_rtl8225(struct net_device *dev, u8 adr); 135void _write_rtl8225(struct net_device *dev, u8 adr, u16 data); 136 137static int r8192_wx_read_regs(struct net_device *dev, 138 struct iw_request_info *info, 139 union iwreq_data *wrqu, char *extra) 140{ 141 struct r8192_priv *priv = ieee80211_priv(dev); 142 u8 addr; 143 u16 data1; 144 145 down(&priv->wx_sem); 146 147 148 get_user(addr,(u8*)wrqu->data.pointer); 149 data1 = read_rtl8225(dev, addr); 150 wrqu->data.length = data1; 151 152 up(&priv->wx_sem); 153 return 0; 154 155} 156 157static int r8192_wx_write_regs(struct net_device *dev, 158 struct iw_request_info *info, 159 union iwreq_data *wrqu, char *extra) 160{ 161 struct r8192_priv *priv = ieee80211_priv(dev); 162 u8 addr; 163 164 down(&priv->wx_sem); 165 166 get_user(addr, (u8*)wrqu->data.pointer); 167 write_rtl8225(dev, addr, wrqu->data.length); 168 169 up(&priv->wx_sem); 170 return 0; 171 172} 173 174void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); 175u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data); 176 177static int r8192_wx_read_bb(struct net_device *dev, 178 struct iw_request_info *info, 179 union iwreq_data *wrqu, char *extra) 180{ 181 struct r8192_priv *priv = ieee80211_priv(dev); 182 u8 databb; 183 184 down(&priv->wx_sem); 185 186 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000); 187 wrqu->data.length = databb; 188 189 up(&priv->wx_sem); 190 return 0; 191} 192 193void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); 194static int r8192_wx_write_bb(struct net_device *dev, 195 struct iw_request_info *info, 196 union iwreq_data *wrqu, char *extra) 197{ 198 struct r8192_priv *priv = ieee80211_priv(dev); 199 u8 databb; 200 201 down(&priv->wx_sem); 202 203 get_user(databb, (u8*)wrqu->data.pointer); 204 rtl8187_write_phy(dev, wrqu->data.length, databb); 205 206 up(&priv->wx_sem); 207 return 0; 208 209} 210 211 212static int r8192_wx_write_nicb(struct net_device *dev, 213 struct iw_request_info *info, 214 union iwreq_data *wrqu, char *extra) 215{ 216 struct r8192_priv *priv = ieee80211_priv(dev); 217 u32 addr; 218 219 down(&priv->wx_sem); 220 221 get_user(addr, (u32*)wrqu->data.pointer); 222 write_nic_byte(dev, addr, wrqu->data.length); 223 224 up(&priv->wx_sem); 225 return 0; 226 227} 228static int r8192_wx_read_nicb(struct net_device *dev, 229 struct iw_request_info *info, 230 union iwreq_data *wrqu, char *extra) 231{ 232 struct r8192_priv *priv = ieee80211_priv(dev); 233 u32 addr; 234 u16 data1; 235 236 down(&priv->wx_sem); 237 238 get_user(addr,(u32*)wrqu->data.pointer); 239 data1 = read_nic_byte(dev, addr); 240 wrqu->data.length = data1; 241 242 up(&priv->wx_sem); 243 return 0; 244} 245 246static int r8192_wx_get_ap_status(struct net_device *dev, 247 struct iw_request_info *info, 248 union iwreq_data *wrqu, char *extra) 249{ 250 struct r8192_priv *priv = ieee80211_priv(dev); 251 struct ieee80211_device *ieee = priv->ieee80211; 252 struct ieee80211_network *target; 253 struct ieee80211_network *latest = NULL; 254 int name_len; 255 256 down(&priv->wx_sem); 257 258 //count the length of input ssid 259 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++); 260 261 //search for the correspoding info which is received 262 list_for_each_entry(target, &ieee->network_list, list) { 263 if ( (target->ssid_len == name_len) && 264 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){ 265 if ((latest == NULL) ||(target->last_scanned > latest->last_scanned)) 266 latest = target; 267 268 } 269 } 270 271 if(latest != NULL) 272 { 273 wrqu->data.length = latest->SignalStrength; 274 275 if(latest->wpa_ie_len>0 || latest->rsn_ie_len>0 ) { 276 wrqu->data.flags = 1; 277 } else { 278 wrqu->data.flags = 0; 279 } 280 } 281 282 up(&priv->wx_sem); 283 return 0; 284} 285 286 287 288#endif 289static int r8192_wx_force_reset(struct net_device *dev, 290 struct iw_request_info *info, 291 union iwreq_data *wrqu, char *extra) 292{ 293 struct r8192_priv *priv = ieee80211_priv(dev); 294 295 down(&priv->wx_sem); 296 297 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra); 298 priv->force_reset = *extra; 299 up(&priv->wx_sem); 300 return 0; 301 302} 303 304static int r8191su_wx_get_firm_version(struct net_device *dev, 305 struct iw_request_info *info, 306 struct iw_param *wrqu, char *extra) 307{ 308 struct r8192_priv *priv = ieee80211_priv(dev); 309 u16 firmware_version; 310 311 down(&priv->wx_sem); 312 firmware_version = priv->pFirmware->FirmwareVersion; 313 wrqu->value = firmware_version; 314 wrqu->fixed = 1; 315 316 up(&priv->wx_sem); 317 return 0; 318} 319 320 321 322static int r8192_wx_set_rawtx(struct net_device *dev, 323 struct iw_request_info *info, 324 union iwreq_data *wrqu, char *extra) 325{ 326 struct r8192_priv *priv = ieee80211_priv(dev); 327 int ret; 328 329 down(&priv->wx_sem); 330 331 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); 332 333 up(&priv->wx_sem); 334 335 return ret; 336 337} 338 339static int r8192_wx_set_crcmon(struct net_device *dev, 340 struct iw_request_info *info, 341 union iwreq_data *wrqu, char *extra) 342{ 343 struct r8192_priv *priv = ieee80211_priv(dev); 344 int *parms = (int *)extra; 345 int enable = (parms[0] > 0); 346 short prev = priv->crcmon; 347 348 down(&priv->wx_sem); 349 350 if(enable) 351 priv->crcmon=1; 352 else 353 priv->crcmon=0; 354 355 DMESG("bad CRC in monitor mode are %s", 356 priv->crcmon ? "accepted" : "rejected"); 357 358 if(prev != priv->crcmon && priv->up){ 359 //rtl8180_down(dev); 360 //rtl8180_up(dev); 361 } 362 363 up(&priv->wx_sem); 364 365 return 0; 366} 367 368static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, 369 union iwreq_data *wrqu, char *b) 370{ 371 struct r8192_priv *priv = ieee80211_priv(dev); 372 int ret; 373 down(&priv->wx_sem); 374 375 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b); 376 377 rtl8192_set_rxconf(dev); 378 379 up(&priv->wx_sem); 380 return ret; 381} 382 383struct iw_range_with_scan_capa 384{ 385 /* Informative stuff (to choose between different interface) */ 386 __u32 throughput; /* To give an idea... */ 387 /* In theory this value should be the maximum benchmarked 388 * TCP/IP throughput, because with most of these devices the 389 * bit rate is meaningless (overhead an co) to estimate how 390 * fast the connection will go and pick the fastest one. 391 * I suggest people to play with Netperf or any benchmark... 392 */ 393 394 /* NWID (or domain id) */ 395 __u32 min_nwid; /* Minimal NWID we are able to set */ 396 __u32 max_nwid; /* Maximal NWID we are able to set */ 397 398 /* Old Frequency (backward compat - moved lower ) */ 399 __u16 old_num_channels; 400 __u8 old_num_frequency; 401 402 /* Scan capabilities */ 403 __u8 scan_capa; 404}; 405static int rtl8180_wx_get_range(struct net_device *dev, 406 struct iw_request_info *info, 407 union iwreq_data *wrqu, char *extra) 408{ 409 struct iw_range *range = (struct iw_range *)extra; 410 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; 411 struct r8192_priv *priv = ieee80211_priv(dev); 412 u16 val; 413 int i; 414 415 wrqu->data.length = sizeof(*range); 416 memset(range, 0, sizeof(*range)); 417 418 /* Let's try to keep this struct in the same order as in 419 * linux/include/wireless.h 420 */ 421 422 /* TODO: See what values we can set, and remove the ones we can't 423 * set, or fill them with some default data. 424 */ 425 426 /* ~5 Mb/s real (802.11b) */ 427 range->throughput = 5 * 1000 * 1000; 428 429 // TODO: Not used in 802.11b? 430// range->min_nwid; /* Minimal NWID we are able to set */ 431 // TODO: Not used in 802.11b? 432// range->max_nwid; /* Maximal NWID we are able to set */ 433 434 /* Old Frequency (backward compat - moved lower ) */ 435// range->old_num_channels; 436// range->old_num_frequency; 437// range->old_freq[6]; /* Filler to keep "version" at the same offset */ 438 if(priv->rf_set_sens != NULL) 439 range->sensitivity = priv->max_sens; /* signal level threshold range */ 440 441 range->max_qual.qual = 100; 442 /* TODO: Find real max RSSI and stick here */ 443 range->max_qual.level = 0; 444 range->max_qual.noise = -98; 445 range->max_qual.updated = 7; /* Updated all three */ 446 447 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ 448 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ 449 range->avg_qual.level = 20 + -98; 450 range->avg_qual.noise = 0; 451 range->avg_qual.updated = 7; /* Updated all three */ 452 453 range->num_bitrates = RATE_COUNT; 454 455 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { 456 range->bitrate[i] = rtl8180_rates[i]; 457 } 458 459 range->min_frag = MIN_FRAG_THRESHOLD; 460 range->max_frag = MAX_FRAG_THRESHOLD; 461 462 range->min_pmp=0; 463 range->max_pmp = 5000000; 464 range->min_pmt = 0; 465 range->max_pmt = 65535*1000; 466 range->pmp_flags = IW_POWER_PERIOD; 467 range->pmt_flags = IW_POWER_TIMEOUT; 468 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; 469 470 range->we_version_compiled = WIRELESS_EXT; 471 range->we_version_source = 16; 472 473 474 for (i = 0, val = 0; i < 14; i++) { 475 476 // Include only legal frequencies for some countries 477 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { 478 range->freq[val].i = i + 1; 479 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; 480 range->freq[val].e = 1; 481 val++; 482 } else { 483 // we don't use ? 484 } 485 486 if (val == IW_MAX_FREQUENCIES) 487 break; 488 } 489 range->num_frequency = val; 490 range->num_channels = val; 491 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| 492 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; 493 tmp->scan_capa = 0x01; 494 return 0; 495} 496 497 498static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, 499 union iwreq_data *wrqu, char *b) 500{ 501 struct r8192_priv *priv = ieee80211_priv(dev); 502 struct ieee80211_device* ieee = priv->ieee80211; 503 int ret = 0; 504 505 if(!priv->up) return -ENETDOWN; 506 507 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) 508 return -EAGAIN; 509 510 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) 511 { 512 struct iw_scan_req* req = (struct iw_scan_req*)b; 513 if (req->essid_len) 514 { 515 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid); 516 ieee->current_network.ssid_len = req->essid_len; 517 memcpy(ieee->current_network.ssid, req->essid, req->essid_len); 518 //printk("=====>network ssid:%s\n", ieee->current_network.ssid); 519 } 520 } 521 522 down(&priv->wx_sem); 523 if(priv->ieee80211->state != IEEE80211_LINKED){ 524 priv->ieee80211->scanning = 0; 525 ieee80211_softmac_scan_syncro(priv->ieee80211); 526 ret = 0; 527 } 528 else 529 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b); 530 up(&priv->wx_sem); 531 return ret; 532} 533 534 535static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, 536 union iwreq_data *wrqu, char *b) 537{ 538 539 int ret; 540 struct r8192_priv *priv = ieee80211_priv(dev); 541 542 if(!priv->up) return -ENETDOWN; 543 544 down(&priv->wx_sem); 545 546 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b); 547 548 up(&priv->wx_sem); 549 550 return ret; 551} 552 553static int r8192_wx_set_essid(struct net_device *dev, 554 struct iw_request_info *a, 555 union iwreq_data *wrqu, char *b) 556{ 557 struct r8192_priv *priv = ieee80211_priv(dev); 558 int ret; 559 down(&priv->wx_sem); 560 561 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); 562 563 up(&priv->wx_sem); 564 565 return ret; 566} 567 568 569 570 571static int r8192_wx_get_essid(struct net_device *dev, 572 struct iw_request_info *a, 573 union iwreq_data *wrqu, char *b) 574{ 575 int ret; 576 struct r8192_priv *priv = ieee80211_priv(dev); 577 578 down(&priv->wx_sem); 579 580 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); 581 582 up(&priv->wx_sem); 583 584 return ret; 585} 586 587 588static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, 589 union iwreq_data *wrqu, char *b) 590{ 591 int ret; 592 struct r8192_priv *priv = ieee80211_priv(dev); 593 594 down(&priv->wx_sem); 595 596 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); 597 598 up(&priv->wx_sem); 599 return ret; 600} 601 602static int r8192_wx_get_name(struct net_device *dev, 603 struct iw_request_info *info, 604 union iwreq_data *wrqu, char *extra) 605{ 606 struct r8192_priv *priv = ieee80211_priv(dev); 607 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); 608} 609 610 611static int r8192_wx_set_frag(struct net_device *dev, 612 struct iw_request_info *info, 613 union iwreq_data *wrqu, char *extra) 614{ 615 struct r8192_priv *priv = ieee80211_priv(dev); 616 617 if (wrqu->frag.disabled) 618 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; 619 else { 620 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 621 wrqu->frag.value > MAX_FRAG_THRESHOLD) 622 return -EINVAL; 623 624 priv->ieee80211->fts = wrqu->frag.value & ~0x1; 625 } 626 627 return 0; 628} 629 630 631static int r8192_wx_get_frag(struct net_device *dev, 632 struct iw_request_info *info, 633 union iwreq_data *wrqu, char *extra) 634{ 635 struct r8192_priv *priv = ieee80211_priv(dev); 636 637 wrqu->frag.value = priv->ieee80211->fts; 638 wrqu->frag.fixed = 0; /* no auto select */ 639 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); 640 641 return 0; 642} 643 644 645static int r8192_wx_set_wap(struct net_device *dev, 646 struct iw_request_info *info, 647 union iwreq_data *awrq, 648 char *extra) 649{ 650 651 int ret; 652 struct r8192_priv *priv = ieee80211_priv(dev); 653// struct sockaddr *temp = (struct sockaddr *)awrq; 654 down(&priv->wx_sem); 655 656 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); 657 658 up(&priv->wx_sem); 659 660 return ret; 661 662} 663 664 665static int r8192_wx_get_wap(struct net_device *dev, 666 struct iw_request_info *info, 667 union iwreq_data *wrqu, char *extra) 668{ 669 struct r8192_priv *priv = ieee80211_priv(dev); 670 671 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra); 672} 673 674 675static int r8192_wx_get_enc(struct net_device *dev, 676 struct iw_request_info *info, 677 union iwreq_data *wrqu, char *key) 678{ 679 struct r8192_priv *priv = ieee80211_priv(dev); 680 681 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); 682} 683 684static int r8192_wx_set_enc(struct net_device *dev, 685 struct iw_request_info *info, 686 union iwreq_data *wrqu, char *key) 687{ 688 struct r8192_priv *priv = ieee80211_priv(dev); 689 struct ieee80211_device *ieee = priv->ieee80211; 690 int ret; 691 692 //u32 TargetContent; 693 u32 hwkey[4]={0,0,0,0}; 694 u8 mask=0xff; 695 u32 key_idx=0; 696 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff}; 697 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00}, 698 {0x00,0x00,0x00,0x00,0x00,0x01}, 699 {0x00,0x00,0x00,0x00,0x00,0x02}, 700 {0x00,0x00,0x00,0x00,0x00,0x03} }; 701 int i; 702 703 if(!priv->up) return -ENETDOWN; 704 705 down(&priv->wx_sem); 706 707 RT_TRACE(COMP_SEC, "Setting SW wep key"); 708 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key); 709 710 up(&priv->wx_sem); 711 712 713 714 //sometimes, the length is zero while we do not type key value 715 if(wrqu->encoding.length!=0){ 716 717 for(i=0 ; i<4 ; i++){ 718 hwkey[i] |= key[4*i+0]&mask; 719 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00; 720 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00; 721 hwkey[i] |= (key[4*i+1]&mask)<<8; 722 hwkey[i] |= (key[4*i+2]&mask)<<16; 723 hwkey[i] |= (key[4*i+3]&mask)<<24; 724 } 725 726 #define CONF_WEP40 0x4 727 #define CONF_WEP104 0x14 728 729 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){ 730 case 0: key_idx = ieee->tx_keyidx; break; 731 case 1: key_idx = 0; break; 732 case 2: key_idx = 1; break; 733 case 3: key_idx = 2; break; 734 case 4: key_idx = 3; break; 735 default: break; 736 } 737 738 if(wrqu->encoding.length==0x5){ 739 ieee->pairwise_key_type = KEY_TYPE_WEP40; 740 EnableHWSecurityConfig8192(dev); 741 742 setKey( dev, 743 key_idx, //EntryNo 744 key_idx, //KeyIndex 745 KEY_TYPE_WEP40, //KeyType 746 zero_addr[key_idx], 747 0, //DefaultKey 748 hwkey); //KeyContent 749 750 } 751 752 else if(wrqu->encoding.length==0xd){ 753 ieee->pairwise_key_type = KEY_TYPE_WEP104; 754 EnableHWSecurityConfig8192(dev); 755 756 setKey( dev, 757 key_idx, //EntryNo 758 key_idx, //KeyIndex 759 KEY_TYPE_WEP104, //KeyType 760 zero_addr[key_idx], 761 0, //DefaultKey 762 hwkey); //KeyContent 763 764 } 765 else printk("wrong type in WEP, not WEP40 and WEP104\n"); 766 767 } 768 769 return ret; 770} 771 772 773static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union 774 iwreq_data *wrqu, char *p){ 775 776 struct r8192_priv *priv = ieee80211_priv(dev); 777 int *parms=(int*)p; 778 int mode=parms[0]; 779 780 priv->ieee80211->active_scan = mode; 781 782 return 1; 783} 784 785 786 787static int r8192_wx_set_retry(struct net_device *dev, 788 struct iw_request_info *info, 789 union iwreq_data *wrqu, char *extra) 790{ 791 struct r8192_priv *priv = ieee80211_priv(dev); 792 int err = 0; 793 794 down(&priv->wx_sem); 795 796 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 797 wrqu->retry.disabled){ 798 err = -EINVAL; 799 goto exit; 800 } 801 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){ 802 err = -EINVAL; 803 goto exit; 804 } 805 806 if(wrqu->retry.value > R8180_MAX_RETRY){ 807 err= -EINVAL; 808 goto exit; 809 } 810 if (wrqu->retry.flags & IW_RETRY_MAX) { 811 priv->retry_rts = wrqu->retry.value; 812 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); 813 814 }else { 815 priv->retry_data = wrqu->retry.value; 816 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); 817 } 818 819 820 rtl8192_commit(dev); 821 /* 822 if(priv->up){ 823 rtl8180_rtx_disable(dev); 824 rtl8180_rx_enable(dev); 825 rtl8180_tx_enable(dev); 826 827 } 828 */ 829exit: 830 up(&priv->wx_sem); 831 832 return err; 833} 834 835static int r8192_wx_get_retry(struct net_device *dev, 836 struct iw_request_info *info, 837 union iwreq_data *wrqu, char *extra) 838{ 839 struct r8192_priv *priv = ieee80211_priv(dev); 840 841 842 wrqu->retry.disabled = 0; /* can't be disabled */ 843 844 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 845 IW_RETRY_LIFETIME) 846 return -EINVAL; 847 848 if (wrqu->retry.flags & IW_RETRY_MAX) { 849 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 850 wrqu->retry.value = priv->retry_rts; 851 } else { 852 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; 853 wrqu->retry.value = priv->retry_data; 854 } 855 //printk("returning %d",wrqu->retry.value); 856 857 858 return 0; 859} 860 861static int r8192_wx_get_sens(struct net_device *dev, 862 struct iw_request_info *info, 863 union iwreq_data *wrqu, char *extra) 864{ 865 struct r8192_priv *priv = ieee80211_priv(dev); 866 if(priv->rf_set_sens == NULL) 867 return -1; /* we have not this support for this radio */ 868 wrqu->sens.value = priv->sens; 869 return 0; 870} 871 872 873static int r8192_wx_set_sens(struct net_device *dev, 874 struct iw_request_info *info, 875 union iwreq_data *wrqu, char *extra) 876{ 877 878 struct r8192_priv *priv = ieee80211_priv(dev); 879 880 short err = 0; 881 down(&priv->wx_sem); 882 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); 883 if(priv->rf_set_sens == NULL) { 884 err= -1; /* we have not this support for this radio */ 885 goto exit; 886 } 887 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0) 888 priv->sens = wrqu->sens.value; 889 else 890 err= -EINVAL; 891 892exit: 893 up(&priv->wx_sem); 894 895 return err; 896} 897 898//hw security need to reorganized. 899static int r8192_wx_set_enc_ext(struct net_device *dev, 900 struct iw_request_info *info, 901 union iwreq_data *wrqu, char *extra) 902{ 903 int ret=0; 904 struct r8192_priv *priv = ieee80211_priv(dev); 905 struct ieee80211_device* ieee = priv->ieee80211; 906 //printk("===>%s()\n", __FUNCTION__); 907 908 909 down(&priv->wx_sem); 910 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); 911 912 { 913 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; 914 u8 zero[6] = {0}; 915 u32 key[4] = {0}; 916 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 917 struct iw_point *encoding = &wrqu->encoding; 918 u8 idx = 0, alg = 0, group = 0; 919 if ((encoding->flags & IW_ENCODE_DISABLED) || 920 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01 921 { 922 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; 923 CamResetAllEntry(dev); 924 goto end_hw_sec; 925 } 926 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; 927 idx = encoding->flags & IW_ENCODE_INDEX; 928 if (idx) 929 idx --; 930 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; 931 932 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) 933 { 934 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) ) 935 alg = KEY_TYPE_WEP104; 936 ieee->pairwise_key_type = alg; 937 EnableHWSecurityConfig8192(dev); 938 } 939 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1 940 941 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) ) 942 { 943 944 setKey( dev, 945 idx,//EntryNo 946 idx, //KeyIndex 947 alg, //KeyType 948 zero, //MacAddr 949 0, //DefaultKey 950 key); //KeyContent 951 } 952 else if (group) 953 { 954 ieee->group_key_type = alg; 955 setKey( dev, 956 idx,//EntryNo 957 idx, //KeyIndex 958 alg, //KeyType 959 broadcast_addr, //MacAddr 960 0, //DefaultKey 961 key); //KeyContent 962 } 963 else //pairwise key 964 { 965 setKey( dev, 966 4,//EntryNo 967 idx, //KeyIndex 968 alg, //KeyType 969 (u8*)ieee->ap_mac_addr, //MacAddr 970 0, //DefaultKey 971 key); //KeyContent 972 } 973 974 975 } 976 977end_hw_sec: 978 979 up(&priv->wx_sem); 980 return ret; 981} 982static int r8192_wx_set_auth(struct net_device *dev, 983 struct iw_request_info *info, 984 union iwreq_data *data, char *extra) 985{ 986 int ret=0; 987 988 //printk("====>%s()\n", __FUNCTION__); 989 struct r8192_priv *priv = ieee80211_priv(dev); 990 down(&priv->wx_sem); 991 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); 992 up(&priv->wx_sem); 993 return ret; 994} 995 996static int r8192_wx_set_mlme(struct net_device *dev, 997 struct iw_request_info *info, 998 union iwreq_data *wrqu, char *extra) 999{ 1000 //printk("====>%s()\n", __FUNCTION__); 1001 1002 int ret=0; 1003 struct r8192_priv *priv = ieee80211_priv(dev); 1004 down(&priv->wx_sem); 1005 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); 1006 up(&priv->wx_sem); 1007 return ret; 1008} 1009 1010static int r8192_wx_set_pmkid(struct net_device *dev, 1011 struct iw_request_info *info, 1012 union iwreq_data *wrqu, char *extra) 1013{ 1014 int i; 1015 struct r8192_priv *priv = ieee80211_priv(dev); 1016 struct ieee80211_device* ieee = priv->ieee80211; 1017 struct iw_pmksa* pPMK = (struct iw_pmksa*)extra; 1018 int intReturn = false; 1019 1020 switch (pPMK->cmd) 1021 { 1022 case IW_PMKSA_ADD: 1023 for (i = 0; i < NUM_PMKID_CACHE; i++) 1024 { 1025 if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0) 1026 { 1027 memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN); 1028 memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN); 1029 ieee->PMKIDList[i].bUsed = true; 1030 intReturn = true; 1031 goto __EXIT__; 1032 } 1033 } 1034 1035 for (i = 0; i < NUM_PMKID_CACHE; i++) 1036 { 1037 if (ieee->PMKIDList[i].bUsed == false) 1038 { 1039 memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN); 1040 memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN); 1041 ieee->PMKIDList[i].bUsed = true; 1042 intReturn = true; 1043 goto __EXIT__; 1044 } 1045 } 1046 break; 1047 1048 case IW_PMKSA_REMOVE: 1049 for (i = 0; i < NUM_PMKID_CACHE; i++) 1050 { 1051 if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true) 1052 { 1053 memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST)); 1054 intReturn = true; 1055 break; 1056 } 1057 } 1058 break; 1059 1060 case IW_PMKSA_FLUSH: 1061 memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE)); 1062 intReturn = true; 1063 break; 1064 1065 default: 1066 break; 1067 } 1068 1069__EXIT__: 1070 return (intReturn); 1071 1072} 1073 1074static int r8192_wx_set_gen_ie(struct net_device *dev, 1075 struct iw_request_info *info, 1076 union iwreq_data *data, char *extra) 1077{ 1078 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); 1079 int ret=0; 1080 struct r8192_priv *priv = ieee80211_priv(dev); 1081 down(&priv->wx_sem); 1082 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); 1083 up(&priv->wx_sem); 1084 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret); 1085 return ret; 1086 1087 1088} 1089 1090static int dummy(struct net_device *dev, struct iw_request_info *a, 1091 union iwreq_data *wrqu,char *b) 1092{ 1093 return -1; 1094} 1095 1096 1097static iw_handler r8192_wx_handlers[] = 1098{ 1099 NULL, /* SIOCSIWCOMMIT */ 1100 r8192_wx_get_name, /* SIOCGIWNAME */ 1101 dummy, /* SIOCSIWNWID */ 1102 dummy, /* SIOCGIWNWID */ 1103 r8192_wx_set_freq, /* SIOCSIWFREQ */ 1104 r8192_wx_get_freq, /* SIOCGIWFREQ */ 1105 r8192_wx_set_mode, /* SIOCSIWMODE */ 1106 r8192_wx_get_mode, /* SIOCGIWMODE */ 1107 r8192_wx_set_sens, /* SIOCSIWSENS */ 1108 r8192_wx_get_sens, /* SIOCGIWSENS */ 1109 NULL, /* SIOCSIWRANGE */ 1110 rtl8180_wx_get_range, /* SIOCGIWRANGE */ 1111 NULL, /* SIOCSIWPRIV */ 1112 NULL, /* SIOCGIWPRIV */ 1113 NULL, /* SIOCSIWSTATS */ 1114 NULL, /* SIOCGIWSTATS */ 1115 dummy, /* SIOCSIWSPY */ 1116 dummy, /* SIOCGIWSPY */ 1117 NULL, /* SIOCGIWTHRSPY */ 1118 NULL, /* SIOCWIWTHRSPY */ 1119 r8192_wx_set_wap, /* SIOCSIWAP */ 1120 r8192_wx_get_wap, /* SIOCGIWAP */ 1121 r8192_wx_set_mlme, /* MLME-- */ 1122 dummy, /* SIOCGIWAPLIST -- depricated */ 1123 r8192_wx_set_scan, /* SIOCSIWSCAN */ 1124 r8192_wx_get_scan, /* SIOCGIWSCAN */ 1125 r8192_wx_set_essid, /* SIOCSIWESSID */ 1126 r8192_wx_get_essid, /* SIOCGIWESSID */ 1127 dummy, /* SIOCSIWNICKN */ 1128 dummy, /* SIOCGIWNICKN */ 1129 NULL, /* -- hole -- */ 1130 NULL, /* -- hole -- */ 1131 r8192_wx_set_rate, /* SIOCSIWRATE */ 1132 r8192_wx_get_rate, /* SIOCGIWRATE */ 1133 r8192_wx_set_rts, /* SIOCSIWRTS */ 1134 r8192_wx_get_rts, /* SIOCGIWRTS */ 1135 r8192_wx_set_frag, /* SIOCSIWFRAG */ 1136 r8192_wx_get_frag, /* SIOCGIWFRAG */ 1137 dummy, /* SIOCSIWTXPOW */ 1138 dummy, /* SIOCGIWTXPOW */ 1139 r8192_wx_set_retry, /* SIOCSIWRETRY */ 1140 r8192_wx_get_retry, /* SIOCGIWRETRY */ 1141 r8192_wx_set_enc, /* SIOCSIWENCODE */ 1142 r8192_wx_get_enc, /* SIOCGIWENCODE */ 1143 r8192_wx_set_power, /* SIOCSIWPOWER */ 1144 r8192_wx_get_power, /* SIOCGIWPOWER */ 1145 NULL, /*---hole---*/ 1146 NULL, /*---hole---*/ 1147 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */ 1148 NULL, /* SIOCSIWGENIE */ 1149 1150 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */ 1151 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */ 1152 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ 1153 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ 1154 r8192_wx_set_pmkid, /* SIOCSIWPMKSA */ 1155 NULL, /*---hole---*/ 1156 1157}; 1158 1159 1160static const struct iw_priv_args r8192_private_args[] = { 1161 1162 { 1163 SIOCIWFIRSTPRIV + 0x0, 1164 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" 1165 }, 1166 1167 { 1168 SIOCIWFIRSTPRIV + 0x1, 1169 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" 1170 1171 }, 1172 { 1173 SIOCIWFIRSTPRIV + 0x2, 1174 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 1175 } 1176#ifdef JOHN_IOCTL 1177 , 1178 { 1179 SIOCIWFIRSTPRIV + 0x3, 1180 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF" 1181 } 1182 , 1183 { 1184 SIOCIWFIRSTPRIV + 0x4, 1185 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF" 1186 } 1187 , 1188 { 1189 SIOCIWFIRSTPRIV + 0x5, 1190 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB" 1191 } 1192 , 1193 { 1194 SIOCIWFIRSTPRIV + 0x6, 1195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB" 1196 } 1197 , 1198 { 1199 SIOCIWFIRSTPRIV + 0x7, 1200 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb" 1201 } 1202 , 1203 { 1204 SIOCIWFIRSTPRIV + 0x8, 1205 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb" 1206 } 1207 , 1208 { 1209 SIOCIWFIRSTPRIV + 0x9, 1210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" 1211 } 1212 1213#endif 1214 , 1215 { 1216 SIOCIWFIRSTPRIV + 0x3, 1217 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" 1218 } 1219 1220 , 1221 { 1222 SIOCIWFIRSTPRIV + 0x5, 1223 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1, 1224 "firm_ver" 1225 } 1226}; 1227 1228 1229static iw_handler r8192_private_handler[] = { 1230// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */ 1231 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ 1232// r8192_wx_set_forceassociate, 1233// r8192_wx_set_beaconinterval, 1234// r8192_wx_set_monitor_type, 1235 r8192_wx_set_scan_type, 1236 r8192_wx_set_rawtx, 1237#ifdef JOHN_IOCTL 1238 r8192_wx_read_regs, 1239 r8192_wx_write_regs, 1240 r8192_wx_read_bb, 1241 r8192_wx_write_bb, 1242 r8192_wx_read_nicb, 1243 r8192_wx_write_nicb, 1244 r8192_wx_get_ap_status, 1245#endif 1246 r8192_wx_force_reset, 1247 (iw_handler)NULL, 1248 (iw_handler)r8191su_wx_get_firm_version, 1249}; 1250 1251struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) 1252{ 1253 struct r8192_priv *priv = ieee80211_priv(dev); 1254 struct ieee80211_device* ieee = priv->ieee80211; 1255 struct iw_statistics* wstats = &priv->wstats; 1256 int tmp_level = 0; 1257 int tmp_qual = 0; 1258 int tmp_noise = 0; 1259 if(ieee->state < IEEE80211_LINKED) 1260 { 1261 wstats->qual.qual = 0; 1262 wstats->qual.level = 0; 1263 wstats->qual.noise = 0; 1264 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 1265 return wstats; 1266 } 1267 1268 tmp_level = (&ieee->current_network)->stats.rssi; 1269 tmp_qual = (&ieee->current_network)->stats.signal; 1270 tmp_noise = (&ieee->current_network)->stats.noise; 1271 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); 1272 1273 wstats->qual.level = tmp_level; 1274 wstats->qual.qual = tmp_qual; 1275 wstats->qual.noise = tmp_noise; 1276 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM; 1277 return wstats; 1278} 1279 1280struct iw_handler_def r8192_wx_handlers_def={ 1281 .standard = r8192_wx_handlers, 1282 .num_standard = ARRAY_SIZE(r8192_wx_handlers), 1283 .private = r8192_private_handler, 1284 .num_private = ARRAY_SIZE(r8192_private_handler), 1285 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), 1286 .get_wireless_stats = r8192_get_wireless_stats, 1287 .private_args = (struct iw_priv_args *)r8192_private_args, 1288}; 1289