linux/drivers/staging/rtl8187se/r8180_wx.c
<<
>>
Prefs
   1/*
   2        This file contains wireless extension handlers.
   3
   4        This is part of rtl8180 OpenSource driver.
   5        Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
   6        Released under the terms of GPL (General Public Licence)
   7
   8        Parts of this driver are based on the GPL part
   9        of the official realtek driver.
  10
  11        Parts of this driver are based on the rtl8180 driver skeleton
  12        from Patric Schenke & Andres Salomon.
  13
  14        Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  15
  16        We want to thanks the Authors of those projects and the Ndiswrapper
  17        project Authors.
  18*/
  19
  20
  21#include "r8180.h"
  22#include "r8180_hw.h"
  23
  24#include "ieee80211/dot11d.h"
  25
  26u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
  27        6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
  28
  29#define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
  30
  31static CHANNEL_LIST DefaultChannelPlan[] = {
  32        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},              /* FCC */
  33        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},                                              /* IC */
  34        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},      /* ETSI */
  35        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},      /* Spain. Change to ETSI. */
  36        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},      /* France. Change to ETSI. */
  37        {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},                                              /* MKK */
  38        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},  /* MKK1 */
  39        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},      /* Israel */
  40        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},                      /* For 11a , TELEC */
  41        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}                                   /* For Global Domain. 1-11:active scan, 12-14 passive scan.*/   /* +YJ, 080626 */
  42};
  43static int r8180_wx_get_freq(struct net_device *dev,
  44                             struct iw_request_info *a,
  45                             union iwreq_data *wrqu, char *b)
  46{
  47        struct r8180_priv *priv = ieee80211_priv(dev);
  48
  49        return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
  50}
  51
  52
  53int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
  54                     union iwreq_data *wrqu, char *key)
  55{
  56        struct r8180_priv *priv = ieee80211_priv(dev);
  57        struct iw_point *erq = &(wrqu->encoding);
  58
  59        if (priv->ieee80211->bHwRadioOff)
  60                return 0;
  61
  62        if (erq->length > 0) {
  63                u32* tkey = (u32*) key;
  64                priv->key0[0] = tkey[0];
  65                priv->key0[1] = tkey[1];
  66                priv->key0[2] = tkey[2];
  67                priv->key0[3] = tkey[3] & 0xff;
  68                DMESG("Setting wep key to %x %x %x %x",
  69                      tkey[0], tkey[1], tkey[2], tkey[3]);
  70                rtl8180_set_hw_wep(dev);
  71        }
  72        return 0;
  73}
  74
  75
  76static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
  77                          union iwreq_data *wrqu, char *b)
  78{
  79        int *parms = (int *)b;
  80        int bi = parms[0];
  81
  82        struct r8180_priv *priv = ieee80211_priv(dev);
  83
  84        if (priv->ieee80211->bHwRadioOff)
  85                return 0;
  86
  87        down(&priv->wx_sem);
  88        DMESG("setting beacon interval to %x", bi);
  89
  90        priv->ieee80211->current_network.beacon_interval = bi;
  91        rtl8180_commit(dev);
  92        up(&priv->wx_sem);
  93
  94        return 0;
  95}
  96
  97
  98
  99static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
 100                             union iwreq_data *wrqu, char *b)
 101{
 102        struct r8180_priv *priv = ieee80211_priv(dev);
 103        return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
 104}
 105
 106
 107
 108static int r8180_wx_get_rate(struct net_device *dev,
 109                             struct iw_request_info *info,
 110                             union iwreq_data *wrqu, char *extra)
 111{
 112        struct r8180_priv *priv = ieee80211_priv(dev);
 113        return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
 114}
 115
 116
 117
 118static int r8180_wx_set_rate(struct net_device *dev,
 119                             struct iw_request_info *info,
 120                             union iwreq_data *wrqu, char *extra)
 121{
 122        int ret;
 123        struct r8180_priv *priv = ieee80211_priv(dev);
 124
 125
 126        if (priv->ieee80211->bHwRadioOff)
 127                return 0;
 128
 129        down(&priv->wx_sem);
 130
 131        ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
 132
 133        up(&priv->wx_sem);
 134
 135        return ret;
 136}
 137
 138
 139static int r8180_wx_set_crcmon(struct net_device *dev,
 140                               struct iw_request_info *info,
 141                               union iwreq_data *wrqu, char *extra)
 142{
 143        struct r8180_priv *priv = ieee80211_priv(dev);
 144        int *parms = (int *)extra;
 145        int enable = (parms[0] > 0);
 146        short prev = priv->crcmon;
 147
 148
 149        if (priv->ieee80211->bHwRadioOff)
 150                return 0;
 151
 152        down(&priv->wx_sem);
 153
 154        if (enable)
 155                priv->crcmon = 1;
 156        else
 157                priv->crcmon = 0;
 158
 159        DMESG("bad CRC in monitor mode are %s",
 160              priv->crcmon ? "accepted" : "rejected");
 161
 162        if (prev != priv->crcmon && priv->up)   {
 163                rtl8180_down(dev);
 164                rtl8180_up(dev);
 165        }
 166
 167        up(&priv->wx_sem);
 168
 169        return 0;
 170}
 171
 172
 173static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
 174                             union iwreq_data *wrqu, char *b)
 175{
 176        struct r8180_priv *priv = ieee80211_priv(dev);
 177        int ret;
 178
 179
 180        if (priv->ieee80211->bHwRadioOff)
 181                return 0;
 182
 183        down(&priv->wx_sem);
 184        if (priv->bInactivePs)  {
 185                if (wrqu->mode == IW_MODE_ADHOC)
 186                        IPSLeave(dev);
 187        }
 188        ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
 189
 190        up(&priv->wx_sem);
 191        return ret;
 192}
 193
 194/* YJ,add,080819,for hidden ap */
 195struct  iw_range_with_scan_capa {
 196                /* Informative stuff (to choose between different interface) */
 197
 198                __u32           throughput; /* To give an idea... */
 199
 200                /* In theory this value should be the maximum benchmarked
 201                 * TCP/IP throughput, because with most of these devices the
 202                 * bit rate is meaningless (overhead an co) to estimate how
 203                 * fast the connection will go and pick the fastest one.
 204                 * I suggest people to play with Netperf or any benchmark...
 205                 */
 206
 207                /* NWID (or domain id)  */
 208                __u32           min_nwid; /* Minimal NWID we are able to set */
 209                __u32                   max_nwid; /* Maximal NWID we are able to set */
 210
 211                /* Old Frequency (backward compat - moved lower ) */
 212                __u16                   old_num_channels;
 213                __u8                    old_num_frequency;
 214
 215                /* Scan capabilities */
 216                __u8                    scan_capa;
 217};
 218/* YJ,add,080819,for hidden ap */
 219
 220
 221static int rtl8180_wx_get_range(struct net_device *dev,
 222                                struct iw_request_info *info,
 223                                union iwreq_data *wrqu, char *extra)
 224{
 225        struct iw_range *range = (struct iw_range *)extra;
 226        struct r8180_priv *priv = ieee80211_priv(dev);
 227        u16 val;
 228        int i;
 229
 230        wrqu->data.length = sizeof(*range);
 231        memset(range, 0, sizeof(*range));
 232
 233        /* Let's try to keep this struct in the same order as in
 234         * linux/include/wireless.h
 235         */
 236
 237        /* TODO: See what values we can set, and remove the ones we can't
 238         * set, or fill them with some default data.
 239         */
 240
 241        /* ~5 Mb/s real (802.11b) */
 242        range->throughput = 5 * 1000 * 1000;
 243
 244        /* TODO: Not used in 802.11b?   */
 245/*      range->min_nwid; */     /* Minimal NWID we are able to set */
 246        /* TODO: Not used in 802.11b?   */
 247/*      range->max_nwid; */     /* Maximal NWID we are able to set */
 248
 249                /* Old Frequency (backward compat - moved lower ) */
 250/*      range->old_num_channels; */
 251/*      range->old_num_frequency; */
 252/*      range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
 253        if (priv->rf_set_sens != NULL)
 254                range->sensitivity = priv->max_sens;    /* signal level threshold range */
 255
 256        range->max_qual.qual = 100;
 257        /* TODO: Find real max RSSI and stick here */
 258        range->max_qual.level = 0;
 259        range->max_qual.noise = -98;
 260        range->max_qual.updated = 7; /* Updated all three */
 261
 262        range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
 263        /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 264        range->avg_qual.level = 20 + -98;
 265        range->avg_qual.noise = 0;
 266        range->avg_qual.updated = 7; /* Updated all three */
 267
 268        range->num_bitrates = RATE_COUNT;
 269
 270        for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
 271                range->bitrate[i] = rtl8180_rates[i];
 272
 273        range->min_frag = MIN_FRAG_THRESHOLD;
 274        range->max_frag = MAX_FRAG_THRESHOLD;
 275
 276        range->pm_capa = 0;
 277
 278        range->we_version_compiled = WIRELESS_EXT;
 279        range->we_version_source = 16;
 280
 281                range->num_channels = 14;
 282
 283        for (i = 0, val = 0; i < 14; i++) {
 284
 285                /* Include only legal frequencies for some countries */
 286                if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
 287                                range->freq[val].i = i + 1;
 288                        range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
 289                        range->freq[val].e = 1;
 290                        val++;
 291                } else {
 292                        /* FIXME: do we need to set anything for channels */
 293                        /* we don't use ? */
 294                }
 295
 296                if (val == IW_MAX_FREQUENCIES)
 297                break;
 298        }
 299
 300        range->num_frequency = val;
 301        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 302                                                IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 303
 304        return 0;
 305}
 306
 307
 308static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 309                             union iwreq_data *wrqu, char *b)
 310{
 311        struct r8180_priv *priv = ieee80211_priv(dev);
 312        int ret;
 313        struct ieee80211_device* ieee = priv->ieee80211;
 314
 315
 316        if (priv->ieee80211->bHwRadioOff)
 317                return 0;
 318
 319        if (wrqu->data.flags & IW_SCAN_THIS_ESSID)      {
 320                struct iw_scan_req* req = (struct iw_scan_req*)b;
 321                if (req->essid_len)             {
 322                        ieee->current_network.ssid_len = req->essid_len;
 323                        memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
 324                }
 325        }
 326
 327        down(&priv->wx_sem);
 328        if (priv->up)   {
 329                priv->ieee80211->actscanning = true;
 330                if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED))  {
 331                        IPSLeave(dev);
 332                ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
 333                        ret = 0;
 334                }       else    {
 335                        /* prevent scan in BusyTraffic */
 336                        /* FIXME: Need to consider last scan time */
 337                        if ((priv->link_detect.bBusyTraffic) && (true)) {
 338                                ret = 0;
 339                                printk("Now traffic is busy, please try later!\n");
 340                        }       else
 341                                /* prevent scan in BusyTraffic,end */
 342                                ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
 343                }
 344        }       else
 345                        ret = -1;
 346
 347        up(&priv->wx_sem);
 348
 349        return ret;
 350}
 351
 352
 353static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
 354                             union iwreq_data *wrqu, char *b)
 355{
 356
 357        int ret;
 358        struct r8180_priv *priv = ieee80211_priv(dev);
 359
 360        down(&priv->wx_sem);
 361        if (priv->up)
 362                ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
 363        else
 364                ret = -1;
 365
 366        up(&priv->wx_sem);
 367        return ret;
 368}
 369
 370
 371static int r8180_wx_set_essid(struct net_device *dev,
 372                              struct iw_request_info *a,
 373                              union iwreq_data *wrqu, char *b)
 374{
 375        struct r8180_priv *priv = ieee80211_priv(dev);
 376
 377        int ret;
 378
 379        if (priv->ieee80211->bHwRadioOff)
 380                return 0;
 381
 382        down(&priv->wx_sem);
 383        if (priv->bInactivePs)
 384                IPSLeave(dev);
 385
 386        ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
 387
 388        up(&priv->wx_sem);
 389        return ret;
 390}
 391
 392
 393static int r8180_wx_get_essid(struct net_device *dev,
 394                              struct iw_request_info *a,
 395                              union iwreq_data *wrqu, char *b)
 396{
 397        int ret;
 398        struct r8180_priv *priv = ieee80211_priv(dev);
 399
 400        down(&priv->wx_sem);
 401
 402        ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
 403
 404        up(&priv->wx_sem);
 405
 406        return ret;
 407}
 408
 409
 410static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
 411                             union iwreq_data *wrqu, char *b)
 412{
 413        int ret;
 414        struct r8180_priv *priv = ieee80211_priv(dev);
 415
 416
 417        if (priv->ieee80211->bHwRadioOff)
 418                return 0;
 419
 420        down(&priv->wx_sem);
 421
 422        ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
 423
 424        up(&priv->wx_sem);
 425        return ret;
 426}
 427
 428
 429static int r8180_wx_get_name(struct net_device *dev,
 430                             struct iw_request_info *info,
 431                             union iwreq_data *wrqu, char *extra)
 432{
 433        struct r8180_priv *priv = ieee80211_priv(dev);
 434        return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
 435}
 436
 437static int r8180_wx_set_frag(struct net_device *dev,
 438                             struct iw_request_info *info,
 439                             union iwreq_data *wrqu, char *extra)
 440{
 441        struct r8180_priv *priv = ieee80211_priv(dev);
 442
 443        if (priv->ieee80211->bHwRadioOff)
 444                return 0;
 445
 446        if (wrqu->frag.disabled)
 447                priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
 448        else {
 449                if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
 450                    wrqu->frag.value > MAX_FRAG_THRESHOLD)
 451                        return -EINVAL;
 452
 453                priv->ieee80211->fts = wrqu->frag.value & ~0x1;
 454        }
 455
 456        return 0;
 457}
 458
 459
 460static int r8180_wx_get_frag(struct net_device *dev,
 461                             struct iw_request_info *info,
 462                             union iwreq_data *wrqu, char *extra)
 463{
 464        struct r8180_priv *priv = ieee80211_priv(dev);
 465
 466        wrqu->frag.value = priv->ieee80211->fts;
 467        wrqu->frag.fixed = 0;   /* no auto select */
 468        wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
 469
 470        return 0;
 471}
 472
 473
 474static int r8180_wx_set_wap(struct net_device *dev,
 475                         struct iw_request_info *info,
 476                         union iwreq_data *awrq,
 477                         char *extra)
 478{
 479        int ret;
 480        struct r8180_priv *priv = ieee80211_priv(dev);
 481
 482        if (priv->ieee80211->bHwRadioOff)
 483                return 0;
 484
 485        down(&priv->wx_sem);
 486
 487        ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
 488
 489        up(&priv->wx_sem);
 490        return ret;
 491
 492}
 493
 494
 495static int r8180_wx_get_wap(struct net_device *dev,
 496                            struct iw_request_info *info,
 497                            union iwreq_data *wrqu, char *extra)
 498{
 499        struct r8180_priv *priv = ieee80211_priv(dev);
 500
 501        return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
 502}
 503
 504
 505static int r8180_wx_set_enc(struct net_device *dev,
 506                            struct iw_request_info *info,
 507                            union iwreq_data *wrqu, char *key)
 508{
 509        struct r8180_priv *priv = ieee80211_priv(dev);
 510        int ret;
 511
 512        if (priv->ieee80211->bHwRadioOff)
 513                return 0;
 514
 515
 516        down(&priv->wx_sem);
 517
 518        if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key);
 519        else    {
 520                DMESG("Setting SW wep key");
 521                ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
 522        }
 523
 524        up(&priv->wx_sem);
 525        return ret;
 526}
 527
 528
 529static int r8180_wx_get_enc(struct net_device *dev,
 530                            struct iw_request_info *info,
 531                            union iwreq_data *wrqu, char *key)
 532{
 533        struct r8180_priv *priv = ieee80211_priv(dev);
 534
 535        return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
 536}
 537
 538
 539static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
 540        iwreq_data *wrqu, char *p)      {
 541
 542        struct r8180_priv *priv = ieee80211_priv(dev);
 543        int *parms = (int*)p;
 544        int mode = parms[0];
 545
 546        if (priv->ieee80211->bHwRadioOff)
 547                return 0;
 548
 549        priv->ieee80211->active_scan = mode;
 550
 551        return 1;
 552}
 553
 554static int r8180_wx_set_retry(struct net_device *dev,
 555                                struct iw_request_info *info,
 556                                union iwreq_data *wrqu, char *extra)
 557{
 558        struct r8180_priv *priv = ieee80211_priv(dev);
 559        int err = 0;
 560
 561        if (priv->ieee80211->bHwRadioOff)
 562                return 0;
 563
 564        down(&priv->wx_sem);
 565
 566        if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
 567            wrqu->retry.disabled)       {
 568                err = -EINVAL;
 569                goto exit;
 570        }
 571        if (!(wrqu->retry.flags & IW_RETRY_LIMIT))      {
 572                err = -EINVAL;
 573                goto exit;
 574        }
 575
 576        if (wrqu->retry.value > R8180_MAX_RETRY)        {
 577                err = -EINVAL;
 578                goto exit;
 579        }
 580        if (wrqu->retry.flags & IW_RETRY_MAX) {
 581                priv->retry_rts = wrqu->retry.value;
 582                DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
 583
 584        }       else {
 585                priv->retry_data = wrqu->retry.value;
 586                DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
 587        }
 588
 589        /* FIXME !
 590         * We might try to write directly the TX config register
 591         * or to restart just the (R)TX process.
 592         * I'm unsure if whole reset is really needed
 593         */
 594
 595        rtl8180_commit(dev);
 596exit:
 597        up(&priv->wx_sem);
 598
 599        return err;
 600}
 601
 602static int r8180_wx_get_retry(struct net_device *dev,
 603                                struct iw_request_info *info,
 604                                union iwreq_data *wrqu, char *extra)
 605{
 606        struct r8180_priv *priv = ieee80211_priv(dev);
 607
 608
 609        wrqu->retry.disabled = 0; /* can't be disabled */
 610
 611        if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
 612            IW_RETRY_LIFETIME)
 613                return -EINVAL;
 614
 615        if (wrqu->retry.flags & IW_RETRY_MAX) {
 616                wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 617                wrqu->retry.value = priv->retry_rts;
 618        } else {
 619                wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
 620                wrqu->retry.value = priv->retry_data;
 621        }
 622
 623        return 0;
 624}
 625
 626static int r8180_wx_get_sens(struct net_device *dev,
 627                                struct iw_request_info *info,
 628                                union iwreq_data *wrqu, char *extra)
 629{
 630        struct r8180_priv *priv = ieee80211_priv(dev);
 631        if (priv->rf_set_sens == NULL)
 632                return -1; /* we have not this support for this radio */
 633        wrqu->sens.value = priv->sens;
 634        return 0;
 635}
 636
 637
 638static int r8180_wx_set_sens(struct net_device *dev,
 639                                struct iw_request_info *info,
 640                                union iwreq_data *wrqu, char *extra)
 641{
 642
 643        struct r8180_priv *priv = ieee80211_priv(dev);
 644
 645        short err = 0;
 646
 647        if (priv->ieee80211->bHwRadioOff)
 648                return 0;
 649
 650        down(&priv->wx_sem);
 651        if (priv->rf_set_sens == NULL) {
 652                err = -1; /* we have not this support for this radio */
 653                goto exit;
 654        }
 655        if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
 656                priv->sens = wrqu->sens.value;
 657        else
 658                err = -EINVAL;
 659
 660exit:
 661        up(&priv->wx_sem);
 662
 663        return err;
 664}
 665
 666
 667static int r8180_wx_set_rawtx(struct net_device *dev,
 668                               struct iw_request_info *info,
 669                               union iwreq_data *wrqu, char *extra)
 670{
 671        struct r8180_priv *priv = ieee80211_priv(dev);
 672        int ret;
 673
 674        if (priv->ieee80211->bHwRadioOff)
 675                return 0;
 676
 677        down(&priv->wx_sem);
 678
 679        ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
 680
 681        up(&priv->wx_sem);
 682
 683        return ret;
 684
 685}
 686
 687static int r8180_wx_get_power(struct net_device *dev,
 688                               struct iw_request_info *info,
 689                               union iwreq_data *wrqu, char *extra)
 690{
 691        int ret;
 692        struct r8180_priv *priv = ieee80211_priv(dev);
 693
 694        down(&priv->wx_sem);
 695
 696        ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
 697
 698        up(&priv->wx_sem);
 699
 700        return ret;
 701}
 702
 703static int r8180_wx_set_power(struct net_device *dev,
 704                               struct iw_request_info *info,
 705                               union iwreq_data *wrqu, char *extra)
 706{
 707        int ret;
 708        struct r8180_priv *priv = ieee80211_priv(dev);
 709
 710
 711        if (priv->ieee80211->bHwRadioOff)
 712                return 0;
 713
 714        down(&priv->wx_sem);
 715        printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
 716        if (wrqu->power.disabled == 0) {
 717                wrqu->power.flags |= IW_POWER_ALL_R;
 718                wrqu->power.flags |= IW_POWER_TIMEOUT;
 719                wrqu->power.value = 1000;
 720        }
 721
 722        ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
 723
 724        up(&priv->wx_sem);
 725
 726        return ret;
 727}
 728
 729static int r8180_wx_set_rts(struct net_device *dev,
 730                             struct iw_request_info *info,
 731                             union iwreq_data *wrqu, char *extra)
 732{
 733        struct r8180_priv *priv = ieee80211_priv(dev);
 734
 735
 736        if (priv->ieee80211->bHwRadioOff)
 737                return 0;
 738
 739        if (wrqu->rts.disabled)
 740                priv->rts = DEFAULT_RTS_THRESHOLD;
 741        else {
 742                if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
 743                    wrqu->rts.value > MAX_RTS_THRESHOLD)
 744                        return -EINVAL;
 745
 746                priv->rts = wrqu->rts.value;
 747        }
 748
 749        return 0;
 750}
 751static int r8180_wx_get_rts(struct net_device *dev,
 752                             struct iw_request_info *info,
 753                             union iwreq_data *wrqu, char *extra)
 754{
 755        struct r8180_priv *priv = ieee80211_priv(dev);
 756
 757
 758
 759        wrqu->rts.value = priv->rts;
 760        wrqu->rts.fixed = 0;    /* no auto select */
 761        wrqu->rts.disabled = (wrqu->rts.value == 0);
 762
 763        return 0;
 764}
 765static int dummy(struct net_device *dev, struct iw_request_info *a,
 766                 union iwreq_data *wrqu, char *b)
 767{
 768        return -1;
 769}
 770
 771static int r8180_wx_get_iwmode(struct net_device *dev,
 772                               struct iw_request_info *info,
 773                               union iwreq_data *wrqu, char *extra)
 774{
 775        struct r8180_priv *priv = ieee80211_priv(dev);
 776        struct ieee80211_device *ieee;
 777        int ret = 0;
 778
 779
 780
 781        down(&priv->wx_sem);
 782
 783        ieee = priv->ieee80211;
 784
 785        strcpy(extra, "802.11");
 786        if (ieee->modulation & IEEE80211_CCK_MODULATION) {
 787                strcat(extra, "b");
 788                if (ieee->modulation & IEEE80211_OFDM_MODULATION)
 789                        strcat(extra, "/g");
 790        } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
 791                strcat(extra, "g");
 792
 793        up(&priv->wx_sem);
 794
 795        return ret;
 796}
 797static int r8180_wx_set_iwmode(struct net_device *dev,
 798                               struct iw_request_info *info,
 799                               union iwreq_data *wrqu, char *extra)
 800{
 801        struct r8180_priv *priv = ieee80211_priv(dev);
 802        struct ieee80211_device *ieee = priv->ieee80211;
 803        int *param = (int *)extra;
 804        int ret = 0;
 805        int modulation = 0, mode = 0;
 806
 807
 808        if (priv->ieee80211->bHwRadioOff)
 809                return 0;
 810
 811        down(&priv->wx_sem);
 812
 813        if (*param == 1) {
 814                modulation |= IEEE80211_CCK_MODULATION;
 815                mode = IEEE_B;
 816        printk(KERN_INFO "B mode!\n");
 817        } else if (*param == 2) {
 818                modulation |= IEEE80211_OFDM_MODULATION;
 819                mode = IEEE_G;
 820        printk(KERN_INFO "G mode!\n");
 821        } else if (*param == 3) {
 822                modulation |= IEEE80211_CCK_MODULATION;
 823                modulation |= IEEE80211_OFDM_MODULATION;
 824                mode = IEEE_B|IEEE_G;
 825        printk(KERN_INFO "B/G mode!\n");
 826        }
 827
 828        if (ieee->proto_started) {
 829                ieee80211_stop_protocol(ieee);
 830                ieee->mode = mode;
 831                ieee->modulation = modulation;
 832                ieee80211_start_protocol(ieee);
 833        } else {
 834                ieee->mode = mode;
 835                ieee->modulation = modulation;
 836        }
 837
 838        up(&priv->wx_sem);
 839
 840        return ret;
 841}
 842static int r8180_wx_get_preamble(struct net_device *dev,
 843                             struct iw_request_info *info,
 844                             union iwreq_data *wrqu, char *extra)
 845{
 846        struct r8180_priv *priv = ieee80211_priv(dev);
 847
 848
 849
 850        down(&priv->wx_sem);
 851
 852
 853
 854        *extra = (char) priv->plcp_preamble_mode;       /* 0:auto 1:short 2:long */
 855        up(&priv->wx_sem);
 856
 857        return 0;
 858}
 859static int r8180_wx_set_preamble(struct net_device *dev,
 860                             struct iw_request_info *info,
 861                             union iwreq_data *wrqu, char *extra)
 862{
 863        struct r8180_priv *priv = ieee80211_priv(dev);
 864        int ret = 0;
 865
 866
 867        if (priv->ieee80211->bHwRadioOff)
 868                return 0;
 869
 870        down(&priv->wx_sem);
 871        if (*extra < 0 || *extra > 2)
 872                ret = -1;
 873        else
 874                priv->plcp_preamble_mode = *((short *)extra) ;
 875
 876
 877
 878        up(&priv->wx_sem);
 879
 880        return ret;
 881}
 882static int r8180_wx_get_siglevel(struct net_device *dev,
 883                               struct iw_request_info *info,
 884                               union iwreq_data *wrqu, char *extra)
 885{
 886        struct r8180_priv *priv = ieee80211_priv(dev);
 887        int ret = 0;
 888
 889
 890
 891        down(&priv->wx_sem);
 892        /* Modify by hikaru 6.5 */
 893        *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
 894
 895
 896
 897        up(&priv->wx_sem);
 898
 899        return ret;
 900}
 901static int r8180_wx_get_sigqual(struct net_device *dev,
 902                               struct iw_request_info *info,
 903                               union iwreq_data *wrqu, char *extra)
 904{
 905        struct r8180_priv *priv = ieee80211_priv(dev);
 906        int ret = 0;
 907
 908
 909
 910        down(&priv->wx_sem);
 911        /* Modify by hikaru 6.5 */
 912        *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
 913
 914
 915
 916        up(&priv->wx_sem);
 917
 918        return ret;
 919}
 920static int r8180_wx_reset_stats(struct net_device *dev,
 921                                struct iw_request_info *info,
 922                                union iwreq_data *wrqu, char *extra)
 923{
 924        struct r8180_priv *priv = ieee80211_priv(dev);
 925        down(&priv->wx_sem);
 926
 927        priv->stats.txrdu = 0;
 928        priv->stats.rxrdu = 0;
 929        priv->stats.rxnolast = 0;
 930        priv->stats.rxnodata = 0;
 931        priv->stats.rxnopointer = 0;
 932        priv->stats.txnperr = 0;
 933        priv->stats.txresumed = 0;
 934        priv->stats.rxerr = 0;
 935        priv->stats.rxoverflow = 0;
 936        priv->stats.rxint = 0;
 937
 938        priv->stats.txnpokint = 0;
 939        priv->stats.txhpokint = 0;
 940        priv->stats.txhperr = 0;
 941        priv->stats.ints = 0;
 942        priv->stats.shints = 0;
 943        priv->stats.txoverflow = 0;
 944        priv->stats.rxdmafail = 0;
 945        priv->stats.txbeacon = 0;
 946        priv->stats.txbeaconerr = 0;
 947        priv->stats.txlpokint = 0;
 948        priv->stats.txlperr = 0;
 949        priv->stats.txretry = 0;/* 20060601 */
 950        priv->stats.rxcrcerrmin = 0 ;
 951        priv->stats.rxcrcerrmid = 0;
 952        priv->stats.rxcrcerrmax = 0;
 953        priv->stats.rxicverr = 0;
 954
 955        up(&priv->wx_sem);
 956
 957        return 0;
 958
 959}
 960static int r8180_wx_radio_on(struct net_device *dev,
 961                                struct iw_request_info *info,
 962                                union iwreq_data *wrqu, char *extra)
 963{
 964        struct r8180_priv *priv = ieee80211_priv(dev);
 965
 966        if (priv->ieee80211->bHwRadioOff)
 967                return 0;
 968
 969
 970        down(&priv->wx_sem);
 971        priv->rf_wakeup(dev);
 972
 973        up(&priv->wx_sem);
 974
 975        return 0;
 976
 977}
 978
 979static int r8180_wx_radio_off(struct net_device *dev,
 980                                struct iw_request_info *info,
 981                                union iwreq_data *wrqu, char *extra)
 982{
 983        struct r8180_priv *priv = ieee80211_priv(dev);
 984
 985        if (priv->ieee80211->bHwRadioOff)
 986                return 0;
 987
 988
 989        down(&priv->wx_sem);
 990        priv->rf_sleep(dev);
 991
 992        up(&priv->wx_sem);
 993
 994        return 0;
 995
 996}
 997static int r8180_wx_get_channelplan(struct net_device *dev,
 998                             struct iw_request_info *info,
 999                             union iwreq_data *wrqu, char *extra)
1000{
1001        struct r8180_priv *priv = ieee80211_priv(dev);
1002
1003
1004
1005        down(&priv->wx_sem);
1006        *extra = priv->channel_plan;
1007
1008
1009
1010        up(&priv->wx_sem);
1011
1012        return 0;
1013}
1014static int r8180_wx_set_channelplan(struct net_device *dev,
1015                             struct iw_request_info *info,
1016                             union iwreq_data *wrqu, char *extra)
1017{
1018        struct r8180_priv *priv = ieee80211_priv(dev);
1019        int *val = (int *)extra;
1020        int i;
1021        printk("-----in fun %s\n", __func__);
1022
1023        if (priv->ieee80211->bHwRadioOff)
1024                return 0;
1025
1026        /* unsigned long flags; */
1027        down(&priv->wx_sem);
1028        if (DefaultChannelPlan[*val].Len != 0)  {
1029                priv->channel_plan = *val;
1030                /* Clear old channel map 8 */
1031                for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1032                        GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1033
1034                /* Set new channel map */
1035                for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1036                        GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1037                
1038        }
1039        up(&priv->wx_sem);
1040
1041        return 0;
1042}
1043
1044static int r8180_wx_get_version(struct net_device *dev,
1045                               struct iw_request_info *info,
1046                               union iwreq_data *wrqu, char *extra)
1047{
1048        struct r8180_priv *priv = ieee80211_priv(dev);
1049        /* struct ieee80211_device *ieee; */
1050
1051        down(&priv->wx_sem);
1052        strcpy(extra, "1020.0808");
1053        up(&priv->wx_sem);
1054
1055        return 0;
1056}
1057
1058/* added by amy 080818 */
1059/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1060static int r8180_wx_set_forcerate(struct net_device *dev,
1061                             struct iw_request_info *info,
1062                             union iwreq_data *wrqu, char *extra)
1063{
1064        struct r8180_priv *priv = ieee80211_priv(dev);
1065        u8 forcerate = *extra;
1066
1067        down(&priv->wx_sem);
1068
1069        printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1070        if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1071                (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1072                (forcerate == 96) || (forcerate == 108))
1073        {
1074                priv->ForcedDataRate = 1;
1075                priv->ieee80211->rate = forcerate * 5;
1076        }       else if (forcerate == 0)        {
1077                priv->ForcedDataRate = 0;
1078                printk("OK! return rate adaptive\n");
1079        }       else
1080                        printk("ERR: wrong rate\n");
1081        up(&priv->wx_sem);
1082        return 0;
1083}
1084
1085static int r8180_wx_set_enc_ext(struct net_device *dev,
1086                                                                                struct iw_request_info *info,
1087                                                                                union iwreq_data *wrqu, char *extra)
1088{
1089
1090        struct r8180_priv *priv = ieee80211_priv(dev);
1091
1092        int ret = 0;
1093
1094        if (priv->ieee80211->bHwRadioOff)
1095                return 0;
1096
1097        down(&priv->wx_sem);
1098        ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1099        up(&priv->wx_sem);
1100        return ret;
1101
1102}
1103static int r8180_wx_set_auth(struct net_device *dev,
1104                             struct iw_request_info *info,
1105                             union iwreq_data *wrqu, char *extra)
1106{
1107        struct r8180_priv *priv = ieee80211_priv(dev);
1108        int ret = 0;
1109
1110        if (priv->ieee80211->bHwRadioOff)
1111                return 0;
1112
1113        down(&priv->wx_sem);
1114        ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1115        up(&priv->wx_sem);
1116        return ret;
1117}
1118
1119static int r8180_wx_set_mlme(struct net_device *dev,
1120                                                                                struct iw_request_info *info,
1121                                                                                union iwreq_data *wrqu, char *extra)
1122{
1123        int ret = 0;
1124        struct r8180_priv *priv = ieee80211_priv(dev);
1125
1126
1127        if (priv->ieee80211->bHwRadioOff)
1128                return 0;
1129
1130
1131        down(&priv->wx_sem);
1132#if 1
1133        ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1134#endif
1135        up(&priv->wx_sem);
1136        return ret;
1137}
1138static int r8180_wx_set_gen_ie(struct net_device *dev,
1139                               struct iw_request_info *info,
1140                               union iwreq_data *wrqu, char *extra)
1141{
1142        int ret = 0;
1143                struct r8180_priv *priv = ieee80211_priv(dev);
1144
1145
1146        if (priv->ieee80211->bHwRadioOff)
1147                return 0;
1148
1149                down(&priv->wx_sem);
1150#if 1
1151                ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1152#endif
1153                up(&priv->wx_sem);
1154                return ret;
1155
1156
1157}
1158static iw_handler r8180_wx_handlers[] = {
1159                NULL,                                   /* SIOCSIWCOMMIT */
1160                r8180_wx_get_name,                      /* SIOCGIWNAME */
1161                dummy,                                  /* SIOCSIWNWID */
1162                dummy,                                  /* SIOCGIWNWID */
1163                r8180_wx_set_freq,                      /* SIOCSIWFREQ */
1164                r8180_wx_get_freq,                      /* SIOCGIWFREQ */
1165                r8180_wx_set_mode,                      /* SIOCSIWMODE */
1166                r8180_wx_get_mode,                      /* SIOCGIWMODE */
1167                r8180_wx_set_sens,                      /* SIOCSIWSENS */
1168                r8180_wx_get_sens,                      /* SIOCGIWSENS */
1169                NULL,                                   /* SIOCSIWRANGE */
1170                rtl8180_wx_get_range,                   /* SIOCGIWRANGE */
1171                NULL,                                   /* SIOCSIWPRIV */
1172                NULL,                                   /* SIOCGIWPRIV */
1173                NULL,                                   /* SIOCSIWSTATS */
1174                NULL,                                   /* SIOCGIWSTATS */
1175                dummy,                                  /* SIOCSIWSPY */
1176                dummy,                                  /* SIOCGIWSPY */
1177                NULL,                                   /* SIOCGIWTHRSPY */
1178                NULL,                                   /* SIOCWIWTHRSPY */
1179                r8180_wx_set_wap,                       /* SIOCSIWAP */
1180                r8180_wx_get_wap,                       /* SIOCGIWAP */
1181                r8180_wx_set_mlme,                      /* SIOCSIWMLME*/
1182                dummy,                                  /* SIOCGIWAPLIST -- deprecated */
1183                r8180_wx_set_scan,                      /* SIOCSIWSCAN */
1184                r8180_wx_get_scan,                      /* SIOCGIWSCAN */
1185                r8180_wx_set_essid,                     /* SIOCSIWESSID */
1186                r8180_wx_get_essid,                     /* SIOCGIWESSID */
1187                dummy,                                  /* SIOCSIWNICKN */
1188                dummy,                                  /* SIOCGIWNICKN */
1189                NULL,                                   /* -- hole -- */
1190                NULL,                                   /* -- hole -- */
1191                r8180_wx_set_rate,                      /* SIOCSIWRATE */
1192                r8180_wx_get_rate,                      /* SIOCGIWRATE */
1193                r8180_wx_set_rts,                       /* SIOCSIWRTS */
1194                r8180_wx_get_rts,                       /* SIOCGIWRTS */
1195                r8180_wx_set_frag,                      /* SIOCSIWFRAG */
1196                r8180_wx_get_frag,                      /* SIOCGIWFRAG */
1197                dummy,                                  /* SIOCSIWTXPOW */
1198                dummy,                                  /* SIOCGIWTXPOW */
1199                r8180_wx_set_retry,                     /* SIOCSIWRETRY */
1200                r8180_wx_get_retry,                     /* SIOCGIWRETRY */
1201                r8180_wx_set_enc,                       /* SIOCSIWENCODE */
1202                r8180_wx_get_enc,                       /* SIOCGIWENCODE */
1203                r8180_wx_set_power,                     /* SIOCSIWPOWER */
1204                r8180_wx_get_power,                     /* SIOCGIWPOWER */
1205                NULL,                                   /*---hole---*/
1206                NULL,                                   /*---hole---*/
1207                r8180_wx_set_gen_ie,                    /* SIOCSIWGENIE */
1208                NULL,                                   /* SIOCSIWGENIE */
1209                r8180_wx_set_auth,                      /* SIOCSIWAUTH */
1210                NULL,                                   /* SIOCSIWAUTH */
1211                r8180_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
1212                NULL,                                   /* SIOCSIWENCODEEXT */
1213                NULL,                                   /* SIOCSIWPMKSA */
1214                NULL,                                   /*---hole---*/
1215};
1216
1217
1218static const struct iw_priv_args r8180_private_args[] = {
1219        {
1220                SIOCIWFIRSTPRIV + 0x0,
1221                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1222        },
1223        {       SIOCIWFIRSTPRIV + 0x1,
1224                0, 0, "dummy"
1225
1226        },
1227        {
1228                SIOCIWFIRSTPRIV + 0x2,
1229                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1230        },
1231        {       SIOCIWFIRSTPRIV + 0x3,
1232                0, 0, "dummy"
1233
1234        },
1235        {
1236                SIOCIWFIRSTPRIV + 0x4,
1237                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1238
1239        },
1240        {       SIOCIWFIRSTPRIV + 0x5,
1241                0, 0, "dummy"
1242
1243        },
1244        {
1245                SIOCIWFIRSTPRIV + 0x6,
1246                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1247
1248        },
1249        {       SIOCIWFIRSTPRIV + 0x7,
1250                0, 0, "dummy"
1251
1252        },
1253        {
1254                SIOCIWFIRSTPRIV + 0x8,
1255                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1256        },
1257        {
1258                SIOCIWFIRSTPRIV + 0x9,
1259                0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1260        },
1261        {
1262                SIOCIWFIRSTPRIV + 0xA,
1263                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1264        },
1265        {
1266                SIOCIWFIRSTPRIV + 0xB,
1267                0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1268        },
1269        {       SIOCIWFIRSTPRIV + 0xC,
1270                0, 0, "dummy"
1271        },
1272        {
1273                SIOCIWFIRSTPRIV + 0xD,
1274                0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1275        },
1276        {       SIOCIWFIRSTPRIV + 0xE,
1277                0, 0, "dummy"
1278        },
1279        {
1280                SIOCIWFIRSTPRIV + 0xF,
1281                0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1282        },
1283        {
1284                SIOCIWFIRSTPRIV + 0x10,
1285                0, 0, "resetstats"
1286        },
1287        {
1288                SIOCIWFIRSTPRIV + 0x11,
1289                0, 0, "dummy"
1290        },
1291        {
1292                SIOCIWFIRSTPRIV + 0x12,
1293                0, 0, "radioon"
1294        },
1295        {
1296                SIOCIWFIRSTPRIV + 0x13,
1297                0, 0, "radiooff"
1298        },
1299        {
1300                SIOCIWFIRSTPRIV + 0x14,
1301                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1302        },
1303        {
1304                SIOCIWFIRSTPRIV + 0x15,
1305                0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1306        },
1307        {
1308                SIOCIWFIRSTPRIV + 0x16,
1309                0, 0, "dummy"
1310        },
1311        {
1312                SIOCIWFIRSTPRIV + 0x17,
1313                0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1314        },
1315        {
1316                SIOCIWFIRSTPRIV + 0x18,
1317                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1318        },
1319};
1320
1321
1322static iw_handler r8180_private_handler[] = {
1323        r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1324        dummy,
1325        r8180_wx_set_beaconinterval,
1326        dummy,
1327        /* r8180_wx_set_monitor_type, */
1328        r8180_wx_set_scan_type,
1329        dummy,
1330        r8180_wx_set_rawtx,
1331        dummy,
1332        r8180_wx_set_iwmode,
1333        r8180_wx_get_iwmode,
1334        r8180_wx_set_preamble,
1335        r8180_wx_get_preamble,
1336        dummy,
1337        r8180_wx_get_siglevel,
1338        dummy,
1339        r8180_wx_get_sigqual,
1340        r8180_wx_reset_stats,
1341        dummy,/* r8180_wx_get_stats */
1342        r8180_wx_radio_on,
1343        r8180_wx_radio_off,
1344        r8180_wx_set_channelplan,
1345        r8180_wx_get_channelplan,
1346        dummy,
1347        r8180_wx_get_version,
1348        r8180_wx_set_forcerate,
1349};
1350
1351static inline int is_same_network(struct ieee80211_network *src,
1352                                                                        struct ieee80211_network *dst,
1353                                  struct ieee80211_device *ieee)
1354{
1355                /* A network is only a duplicate if the channel, BSSID, ESSID
1356                 * and the capability field (in particular IBSS and BSS) all match.
1357                 * We treat all <hidden> with the same BSSID and channel
1358                 * as one network
1359                 */
1360                return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1361                        (src->channel == dst->channel) &&
1362                        !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1363                        (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&  /* YJ,mod, 080819,for hidden ap */
1364                        ((src->capability & WLAN_CAPABILITY_IBSS) ==
1365                        (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1366                        ((src->capability & WLAN_CAPABILITY_BSS) ==
1367                        (dst->capability & WLAN_CAPABILITY_BSS)));
1368}
1369
1370/* WB modified to show signal to GUI on 18-01-2008 */
1371static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1372{
1373        struct r8180_priv *priv = ieee80211_priv(dev);
1374        struct ieee80211_device* ieee = priv->ieee80211;
1375        struct iw_statistics* wstats = &priv->wstats;
1376        int tmp_level = 0;
1377        int tmp_qual = 0;
1378        int tmp_noise = 0;
1379
1380        if (ieee->state < IEEE80211_LINKED)     {
1381                wstats->qual.qual = 0;
1382                wstats->qual.level = 0;
1383                wstats->qual.noise = 0;
1384                wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1385                return wstats;
1386        }
1387
1388        tmp_level = (&ieee->current_network)->stats.signal;
1389        tmp_qual = (&ieee->current_network)->stats.signalstrength;
1390        tmp_noise = (&ieee->current_network)->stats.noise;
1391
1392        wstats->qual.level = tmp_level;
1393        wstats->qual.qual = tmp_qual;
1394        wstats->qual.noise = tmp_noise;
1395        wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1396        return wstats;
1397}
1398
1399struct iw_handler_def  r8180_wx_handlers_def = {
1400        .standard = r8180_wx_handlers,
1401        .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1402        .private = r8180_private_handler,
1403        .num_private = ARRAY_SIZE(r8180_private_handler),
1404        .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1405        .get_wireless_stats = r8180_get_wireless_stats,
1406        .private_args = (struct iw_priv_args *)r8180_private_args,
1407};
1408
1409
1410