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