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