linux/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
   4 *
   5 * Contact Information: wlanfae <wlanfae@realtek.com>
   6 */
   7#include <linux/string.h>
   8#include "rtl_core.h"
   9#include "rtl_wx.h"
  10
  11#define RATE_COUNT 12
  12static u32 rtl8192_rates[] = {
  13        1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000,
  14        18000000, 24000000, 36000000, 48000000, 54000000
  15};
  16
  17#ifndef ENETDOWN
  18#define ENETDOWN 1
  19#endif
  20
  21static int _rtl92e_wx_get_freq(struct net_device *dev,
  22                               struct iw_request_info *a,
  23                               union iwreq_data *wrqu, char *b)
  24{
  25        struct r8192_priv *priv = rtllib_priv(dev);
  26
  27        return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b);
  28}
  29
  30static int _rtl92e_wx_get_mode(struct net_device *dev,
  31                               struct iw_request_info *a,
  32                               union iwreq_data *wrqu, char *b)
  33{
  34        struct r8192_priv *priv = rtllib_priv(dev);
  35
  36        return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b);
  37}
  38
  39static int _rtl92e_wx_get_rate(struct net_device *dev,
  40                               struct iw_request_info *info,
  41                               union iwreq_data *wrqu, char *extra)
  42{
  43        struct r8192_priv *priv = rtllib_priv(dev);
  44
  45        return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra);
  46}
  47
  48static int _rtl92e_wx_set_rate(struct net_device *dev,
  49                               struct iw_request_info *info,
  50                               union iwreq_data *wrqu, char *extra)
  51{
  52        int ret;
  53        struct r8192_priv *priv = rtllib_priv(dev);
  54
  55        if (priv->bHwRadioOff)
  56                return 0;
  57
  58        mutex_lock(&priv->wx_mutex);
  59
  60        ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
  61
  62        mutex_unlock(&priv->wx_mutex);
  63
  64        return ret;
  65}
  66
  67static int _rtl92e_wx_set_rts(struct net_device *dev,
  68                              struct iw_request_info *info,
  69                              union iwreq_data *wrqu, char *extra)
  70{
  71        int ret;
  72        struct r8192_priv *priv = rtllib_priv(dev);
  73
  74        if (priv->bHwRadioOff)
  75                return 0;
  76
  77        mutex_lock(&priv->wx_mutex);
  78
  79        ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
  80
  81        mutex_unlock(&priv->wx_mutex);
  82
  83        return ret;
  84}
  85
  86static int _rtl92e_wx_get_rts(struct net_device *dev,
  87                              struct iw_request_info *info,
  88                              union iwreq_data *wrqu, char *extra)
  89{
  90        struct r8192_priv *priv = rtllib_priv(dev);
  91
  92        return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra);
  93}
  94
  95static int _rtl92e_wx_set_power(struct net_device *dev,
  96                                struct iw_request_info *info,
  97                                union iwreq_data *wrqu, char *extra)
  98{
  99        int ret;
 100        struct r8192_priv *priv = rtllib_priv(dev);
 101
 102        if (priv->bHwRadioOff) {
 103                netdev_warn(dev, "%s(): Can't set Power: Radio is Off.\n",
 104                            __func__);
 105                return 0;
 106        }
 107        mutex_lock(&priv->wx_mutex);
 108
 109        ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
 110
 111        mutex_unlock(&priv->wx_mutex);
 112
 113        return ret;
 114}
 115
 116static int _rtl92e_wx_get_power(struct net_device *dev,
 117                                struct iw_request_info *info,
 118                                union iwreq_data *wrqu, char *extra)
 119{
 120        struct r8192_priv *priv = rtllib_priv(dev);
 121
 122        return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
 123}
 124
 125static int _rtl92e_wx_set_rawtx(struct net_device *dev,
 126                                struct iw_request_info *info,
 127                                union iwreq_data *wrqu, char *extra)
 128{
 129        struct r8192_priv *priv = rtllib_priv(dev);
 130        int ret;
 131
 132        if (priv->bHwRadioOff)
 133                return 0;
 134
 135        mutex_lock(&priv->wx_mutex);
 136
 137        ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra);
 138
 139        mutex_unlock(&priv->wx_mutex);
 140
 141        return ret;
 142}
 143
 144static int _rtl92e_wx_force_reset(struct net_device *dev,
 145                                  struct iw_request_info *info,
 146                                  union iwreq_data *wrqu, char *extra)
 147{
 148        struct r8192_priv *priv = rtllib_priv(dev);
 149
 150        mutex_lock(&priv->wx_mutex);
 151
 152        RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n",
 153                 __func__, *extra);
 154        priv->force_reset = *extra;
 155        mutex_unlock(&priv->wx_mutex);
 156        return 0;
 157}
 158
 159static int _rtl92e_wx_adapter_power_status(struct net_device *dev,
 160                                           struct iw_request_info *info,
 161                                           union iwreq_data *wrqu, char *extra)
 162{
 163        struct r8192_priv *priv = rtllib_priv(dev);
 164        struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
 165                                        (&priv->rtllib->PowerSaveControl);
 166        struct rtllib_device *ieee = priv->rtllib;
 167
 168        mutex_lock(&priv->wx_mutex);
 169
 170        RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ?
 171                 "DC power" : "AC power");
 172        if (*extra || priv->force_lps) {
 173                priv->ps_force = false;
 174                pPSC->bLeisurePs = true;
 175        } else {
 176                if (priv->rtllib->state == RTLLIB_LINKED)
 177                        rtl92e_leisure_ps_leave(dev);
 178
 179                priv->ps_force = true;
 180                pPSC->bLeisurePs = false;
 181                ieee->ps = *extra;
 182        }
 183
 184        mutex_unlock(&priv->wx_mutex);
 185
 186        return 0;
 187}
 188
 189static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev,
 190                                             struct iw_request_info *info,
 191                                             union iwreq_data *wrqu,
 192                                             char *extra)
 193{
 194        struct r8192_priv *priv = rtllib_priv(dev);
 195        struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
 196                                        (&priv->rtllib->PowerSaveControl);
 197
 198        mutex_lock(&priv->wx_mutex);
 199
 200        netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n",
 201                    __func__, *extra);
 202
 203        pPSC->RegMaxLPSAwakeIntvl = *extra;
 204        mutex_unlock(&priv->wx_mutex);
 205        return 0;
 206}
 207
 208static int _rtl92e_wx_set_force_lps(struct net_device *dev,
 209                                    struct iw_request_info *info,
 210                                    union iwreq_data *wrqu, char *extra)
 211{
 212        struct r8192_priv *priv = rtllib_priv(dev);
 213
 214        mutex_lock(&priv->wx_mutex);
 215
 216        netdev_info(dev,
 217                    "%s(): force LPS ! extra is %d (1 is open 0 is close)\n",
 218                    __func__, *extra);
 219        priv->force_lps = *extra;
 220        mutex_unlock(&priv->wx_mutex);
 221        return 0;
 222}
 223
 224static int _rtl92e_wx_set_debug(struct net_device *dev,
 225                                struct iw_request_info *info,
 226                                union iwreq_data *wrqu, char *extra)
 227{
 228        struct r8192_priv *priv = rtllib_priv(dev);
 229        u8 c = *extra;
 230
 231        if (priv->bHwRadioOff)
 232                return 0;
 233
 234        netdev_info(dev, "=====>%s(), *extra:%x, debugflag:%x\n", __func__,
 235                    *extra, rt_global_debug_component);
 236        if (c > 0)
 237                rt_global_debug_component |= (1 << c);
 238        else
 239                rt_global_debug_component &= BIT31;
 240        return 0;
 241}
 242
 243static int _rtl92e_wx_set_mode(struct net_device *dev,
 244                               struct iw_request_info *a,
 245                               union iwreq_data *wrqu, char *b)
 246{
 247        struct r8192_priv *priv = rtllib_priv(dev);
 248        struct rtllib_device *ieee = netdev_priv_rsl(dev);
 249
 250        enum rt_rf_power_state rtState;
 251        int ret;
 252
 253        if (priv->bHwRadioOff)
 254                return 0;
 255        rtState = priv->rtllib->eRFPowerState;
 256        mutex_lock(&priv->wx_mutex);
 257        if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR ||
 258            ieee->bNetPromiscuousMode) {
 259                if (priv->rtllib->PowerSaveControl.bInactivePs) {
 260                        if (rtState == eRfOff) {
 261                                if (priv->rtllib->RfOffReason >
 262                                    RF_CHANGE_BY_IPS) {
 263                                        netdev_warn(dev, "%s(): RF is OFF.\n",
 264                                                    __func__);
 265                                        mutex_unlock(&priv->wx_mutex);
 266                                        return -1;
 267                                }
 268                                netdev_info(dev,
 269                                            "=========>%s(): rtl92e_ips_leave\n",
 270                                            __func__);
 271                                mutex_lock(&priv->rtllib->ips_mutex);
 272                                rtl92e_ips_leave(dev);
 273                                mutex_unlock(&priv->rtllib->ips_mutex);
 274                        }
 275                }
 276        }
 277        ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
 278
 279        mutex_unlock(&priv->wx_mutex);
 280        return ret;
 281}
 282
 283struct  iw_range_with_scan_capa {
 284        /* Informative stuff (to choose between different interface) */
 285        __u32      throughput;     /* To give an idea... */
 286        /* In theory this value should be the maximum benchmarked
 287         * TCP/IP throughput, because with most of these devices the
 288         * bit rate is meaningless (overhead an co) to estimate how
 289         * fast the connection will go and pick the fastest one.
 290         * I suggest people to play with Netperf or any benchmark...
 291         */
 292
 293        /* NWID (or domain id) */
 294        __u32      min_nwid;    /* Minimal NWID we are able to set */
 295        __u32      max_nwid;    /* Maximal NWID we are able to set */
 296
 297        /* Old Frequency (backward compat - moved lower ) */
 298        __u16      old_num_channels;
 299        __u8        old_num_frequency;
 300
 301        /* Scan capabilities */
 302        __u8        scan_capa;
 303};
 304
 305static int _rtl92e_wx_get_range(struct net_device *dev,
 306                                struct iw_request_info *info,
 307                                union iwreq_data *wrqu, char *extra)
 308{
 309        struct iw_range *range = (struct iw_range *)extra;
 310        struct r8192_priv *priv = rtllib_priv(dev);
 311        u16 val;
 312        int i;
 313
 314        wrqu->data.length = sizeof(*range);
 315        memset(range, 0, sizeof(*range));
 316
 317        /* ~130 Mb/s real (802.11n) */
 318        range->throughput = 130 * 1000 * 1000;
 319
 320        if (priv->rf_set_sens != NULL)
 321                /* signal level threshold range */
 322                range->sensitivity = priv->max_sens;
 323
 324        range->max_qual.qual = 100;
 325        range->max_qual.level = 0;
 326        range->max_qual.noise = 0;
 327        range->max_qual.updated = 7; /* Updated all three */
 328
 329        range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
 330        range->avg_qual.level = 0;
 331        range->avg_qual.noise = 0;
 332        range->avg_qual.updated = 7; /* Updated all three */
 333
 334        range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES);
 335
 336        for (i = 0; i < range->num_bitrates; i++)
 337                range->bitrate[i] = rtl8192_rates[i];
 338
 339        range->max_rts = DEFAULT_RTS_THRESHOLD;
 340        range->min_frag = MIN_FRAG_THRESHOLD;
 341        range->max_frag = MAX_FRAG_THRESHOLD;
 342
 343        range->min_pmp = 0;
 344        range->max_pmp = 5000000;
 345        range->min_pmt = 0;
 346        range->max_pmt = 65535 * 1000;
 347        range->pmp_flags = IW_POWER_PERIOD;
 348        range->pmt_flags = IW_POWER_TIMEOUT;
 349        range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 350        range->we_version_compiled = WIRELESS_EXT;
 351        range->we_version_source = 18;
 352
 353        for (i = 0, val = 0; i < 14; i++) {
 354                if ((priv->rtllib->active_channel_map)[i + 1]) {
 355                        range->freq[val].i = i + 1;
 356                        range->freq[val].m = rtllib_wlan_frequencies[i] *
 357                                             100000;
 358                        range->freq[val].e = 1;
 359                        val++;
 360                }
 361
 362                if (val == IW_MAX_FREQUENCIES)
 363                        break;
 364        }
 365        range->num_frequency = val;
 366        range->num_channels = val;
 367        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 368                          IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 369        range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
 370
 371        /* Event capability (kernel + driver) */
 372
 373        return 0;
 374}
 375
 376static int _rtl92e_wx_set_scan(struct net_device *dev,
 377                               struct iw_request_info *a,
 378                               union iwreq_data *wrqu, char *b)
 379{
 380        struct r8192_priv *priv = rtllib_priv(dev);
 381        struct rtllib_device *ieee = priv->rtllib;
 382        enum rt_rf_power_state rtState;
 383        int ret;
 384
 385        if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
 386                if ((ieee->state >= RTLLIB_ASSOCIATING) &&
 387                    (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED))
 388                        return 0;
 389                if ((priv->rtllib->state == RTLLIB_LINKED) &&
 390                    (priv->rtllib->CntAfterLink < 2))
 391                        return 0;
 392        }
 393
 394        if (priv->bHwRadioOff) {
 395                netdev_info(dev, "================>%s(): hwradio off\n",
 396                            __func__);
 397                return 0;
 398        }
 399        rtState = priv->rtllib->eRFPowerState;
 400        if (!priv->up)
 401                return -ENETDOWN;
 402        if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true)
 403                return -EAGAIN;
 404
 405        if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 406                struct iw_scan_req *req = (struct iw_scan_req *)b;
 407
 408                if (req->essid_len) {
 409                        int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE);
 410
 411                        ieee->current_network.ssid_len = len;
 412                        memcpy(ieee->current_network.ssid, req->essid, len);
 413                }
 414        }
 415
 416        mutex_lock(&priv->wx_mutex);
 417
 418        priv->rtllib->FirstIe_InScan = true;
 419
 420        if (priv->rtllib->state != RTLLIB_LINKED) {
 421                if (priv->rtllib->PowerSaveControl.bInactivePs) {
 422                        if (rtState == eRfOff) {
 423                                if (priv->rtllib->RfOffReason >
 424                                    RF_CHANGE_BY_IPS) {
 425                                        netdev_warn(dev, "%s(): RF is OFF.\n",
 426                                                    __func__);
 427                                        mutex_unlock(&priv->wx_mutex);
 428                                        return -1;
 429                                }
 430                                RT_TRACE(COMP_PS,
 431                                         "=========>%s(): rtl92e_ips_leave\n",
 432                                         __func__);
 433                                mutex_lock(&priv->rtllib->ips_mutex);
 434                                rtl92e_ips_leave(dev);
 435                                mutex_unlock(&priv->rtllib->ips_mutex);
 436                        }
 437                }
 438                rtllib_stop_scan(priv->rtllib);
 439                if (priv->rtllib->LedControlHandler)
 440                        priv->rtllib->LedControlHandler(dev,
 441                                                         LED_CTL_SITE_SURVEY);
 442
 443                if (priv->rtllib->eRFPowerState != eRfOff) {
 444                        priv->rtllib->actscanning = true;
 445
 446                        if (ieee->ScanOperationBackupHandler)
 447                                ieee->ScanOperationBackupHandler(ieee->dev,
 448                                                         SCAN_OPT_BACKUP);
 449
 450                        rtllib_start_scan_syncro(priv->rtllib, 0);
 451
 452                        if (ieee->ScanOperationBackupHandler)
 453                                ieee->ScanOperationBackupHandler(ieee->dev,
 454                                                         SCAN_OPT_RESTORE);
 455                }
 456                ret = 0;
 457        } else {
 458                priv->rtllib->actscanning = true;
 459                ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
 460        }
 461
 462        mutex_unlock(&priv->wx_mutex);
 463        return ret;
 464}
 465
 466static int _rtl92e_wx_get_scan(struct net_device *dev,
 467                               struct iw_request_info *a,
 468                               union iwreq_data *wrqu, char *b)
 469{
 470        int ret;
 471        struct r8192_priv *priv = rtllib_priv(dev);
 472
 473        if (!priv->up)
 474                return -ENETDOWN;
 475
 476        if (priv->bHwRadioOff)
 477                return 0;
 478
 479        mutex_lock(&priv->wx_mutex);
 480
 481        ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
 482
 483        mutex_unlock(&priv->wx_mutex);
 484
 485        return ret;
 486}
 487
 488static int _rtl92e_wx_set_essid(struct net_device *dev,
 489                                struct iw_request_info *a,
 490                                union iwreq_data *wrqu, char *b)
 491{
 492        struct r8192_priv *priv = rtllib_priv(dev);
 493        int ret;
 494
 495        if (priv->bHwRadioOff) {
 496                netdev_info(dev,
 497                            "=========>%s():hw radio off,or Rf state is eRfOff, return\n",
 498                            __func__);
 499                return 0;
 500        }
 501        mutex_lock(&priv->wx_mutex);
 502        ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
 503
 504        mutex_unlock(&priv->wx_mutex);
 505
 506        return ret;
 507}
 508
 509static int _rtl92e_wx_get_essid(struct net_device *dev,
 510                                struct iw_request_info *a,
 511                                union iwreq_data *wrqu, char *b)
 512{
 513        int ret;
 514        struct r8192_priv *priv = rtllib_priv(dev);
 515
 516        mutex_lock(&priv->wx_mutex);
 517
 518        ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
 519
 520        mutex_unlock(&priv->wx_mutex);
 521
 522        return ret;
 523}
 524
 525static int _rtl92e_wx_set_nick(struct net_device *dev,
 526                               struct iw_request_info *info,
 527                               union iwreq_data *wrqu, char *extra)
 528{
 529        struct r8192_priv *priv = rtllib_priv(dev);
 530
 531        if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 532                return -E2BIG;
 533        mutex_lock(&priv->wx_mutex);
 534        wrqu->data.length = min_t(size_t, wrqu->data.length,
 535                                  sizeof(priv->nick));
 536        memset(priv->nick, 0, sizeof(priv->nick));
 537        memcpy(priv->nick, extra, wrqu->data.length);
 538        mutex_unlock(&priv->wx_mutex);
 539        return 0;
 540}
 541
 542static int _rtl92e_wx_get_nick(struct net_device *dev,
 543                               struct iw_request_info *info,
 544                               union iwreq_data *wrqu, char *extra)
 545{
 546        struct r8192_priv *priv = rtllib_priv(dev);
 547
 548        mutex_lock(&priv->wx_mutex);
 549        wrqu->data.length = strlen(priv->nick);
 550        memcpy(extra, priv->nick, wrqu->data.length);
 551        wrqu->data.flags = 1;   /* active */
 552        mutex_unlock(&priv->wx_mutex);
 553        return 0;
 554}
 555
 556static int _rtl92e_wx_set_freq(struct net_device *dev,
 557                               struct iw_request_info *a,
 558                               union iwreq_data *wrqu, char *b)
 559{
 560        int ret;
 561        struct r8192_priv *priv = rtllib_priv(dev);
 562
 563        if (priv->bHwRadioOff)
 564                return 0;
 565
 566        mutex_lock(&priv->wx_mutex);
 567
 568        ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
 569
 570        mutex_unlock(&priv->wx_mutex);
 571        return ret;
 572}
 573
 574static int _rtl92e_wx_get_name(struct net_device *dev,
 575                               struct iw_request_info *info,
 576                               union iwreq_data *wrqu, char *extra)
 577{
 578        struct r8192_priv *priv = rtllib_priv(dev);
 579
 580        return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra);
 581}
 582
 583static int _rtl92e_wx_set_frag(struct net_device *dev,
 584                               struct iw_request_info *info,
 585                               union iwreq_data *wrqu, char *extra)
 586{
 587        struct r8192_priv *priv = rtllib_priv(dev);
 588
 589        if (priv->bHwRadioOff)
 590                return 0;
 591
 592        if (wrqu->frag.disabled)
 593                priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
 594        else {
 595                if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
 596                    wrqu->frag.value > MAX_FRAG_THRESHOLD)
 597                        return -EINVAL;
 598
 599                priv->rtllib->fts = wrqu->frag.value & ~0x1;
 600        }
 601
 602        return 0;
 603}
 604
 605static int _rtl92e_wx_get_frag(struct net_device *dev,
 606                               struct iw_request_info *info,
 607                               union iwreq_data *wrqu, char *extra)
 608{
 609        struct r8192_priv *priv = rtllib_priv(dev);
 610
 611        wrqu->frag.value = priv->rtllib->fts;
 612        wrqu->frag.fixed = 0;   /* no auto select */
 613        wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
 614
 615        return 0;
 616}
 617
 618static int _rtl92e_wx_set_wap(struct net_device *dev,
 619                              struct iw_request_info *info,
 620                              union iwreq_data *awrq, char *extra)
 621{
 622        int ret;
 623        struct r8192_priv *priv = rtllib_priv(dev);
 624
 625        if (priv->bHwRadioOff)
 626                return 0;
 627
 628        mutex_lock(&priv->wx_mutex);
 629
 630        ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
 631
 632        mutex_unlock(&priv->wx_mutex);
 633
 634        return ret;
 635}
 636
 637static int _rtl92e_wx_get_wap(struct net_device *dev,
 638                              struct iw_request_info *info,
 639                              union iwreq_data *wrqu, char *extra)
 640{
 641        struct r8192_priv *priv = rtllib_priv(dev);
 642
 643        return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra);
 644}
 645
 646static int _rtl92e_wx_get_enc(struct net_device *dev,
 647                              struct iw_request_info *info,
 648                              union iwreq_data *wrqu, char *key)
 649{
 650        struct r8192_priv *priv = rtllib_priv(dev);
 651
 652        return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key);
 653}
 654
 655static int _rtl92e_wx_set_enc(struct net_device *dev,
 656                              struct iw_request_info *info,
 657                              union iwreq_data *wrqu, char *key)
 658{
 659        struct r8192_priv *priv = rtllib_priv(dev);
 660        int ret;
 661
 662        struct rtllib_device *ieee = priv->rtllib;
 663        u32 hwkey[4] = {0, 0, 0, 0};
 664        u8 mask = 0xff;
 665        u32 key_idx = 0;
 666        u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 667                             {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
 668                             {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
 669                             {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
 670        int i;
 671
 672        if (priv->bHwRadioOff)
 673                return 0;
 674
 675        if (!priv->up)
 676                return -ENETDOWN;
 677
 678        priv->rtllib->wx_set_enc = 1;
 679        mutex_lock(&priv->rtllib->ips_mutex);
 680        rtl92e_ips_leave(dev);
 681        mutex_unlock(&priv->rtllib->ips_mutex);
 682        mutex_lock(&priv->wx_mutex);
 683
 684        RT_TRACE(COMP_SEC, "Setting SW wep key");
 685        ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
 686        mutex_unlock(&priv->wx_mutex);
 687
 688        if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
 689                ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
 690                rtl92e_cam_reset(dev);
 691                memset(priv->rtllib->swcamtable, 0,
 692                       sizeof(struct sw_cam_table) * 32);
 693                goto end_hw_sec;
 694        }
 695        if (wrqu->encoding.length != 0) {
 696                for (i = 0; i < 4; i++) {
 697                        hwkey[i] |=  key[4 * i + 0] & mask;
 698                        if (i == 1 && (4 * i + 1) == wrqu->encoding.length)
 699                                mask = 0x00;
 700                        if (i == 3 && (4 * i + 1) == wrqu->encoding.length)
 701                                mask = 0x00;
 702                        hwkey[i] |= (key[4 * i + 1] & mask) << 8;
 703                        hwkey[i] |= (key[4 * i + 2] & mask) << 16;
 704                        hwkey[i] |= (key[4 * i + 3] & mask) << 24;
 705                }
 706
 707                switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
 708                case 0:
 709                        key_idx = ieee->crypt_info.tx_keyidx;
 710                        break;
 711                case 1:
 712                        key_idx = 0;
 713                        break;
 714                case 2:
 715                        key_idx = 1;
 716                        break;
 717                case 3:
 718                        key_idx = 2;
 719                        break;
 720                case 4:
 721                        key_idx = 3;
 722                        break;
 723                default:
 724                        break;
 725                }
 726                if (wrqu->encoding.length == 0x5) {
 727                        ieee->pairwise_key_type = KEY_TYPE_WEP40;
 728                        rtl92e_enable_hw_security_config(dev);
 729                }
 730
 731                else if (wrqu->encoding.length == 0xd) {
 732                        ieee->pairwise_key_type = KEY_TYPE_WEP104;
 733                        rtl92e_enable_hw_security_config(dev);
 734                        rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104,
 735                                       zero_addr[key_idx], 0, hwkey);
 736                        rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104,
 737                                         zero_addr[key_idx], 0, hwkey, 0);
 738                } else {
 739                        netdev_info(dev,
 740                                    "wrong type in WEP, not WEP40 and WEP104\n");
 741                }
 742        }
 743
 744end_hw_sec:
 745        priv->rtllib->wx_set_enc = 0;
 746        return ret;
 747}
 748
 749static int _rtl92e_wx_set_scan_type(struct net_device *dev,
 750                                    struct iw_request_info *aa,
 751                                    union iwreq_data *wrqu, char *p)
 752{
 753        struct r8192_priv *priv = rtllib_priv(dev);
 754        int *parms = (int *)p;
 755        int mode = parms[0];
 756
 757        if (priv->bHwRadioOff)
 758                return 0;
 759
 760        priv->rtllib->active_scan = mode;
 761
 762        return 1;
 763}
 764
 765#define R8192_MAX_RETRY 255
 766static int _rtl92e_wx_set_retry(struct net_device *dev,
 767                                struct iw_request_info *info,
 768                                union iwreq_data *wrqu, char *extra)
 769{
 770        struct r8192_priv *priv = rtllib_priv(dev);
 771        int err = 0;
 772
 773        if (priv->bHwRadioOff)
 774                return 0;
 775
 776        mutex_lock(&priv->wx_mutex);
 777
 778        if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
 779            wrqu->retry.disabled) {
 780                err = -EINVAL;
 781                goto exit;
 782        }
 783        if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
 784                err = -EINVAL;
 785                goto exit;
 786        }
 787
 788        if (wrqu->retry.value > R8192_MAX_RETRY) {
 789                err = -EINVAL;
 790                goto exit;
 791        }
 792        if (wrqu->retry.flags & IW_RETRY_MAX)
 793                priv->retry_rts = wrqu->retry.value;
 794        else
 795                priv->retry_data = wrqu->retry.value;
 796
 797        rtl92e_commit(dev);
 798exit:
 799        mutex_unlock(&priv->wx_mutex);
 800
 801        return err;
 802}
 803
 804static int _rtl92e_wx_get_retry(struct net_device *dev,
 805                                struct iw_request_info *info,
 806                                union iwreq_data *wrqu, char *extra)
 807{
 808        struct r8192_priv *priv = rtllib_priv(dev);
 809
 810        wrqu->retry.disabled = 0; /* can't be disabled */
 811
 812        if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
 813            IW_RETRY_LIFETIME)
 814                return -EINVAL;
 815
 816        if (wrqu->retry.flags & IW_RETRY_MAX) {
 817                wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 818                wrqu->retry.value = priv->retry_rts;
 819        } else {
 820                wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
 821                wrqu->retry.value = priv->retry_data;
 822        }
 823        return 0;
 824}
 825
 826static int _rtl92e_wx_get_sens(struct net_device *dev,
 827                               struct iw_request_info *info,
 828                               union iwreq_data *wrqu, char *extra)
 829{
 830        struct r8192_priv *priv = rtllib_priv(dev);
 831
 832        if (priv->rf_set_sens == NULL)
 833                return -1; /* we have not this support for this radio */
 834        wrqu->sens.value = priv->sens;
 835        return 0;
 836}
 837
 838static int _rtl92e_wx_set_sens(struct net_device *dev,
 839                               struct iw_request_info *info,
 840                               union iwreq_data *wrqu, char *extra)
 841{
 842        struct r8192_priv *priv = rtllib_priv(dev);
 843
 844        short err = 0;
 845
 846        if (priv->bHwRadioOff)
 847                return 0;
 848
 849        mutex_lock(&priv->wx_mutex);
 850        if (priv->rf_set_sens == NULL) {
 851                err = -1; /* we have not this support for this radio */
 852                goto exit;
 853        }
 854        if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
 855                priv->sens = wrqu->sens.value;
 856        else
 857                err = -EINVAL;
 858
 859exit:
 860        mutex_unlock(&priv->wx_mutex);
 861
 862        return err;
 863}
 864
 865static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
 866                                     struct iw_request_info *info,
 867                                     union iwreq_data *wrqu, char *extra)
 868{
 869        int ret = 0;
 870        struct r8192_priv *priv = rtllib_priv(dev);
 871        struct rtllib_device *ieee = priv->rtllib;
 872
 873        if (priv->bHwRadioOff)
 874                return 0;
 875
 876        mutex_lock(&priv->wx_mutex);
 877
 878        priv->rtllib->wx_set_enc = 1;
 879        mutex_lock(&priv->rtllib->ips_mutex);
 880        rtl92e_ips_leave(dev);
 881        mutex_unlock(&priv->rtllib->ips_mutex);
 882
 883        ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
 884        {
 885                const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 886                const u8 zero[ETH_ALEN] = {0};
 887                u32 key[4] = {0};
 888                struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 889                struct iw_point *encoding = &wrqu->encoding;
 890                u8 idx = 0, alg = 0, group = 0;
 891
 892                if ((encoding->flags & IW_ENCODE_DISABLED) ||
 893                     ext->alg == IW_ENCODE_ALG_NONE) {
 894                        ieee->pairwise_key_type = ieee->group_key_type
 895                                                = KEY_TYPE_NA;
 896                        rtl92e_cam_reset(dev);
 897                        memset(priv->rtllib->swcamtable, 0,
 898                               sizeof(struct sw_cam_table) * 32);
 899                        goto end_hw_sec;
 900                }
 901                alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP :
 902                      ext->alg;
 903                idx = encoding->flags & IW_ENCODE_INDEX;
 904                if (idx)
 905                        idx--;
 906                group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
 907
 908                if ((!group) || (ieee->iw_mode == IW_MODE_ADHOC) ||
 909                    (alg ==  KEY_TYPE_WEP40)) {
 910                        if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
 911                                alg = KEY_TYPE_WEP104;
 912                        ieee->pairwise_key_type = alg;
 913                        rtl92e_enable_hw_security_config(dev);
 914                }
 915                memcpy((u8 *)key, ext->key, 16);
 916
 917                if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
 918                        if (ext->key_len == 13)
 919                                ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
 920                        rtl92e_set_key(dev, idx, idx, alg, zero, 0, key);
 921                        rtl92e_set_swcam(dev, idx, idx, alg, zero, 0, key, 0);
 922                } else if (group) {
 923                        ieee->group_key_type = alg;
 924                        rtl92e_set_key(dev, idx, idx, alg, broadcast_addr, 0,
 925                                       key);
 926                        rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, 0,
 927                                         key, 0);
 928                } else {
 929                        if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
 930                             ieee->pHTInfo->bCurrentHTSupport)
 931                                rtl92e_writeb(dev, 0x173, 1);
 932                        rtl92e_set_key(dev, 4, idx, alg,
 933                                       (u8 *)ieee->ap_mac_addr, 0, key);
 934                        rtl92e_set_swcam(dev, 4, idx, alg,
 935                                         (u8 *)ieee->ap_mac_addr, 0, key, 0);
 936                }
 937        }
 938
 939end_hw_sec:
 940        priv->rtllib->wx_set_enc = 0;
 941        mutex_unlock(&priv->wx_mutex);
 942        return ret;
 943}
 944
 945static int _rtl92e_wx_set_auth(struct net_device *dev,
 946                               struct iw_request_info *info,
 947                               union iwreq_data *data, char *extra)
 948{
 949        int ret = 0;
 950
 951        struct r8192_priv *priv = rtllib_priv(dev);
 952
 953        if (priv->bHwRadioOff)
 954                return 0;
 955
 956        mutex_lock(&priv->wx_mutex);
 957        ret = rtllib_wx_set_auth(priv->rtllib, info, &data->param, extra);
 958        mutex_unlock(&priv->wx_mutex);
 959        return ret;
 960}
 961
 962static int _rtl92e_wx_set_mlme(struct net_device *dev,
 963                               struct iw_request_info *info,
 964                               union iwreq_data *wrqu, char *extra)
 965{
 966        int ret = 0;
 967
 968        struct r8192_priv *priv = rtllib_priv(dev);
 969
 970        if (priv->bHwRadioOff)
 971                return 0;
 972
 973        mutex_lock(&priv->wx_mutex);
 974        ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
 975        mutex_unlock(&priv->wx_mutex);
 976        return ret;
 977}
 978
 979static int _rtl92e_wx_set_gen_ie(struct net_device *dev,
 980                                 struct iw_request_info *info,
 981                                 union iwreq_data *data, char *extra)
 982{
 983        int ret = 0;
 984
 985        struct r8192_priv *priv = rtllib_priv(dev);
 986
 987        if (priv->bHwRadioOff)
 988                return 0;
 989
 990        mutex_lock(&priv->wx_mutex);
 991        ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
 992        mutex_unlock(&priv->wx_mutex);
 993        return ret;
 994}
 995
 996static int _rtl92e_wx_get_gen_ie(struct net_device *dev,
 997                                 struct iw_request_info *info,
 998                                 union iwreq_data *data, char *extra)
 999{
1000        int ret = 0;
1001        struct r8192_priv *priv = rtllib_priv(dev);
1002        struct rtllib_device *ieee = priv->rtllib;
1003
1004        if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
1005                data->data.length = 0;
1006                return 0;
1007        }
1008
1009        if (data->data.length < ieee->wpa_ie_len)
1010                return -E2BIG;
1011
1012        data->data.length = ieee->wpa_ie_len;
1013        memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
1014        return ret;
1015}
1016
1017#define OID_RT_INTEL_PROMISCUOUS_MODE   0xFF0101F6
1018
1019static int _rtl92e_wx_set_promisc_mode(struct net_device *dev,
1020                                       struct iw_request_info *info,
1021                                       union iwreq_data *wrqu, char *extra)
1022{
1023        struct r8192_priv *priv = rtllib_priv(dev);
1024        struct rtllib_device *ieee = priv->rtllib;
1025
1026        u32 info_buf[3];
1027
1028        u32 oid;
1029        u32 bPromiscuousOn;
1030        u32 bFilterSourceStationFrame;
1031
1032        if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf)))
1033                return -EFAULT;
1034
1035        oid = info_buf[0];
1036        bPromiscuousOn = info_buf[1];
1037        bFilterSourceStationFrame = info_buf[2];
1038
1039        if (oid == OID_RT_INTEL_PROMISCUOUS_MODE) {
1040                ieee->IntelPromiscuousModeInfo.bPromiscuousOn =
1041                                        (bPromiscuousOn) ? (true) : (false);
1042                ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame =
1043                        (bFilterSourceStationFrame) ? (true) : (false);
1044                (bPromiscuousOn) ?
1045                (rtllib_EnableIntelPromiscuousMode(dev, false)) :
1046                (rtllib_DisableIntelPromiscuousMode(dev, false));
1047
1048                netdev_info(dev,
1049                            "=======>%s(), on = %d, filter src sta = %d\n",
1050                            __func__, bPromiscuousOn,
1051                            bFilterSourceStationFrame);
1052        } else {
1053                return -1;
1054        }
1055
1056        return 0;
1057}
1058
1059static int _rtl92e_wx_get_promisc_mode(struct net_device *dev,
1060                                       struct iw_request_info *info,
1061                                       union iwreq_data *wrqu, char *extra)
1062{
1063        struct r8192_priv *priv = rtllib_priv(dev);
1064        struct rtllib_device *ieee = priv->rtllib;
1065
1066        mutex_lock(&priv->wx_mutex);
1067
1068        snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d",
1069                 ieee->IntelPromiscuousModeInfo.bPromiscuousOn,
1070                 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame);
1071        wrqu->data.length = strlen(extra) + 1;
1072
1073        mutex_unlock(&priv->wx_mutex);
1074
1075        return 0;
1076}
1077
1078#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT)
1079static iw_handler r8192_wx_handlers[] = {
1080        [IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name,
1081        [IW_IOCTL(SIOCSIWFREQ)] = _rtl92e_wx_set_freq,
1082        [IW_IOCTL(SIOCGIWFREQ)] = _rtl92e_wx_get_freq,
1083        [IW_IOCTL(SIOCSIWMODE)] = _rtl92e_wx_set_mode,
1084        [IW_IOCTL(SIOCGIWMODE)] = _rtl92e_wx_get_mode,
1085        [IW_IOCTL(SIOCSIWSENS)] = _rtl92e_wx_set_sens,
1086        [IW_IOCTL(SIOCGIWSENS)] = _rtl92e_wx_get_sens,
1087        [IW_IOCTL(SIOCGIWRANGE)] = _rtl92e_wx_get_range,
1088        [IW_IOCTL(SIOCSIWAP)] = _rtl92e_wx_set_wap,
1089        [IW_IOCTL(SIOCGIWAP)] = _rtl92e_wx_get_wap,
1090        [IW_IOCTL(SIOCSIWSCAN)] = _rtl92e_wx_set_scan,
1091        [IW_IOCTL(SIOCGIWSCAN)] = _rtl92e_wx_get_scan,
1092        [IW_IOCTL(SIOCSIWESSID)] = _rtl92e_wx_set_essid,
1093        [IW_IOCTL(SIOCGIWESSID)] = _rtl92e_wx_get_essid,
1094        [IW_IOCTL(SIOCSIWNICKN)] = _rtl92e_wx_set_nick,
1095        [IW_IOCTL(SIOCGIWNICKN)] = _rtl92e_wx_get_nick,
1096        [IW_IOCTL(SIOCSIWRATE)] = _rtl92e_wx_set_rate,
1097        [IW_IOCTL(SIOCGIWRATE)] = _rtl92e_wx_get_rate,
1098        [IW_IOCTL(SIOCSIWRTS)] = _rtl92e_wx_set_rts,
1099        [IW_IOCTL(SIOCGIWRTS)] = _rtl92e_wx_get_rts,
1100        [IW_IOCTL(SIOCSIWFRAG)] = _rtl92e_wx_set_frag,
1101        [IW_IOCTL(SIOCGIWFRAG)] = _rtl92e_wx_get_frag,
1102        [IW_IOCTL(SIOCSIWRETRY)] = _rtl92e_wx_set_retry,
1103        [IW_IOCTL(SIOCGIWRETRY)] = _rtl92e_wx_get_retry,
1104        [IW_IOCTL(SIOCSIWENCODE)] = _rtl92e_wx_set_enc,
1105        [IW_IOCTL(SIOCGIWENCODE)] = _rtl92e_wx_get_enc,
1106        [IW_IOCTL(SIOCSIWPOWER)] = _rtl92e_wx_set_power,
1107        [IW_IOCTL(SIOCGIWPOWER)] = _rtl92e_wx_get_power,
1108        [IW_IOCTL(SIOCSIWGENIE)] = _rtl92e_wx_set_gen_ie,
1109        [IW_IOCTL(SIOCGIWGENIE)] = _rtl92e_wx_get_gen_ie,
1110        [IW_IOCTL(SIOCSIWMLME)] = _rtl92e_wx_set_mlme,
1111        [IW_IOCTL(SIOCSIWAUTH)] = _rtl92e_wx_set_auth,
1112        [IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext,
1113};
1114
1115/* the following rule need to be following,
1116 * Odd : get (world access),
1117 * even : set (root access)
1118 */
1119static const struct iw_priv_args r8192_private_args[] = {
1120        {
1121                SIOCIWFIRSTPRIV + 0x0,
1122                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag"
1123        }, {
1124                SIOCIWFIRSTPRIV + 0x1,
1125                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1126        }, {
1127                SIOCIWFIRSTPRIV + 0x2,
1128                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1129        }, {
1130                SIOCIWFIRSTPRIV + 0x3,
1131                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1132        }, {
1133                SIOCIWFIRSTPRIV + 0x6,
1134                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
1135                "set_power"
1136        }, {
1137                SIOCIWFIRSTPRIV + 0xa,
1138                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
1139                "lps_interv"
1140        }, {
1141                SIOCIWFIRSTPRIV + 0xb,
1142                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
1143                "lps_force"
1144        }, {
1145                SIOCIWFIRSTPRIV + 0x16,
1146                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc"
1147        }, {
1148                SIOCIWFIRSTPRIV + 0x17,
1149                0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc"
1150        }
1151
1152};
1153
1154static iw_handler r8192_private_handler[] = {
1155        (iw_handler)_rtl92e_wx_set_debug,   /*SIOCIWSECONDPRIV*/
1156        (iw_handler)_rtl92e_wx_set_scan_type,
1157        (iw_handler)_rtl92e_wx_set_rawtx,
1158        (iw_handler)_rtl92e_wx_force_reset,
1159        (iw_handler)NULL,
1160        (iw_handler)NULL,
1161        (iw_handler)_rtl92e_wx_adapter_power_status,
1162        (iw_handler)NULL,
1163        (iw_handler)NULL,
1164        (iw_handler)NULL,
1165        (iw_handler)_rtl92e_wx_set_lps_awake_interval,
1166        (iw_handler)_rtl92e_wx_set_force_lps,
1167        (iw_handler)NULL,
1168        (iw_handler)NULL,
1169        (iw_handler)NULL,
1170        (iw_handler)NULL,
1171        (iw_handler)NULL,
1172        (iw_handler)NULL,
1173        (iw_handler)NULL,
1174        (iw_handler)NULL,
1175        (iw_handler)NULL,
1176        (iw_handler)NULL,
1177        (iw_handler)_rtl92e_wx_set_promisc_mode,
1178        (iw_handler)_rtl92e_wx_get_promisc_mode,
1179};
1180
1181static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
1182{
1183        struct r8192_priv *priv = rtllib_priv(dev);
1184        struct rtllib_device *ieee = priv->rtllib;
1185        struct iw_statistics *wstats = &priv->wstats;
1186        int tmp_level = 0;
1187        int tmp_qual = 0;
1188        int tmp_noise = 0;
1189
1190        if (ieee->state < RTLLIB_LINKED) {
1191                wstats->qual.qual = 10;
1192                wstats->qual.level = 0;
1193                wstats->qual.noise = 0x100 - 100;       /* -100 dBm */
1194                wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1195                return wstats;
1196        }
1197
1198        tmp_level = (&ieee->current_network)->stats.rssi;
1199        tmp_qual = (&ieee->current_network)->stats.signal;
1200        tmp_noise = (&ieee->current_network)->stats.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
1209const struct iw_handler_def r8192_wx_handlers_def = {
1210        .standard = r8192_wx_handlers,
1211        .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1212        .private = r8192_private_handler,
1213        .num_private = ARRAY_SIZE(r8192_private_handler),
1214        .num_private_args = sizeof(r8192_private_args) /
1215                            sizeof(struct iw_priv_args),
1216        .get_wireless_stats = _rtl92e_get_wireless_stats,
1217        .private_args = (struct iw_priv_args *)r8192_private_args,
1218};
1219