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