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