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