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