Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[cascardo/linux.git] / 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 #include "r8180_sa2400.h"
24
25 #ifdef ENABLE_DOT11D
26 #include "dot11d.h"
27 #endif
28
29 //#define RATE_COUNT 4
30 u32 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
35 static 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 };
48 static 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
58 int 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
92 static 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
115 static 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
124 static 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
134 static 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
155 static 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
189 static 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
216 struct  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
241 static 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
344 static 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
419 static 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
437 static 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
463 static 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
480 static 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
499 static 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
507 static 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
530 static 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
544 static 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
565 static 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
575 static 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
599 static 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
609 static 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 /*
627 static 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
646 static 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         */
696 exit:
697         up(&priv->wx_sem);
698
699         return err;
700 }
701
702 static 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
728 static 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
740 static 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
763 exit:
764         up(&priv->wx_sem);
765
766         return err;
767 }
768
769
770 static 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
790 static 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
806 static 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
832 static 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 }
854 static 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 }
868 static 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 /*
875 static 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;
900 exit:
901         up(&priv->wx_sem);
902
903         return ret;
904 }
905 static 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
926 static 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 }
952 static 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 }
998 static 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 }
1015 static 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 }
1038 static 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 }
1058 static 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 }
1078 static 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 }
1118 static 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
1137 static 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 }
1155 static 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 }
1172 static 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", __FUNCTION__);
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
1213 static 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.
1229 static 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",__FUNCTION__,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
1257 static 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", __FUNCTION__);
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 }
1276 static int r8180_wx_set_auth(struct net_device *dev,
1277                                         struct iw_request_info *info,
1278                                         struct iw_param *data, char *extra)
1279 {
1280         //printk("====>%s()\n", __FUNCTION__);
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, data, extra);
1289         up(&priv->wx_sem);
1290         return ret;
1291 }
1292
1293 static 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", __FUNCTION__);
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 }
1314 static int r8180_wx_set_gen_ie(struct net_device *dev,
1315                                         struct iw_request_info *info,
1316                                         struct iw_point *data, char *extra)
1317 {
1318 //      printk("====>%s(), len:%d\n", __FUNCTION__, 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, data->length);
1329 #endif
1330         up(&priv->wx_sem);
1331         //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1332         return ret;
1333
1334
1335 }
1336 static 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
1397 static 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
1517 static 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
1547 static 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
1568 static 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
1632 struct 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