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