766892e31f52196ed2c914c47932c392c34f1d9e
[safe/jmp/linux-2.6] / drivers / staging / rtl8187se / r8180_wx.c
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
27 u32 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
32 static 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 };
45 static 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
55 int 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
89 static 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
112 static 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
121 static 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
131 static 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
152 static 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
186 static 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
211 struct  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
236 static 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
335 static 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
408 static 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
426 static 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
450 static 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
467 static 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
486 static 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
494 static 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
517 static 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
531 static 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
552 static 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
562 static 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
586 static 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
596 static 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 /*
614 static 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
633 static 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         */
683 exit:
684         up(&priv->wx_sem);
685
686         return err;
687 }
688
689 static 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
715 static 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
727 static 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
750 exit:
751         up(&priv->wx_sem);
752
753         return err;
754 }
755
756
757 static 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
777 static 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
793 static 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
819 static 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 }
841 static 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 }
855 static 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 /*
862 static 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;
887 exit:
888         up(&priv->wx_sem);
889
890         return ret;
891 }
892 static 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
913 static 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 }
939 static 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 }
985 static 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 }
1002 static 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 }
1025 static 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 }
1045 static 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 }
1065 static 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 }
1105 static 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
1124 static 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 }
1142 static 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 }
1159 static 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
1192 static 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.
1208 static 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
1236 static 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 }
1255 static 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
1272 static 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 }
1293 static 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 }
1315 static 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
1376 static 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
1496 static 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
1525 static 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
1546 static 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
1579 struct 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