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