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