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