e9e799c228632d6f292b99322c3988075567fedc
[safe/jmp/linux-2.6] / drivers / staging / rtl8192e / r8192E_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 #include <linux/string.h>
21 #include "r8192E.h"
22 #include "r8192E_hw.h"
23 #include "r8192E_wx.h"
24 #ifdef ENABLE_DOT11D
25 #include "dot11d.h"
26 #endif
27
28 #define RATE_COUNT 12
29 static u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
30         6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31
32
33 #ifndef ENETDOWN
34 #define ENETDOWN 1
35 #endif
36 static int r8192_wx_get_freq(struct net_device *dev,
37                              struct iw_request_info *a,
38                              union iwreq_data *wrqu, char *b)
39 {
40         struct r8192_priv *priv = ieee80211_priv(dev);
41
42         return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
43 }
44
45
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47                              union iwreq_data *wrqu, char *b)
48 {
49         struct r8192_priv *priv=ieee80211_priv(dev);
50
51         return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
52 }
53
54
55
56 static int r8192_wx_get_rate(struct net_device *dev,
57                              struct iw_request_info *info,
58                              union iwreq_data *wrqu, char *extra)
59 {
60         struct r8192_priv *priv = ieee80211_priv(dev);
61         return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
62 }
63
64
65
66 static int r8192_wx_set_rate(struct net_device *dev,
67                              struct iw_request_info *info,
68                              union iwreq_data *wrqu, char *extra)
69 {
70         int ret;
71         struct r8192_priv *priv = ieee80211_priv(dev);
72
73         down(&priv->wx_sem);
74
75         ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
76
77         up(&priv->wx_sem);
78
79         return ret;
80 }
81
82
83 static int r8192_wx_set_rts(struct net_device *dev,
84                              struct iw_request_info *info,
85                              union iwreq_data *wrqu, char *extra)
86 {
87         int ret;
88         struct r8192_priv *priv = ieee80211_priv(dev);
89
90         down(&priv->wx_sem);
91
92         ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
93
94         up(&priv->wx_sem);
95
96         return ret;
97 }
98
99 static int r8192_wx_get_rts(struct net_device *dev,
100                              struct iw_request_info *info,
101                              union iwreq_data *wrqu, char *extra)
102 {
103         struct r8192_priv *priv = ieee80211_priv(dev);
104         return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
105 }
106
107 static int r8192_wx_set_power(struct net_device *dev,
108                              struct iw_request_info *info,
109                              union iwreq_data *wrqu, char *extra)
110 {
111         int ret;
112         struct r8192_priv *priv = ieee80211_priv(dev);
113
114         down(&priv->wx_sem);
115
116         ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
117
118         up(&priv->wx_sem);
119
120         return ret;
121 }
122
123 static int r8192_wx_get_power(struct net_device *dev,
124                              struct iw_request_info *info,
125                              union iwreq_data *wrqu, char *extra)
126 {
127         struct r8192_priv *priv = ieee80211_priv(dev);
128         return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
129 }
130
131 #ifdef JOHN_IOCTL
132 u16 read_rtl8225(struct net_device *dev, u8 addr);
133 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
134 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
135 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
136
137 static int r8192_wx_read_regs(struct net_device *dev,
138                                struct iw_request_info *info,
139                                union iwreq_data *wrqu, char *extra)
140 {
141         struct r8192_priv *priv = ieee80211_priv(dev);
142         u8 addr;
143         u16 data1;
144
145         down(&priv->wx_sem);
146
147
148         get_user(addr,(u8*)wrqu->data.pointer);
149         data1 = read_rtl8225(dev, addr);
150         wrqu->data.length = data1;
151
152         up(&priv->wx_sem);
153         return 0;
154
155 }
156
157 static int r8192_wx_write_regs(struct net_device *dev,
158                                struct iw_request_info *info,
159                                union iwreq_data *wrqu, char *extra)
160 {
161         struct r8192_priv *priv = ieee80211_priv(dev);
162         u8 addr;
163
164         down(&priv->wx_sem);
165
166         get_user(addr, (u8*)wrqu->data.pointer);
167         write_rtl8225(dev, addr, wrqu->data.length);
168
169         up(&priv->wx_sem);
170         return 0;
171
172 }
173
174 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
175 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
176
177 static int r8192_wx_read_bb(struct net_device *dev,
178                                struct iw_request_info *info,
179                                union iwreq_data *wrqu, char *extra)
180 {
181         struct r8192_priv *priv = ieee80211_priv(dev);
182         u8 databb;
183 #if 0
184         int i;
185         for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
186 #endif
187
188         down(&priv->wx_sem);
189
190         databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
191         wrqu->data.length = databb;
192
193         up(&priv->wx_sem);
194         return 0;
195 }
196
197 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
198 static int r8192_wx_write_bb(struct net_device *dev,
199                                struct iw_request_info *info,
200                                union iwreq_data *wrqu, char *extra)
201 {
202         struct r8192_priv *priv = ieee80211_priv(dev);
203         u8 databb;
204
205         down(&priv->wx_sem);
206
207         get_user(databb, (u8*)wrqu->data.pointer);
208         rtl8187_write_phy(dev, wrqu->data.length, databb);
209
210         up(&priv->wx_sem);
211         return 0;
212
213 }
214
215
216 static int r8192_wx_write_nicb(struct net_device *dev,
217                                struct iw_request_info *info,
218                                union iwreq_data *wrqu, char *extra)
219 {
220         struct r8192_priv *priv = ieee80211_priv(dev);
221         u32 addr;
222
223         down(&priv->wx_sem);
224
225         get_user(addr, (u32*)wrqu->data.pointer);
226         write_nic_byte(dev, addr, wrqu->data.length);
227
228         up(&priv->wx_sem);
229         return 0;
230
231 }
232 static int r8192_wx_read_nicb(struct net_device *dev,
233                                struct iw_request_info *info,
234                                union iwreq_data *wrqu, char *extra)
235 {
236         struct r8192_priv *priv = ieee80211_priv(dev);
237         u32 addr;
238         u16 data1;
239
240         down(&priv->wx_sem);
241
242         get_user(addr,(u32*)wrqu->data.pointer);
243         data1 = read_nic_byte(dev, addr);
244         wrqu->data.length = data1;
245
246         up(&priv->wx_sem);
247         return 0;
248 }
249
250 static int r8192_wx_get_ap_status(struct net_device *dev,
251                                struct iw_request_info *info,
252                                union iwreq_data *wrqu, char *extra)
253 {
254         struct r8192_priv *priv = ieee80211_priv(dev);
255         struct ieee80211_device *ieee = priv->ieee80211;
256         struct ieee80211_network *target;
257         int name_len;
258
259         down(&priv->wx_sem);
260
261         //count the length of input ssid
262         for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
263
264         //search for the correspoding info which is received
265         list_for_each_entry(target, &ieee->network_list, list) {
266                 if ( (target->ssid_len == name_len) &&
267                      (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
268                         if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
269                                 //set flags=1 to indicate this ap is WPA
270                                 wrqu->data.flags = 1;
271                         else wrqu->data.flags = 0;
272
273
274                 break;
275                 }
276         }
277
278         up(&priv->wx_sem);
279         return 0;
280 }
281
282
283
284 #endif
285
286 static int r8192_wx_set_rawtx(struct net_device *dev,
287                                struct iw_request_info *info,
288                                union iwreq_data *wrqu, char *extra)
289 {
290         struct r8192_priv *priv = ieee80211_priv(dev);
291         int ret;
292
293         down(&priv->wx_sem);
294
295         ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
296
297         up(&priv->wx_sem);
298
299         return ret;
300
301 }
302
303 static int r8192_wx_force_reset(struct net_device *dev,
304                 struct iw_request_info *info,
305                 union iwreq_data *wrqu, char *extra)
306 {
307         struct r8192_priv *priv = ieee80211_priv(dev);
308
309         down(&priv->wx_sem);
310
311         printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
312         priv->force_reset = *extra;
313         up(&priv->wx_sem);
314         return 0;
315
316 }
317
318
319 static int r8192_wx_set_crcmon(struct net_device *dev,
320                                struct iw_request_info *info,
321                                union iwreq_data *wrqu, char *extra)
322 {
323         struct r8192_priv *priv = ieee80211_priv(dev);
324         int *parms = (int *)extra;
325         int enable = (parms[0] > 0);
326         short prev = priv->crcmon;
327
328         down(&priv->wx_sem);
329
330         if(enable)
331                 priv->crcmon=1;
332         else
333                 priv->crcmon=0;
334
335         DMESG("bad CRC in monitor mode are %s",
336               priv->crcmon ? "accepted" : "rejected");
337
338         if(prev != priv->crcmon && priv->up){
339                 //rtl8180_down(dev);
340                 //rtl8180_up(dev);
341         }
342
343         up(&priv->wx_sem);
344
345         return 0;
346 }
347
348 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
349                              union iwreq_data *wrqu, char *b)
350 {
351         struct r8192_priv *priv = ieee80211_priv(dev);
352         RT_RF_POWER_STATE       rtState;
353         int ret;
354
355         rtState = priv->ieee80211->eRFPowerState;
356         down(&priv->wx_sem);
357 #ifdef ENABLE_IPS
358         if(wrqu->mode == IW_MODE_ADHOC){
359
360                 if(priv->ieee80211->PowerSaveControl.bInactivePs){
361                         if(rtState == eRfOff){
362                                 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
363                                 {
364                                         RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
365                                         up(&priv->wx_sem);
366                                         return -1;
367                                 }
368                                 else{
369                                 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
370                                         IPSLeave(dev);
371                                 }
372                         }
373                 }
374         }
375 #endif
376         ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
377
378         //rtl8187_set_rxconf(dev);
379
380         up(&priv->wx_sem);
381         return ret;
382 }
383
384 struct  iw_range_with_scan_capa
385 {
386         /* Informative stuff (to choose between different interface) */
387         __u32           throughput;     /* To give an idea... */
388         /* In theory this value should be the maximum benchmarked
389          * TCP/IP throughput, because with most of these devices the
390          * bit rate is meaningless (overhead an co) to estimate how
391          * fast the connection will go and pick the fastest one.
392          * I suggest people to play with Netperf or any benchmark...
393          */
394
395         /* NWID (or domain id) */
396         __u32           min_nwid;       /* Minimal NWID we are able to set */
397         __u32           max_nwid;       /* Maximal NWID we are able to set */
398
399         /* Old Frequency (backward compat - moved lower ) */
400         __u16           old_num_channels;
401         __u8            old_num_frequency;
402
403         /* Scan capabilities */
404         __u8            scan_capa;
405 };
406 static int rtl8180_wx_get_range(struct net_device *dev,
407                                 struct iw_request_info *info,
408                                 union iwreq_data *wrqu, char *extra)
409 {
410         struct iw_range *range = (struct iw_range *)extra;
411         struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
412         struct r8192_priv *priv = ieee80211_priv(dev);
413         u16 val;
414         int i;
415
416         wrqu->data.length = sizeof(*range);
417         memset(range, 0, sizeof(*range));
418
419         /* Let's try to keep this struct in the same order as in
420          * linux/include/wireless.h
421          */
422
423         /* TODO: See what values we can set, and remove the ones we can't
424          * set, or fill them with some default data.
425          */
426
427         /* ~5 Mb/s real (802.11b) */
428         range->throughput = 5 * 1000 * 1000;
429
430         // TODO: Not used in 802.11b?
431 //      range->min_nwid;        /* Minimal NWID we are able to set */
432         // TODO: Not used in 802.11b?
433 //      range->max_nwid;        /* Maximal NWID we are able to set */
434
435         /* Old Frequency (backward compat - moved lower ) */
436 //      range->old_num_channels;
437 //      range->old_num_frequency;
438 //      range->old_freq[6]; /* Filler to keep "version" at the same offset */
439         if(priv->rf_set_sens != NULL)
440                 range->sensitivity = priv->max_sens;    /* signal level threshold range */
441
442         range->max_qual.qual = 100;
443         /* TODO: Find real max RSSI and stick here */
444         range->max_qual.level = 0;
445         range->max_qual.noise = -98;
446         range->max_qual.updated = 7; /* Updated all three */
447
448         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
449         /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
450         range->avg_qual.level = 20 + -98;
451         range->avg_qual.noise = 0;
452         range->avg_qual.updated = 7; /* Updated all three */
453
454         range->num_bitrates = RATE_COUNT;
455
456         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
457                 range->bitrate[i] = rtl8180_rates[i];
458         }
459
460         range->min_frag = MIN_FRAG_THRESHOLD;
461         range->max_frag = MAX_FRAG_THRESHOLD;
462
463         range->min_pmp=0;
464         range->max_pmp = 5000000;
465         range->min_pmt = 0;
466         range->max_pmt = 65535*1000;
467         range->pmp_flags = IW_POWER_PERIOD;
468         range->pmt_flags = IW_POWER_TIMEOUT;
469         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
470         range->we_version_compiled = WIRELESS_EXT;
471         range->we_version_source = 16;
472
473 //      range->retry_capa;      /* What retry options are supported */
474 //      range->retry_flags;     /* How to decode max/min retry limit */
475 //      range->r_time_flags;    /* How to decode max/min retry life */
476 //      range->min_retry;       /* Minimal number of retries */
477 //      range->max_retry;       /* Maximal number of retries */
478 //      range->min_r_time;      /* Minimal retry lifetime */
479 //      range->max_r_time;      /* Maximal retry lifetime */
480
481
482         for (i = 0, val = 0; i < 14; i++) {
483
484                 // Include only legal frequencies for some countries
485 #ifdef ENABLE_DOT11D
486                 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
487 #else
488                 if ((priv->ieee80211->channel_map)[i+1]) {
489 #endif
490                         range->freq[val].i = i + 1;
491                         range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
492                         range->freq[val].e = 1;
493                         val++;
494                 } else {
495                         // FIXME: do we need to set anything for channels
496                         // we don't use ?
497                 }
498
499                 if (val == IW_MAX_FREQUENCIES)
500                 break;
501         }
502         range->num_frequency = val;
503         range->num_channels = val;
504 #if WIRELESS_EXT > 17
505         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
506                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
507 #endif
508         tmp->scan_capa = 0x01;
509         return 0;
510 }
511
512
513 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
514                              union iwreq_data *wrqu, char *b)
515 {
516         struct r8192_priv *priv = ieee80211_priv(dev);
517         struct ieee80211_device* ieee = priv->ieee80211;
518         RT_RF_POWER_STATE       rtState;
519         int ret;
520         rtState = priv->ieee80211->eRFPowerState;
521         if(!priv->up) return -ENETDOWN;
522         if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
523                 return -EAGAIN;
524
525         if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
526         {
527                 struct iw_scan_req* req = (struct iw_scan_req*)b;
528                 if (req->essid_len)
529                 {
530                         //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
531                         ieee->current_network.ssid_len = req->essid_len;
532                         memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
533                         //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
534                 }
535         }
536
537         down(&priv->wx_sem);
538 #ifdef ENABLE_IPS
539         priv->ieee80211->actscanning = true;
540         if(priv->ieee80211->state != IEEE80211_LINKED){
541                 if(priv->ieee80211->PowerSaveControl.bInactivePs){
542                         if(rtState == eRfOff){
543                                 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
544                                 {
545                                         RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
546                                         up(&priv->wx_sem);
547                                         return -1;
548                                 }
549                                 else{
550                                         printk("=========>%s(): IPSLeave\n",__FUNCTION__);
551                                         IPSLeave(dev);
552                                 }
553                         }
554                 }
555                 priv->ieee80211->scanning = 0;
556                 ieee80211_softmac_scan_syncro(priv->ieee80211);
557                 ret = 0;
558         }
559         else
560 #else
561
562         if(priv->ieee80211->state != IEEE80211_LINKED){
563                 priv->ieee80211->scanning = 0;
564                 ieee80211_softmac_scan_syncro(priv->ieee80211);
565                 ret = 0;
566         }
567         else
568 #endif
569         ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
570
571         up(&priv->wx_sem);
572         return ret;
573 }
574
575
576 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
577                              union iwreq_data *wrqu, char *b)
578 {
579
580         int ret;
581         struct r8192_priv *priv = ieee80211_priv(dev);
582
583         if(!priv->up) return -ENETDOWN;
584
585         down(&priv->wx_sem);
586
587         ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
588
589         up(&priv->wx_sem);
590
591         return ret;
592 }
593
594 static int r8192_wx_set_essid(struct net_device *dev,
595                               struct iw_request_info *a,
596                               union iwreq_data *wrqu, char *b)
597 {
598         struct r8192_priv *priv = ieee80211_priv(dev);
599         RT_RF_POWER_STATE       rtState;
600         int ret;
601
602         rtState = priv->ieee80211->eRFPowerState;
603         down(&priv->wx_sem);
604 #ifdef ENABLE_IPS
605         if(priv->ieee80211->PowerSaveControl.bInactivePs){
606                 if(rtState == eRfOff){
607                         if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
608                         {
609                                 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
610                                 up(&priv->wx_sem);
611                                 return -1;
612                         }
613                         else{
614                                 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
615                                 IPSLeave(dev);
616                         }
617                 }
618         }
619 #endif
620         ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
621
622         up(&priv->wx_sem);
623
624         return ret;
625 }
626
627
628
629
630 static int r8192_wx_get_essid(struct net_device *dev,
631                               struct iw_request_info *a,
632                               union iwreq_data *wrqu, char *b)
633 {
634         int ret;
635         struct r8192_priv *priv = ieee80211_priv(dev);
636
637         down(&priv->wx_sem);
638
639         ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
640
641         up(&priv->wx_sem);
642
643         return ret;
644 }
645
646
647 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
648                              union iwreq_data *wrqu, char *b)
649 {
650         int ret;
651         struct r8192_priv *priv = ieee80211_priv(dev);
652
653         down(&priv->wx_sem);
654
655         ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
656
657         up(&priv->wx_sem);
658         return ret;
659 }
660
661 static int r8192_wx_get_name(struct net_device *dev,
662                              struct iw_request_info *info,
663                              union iwreq_data *wrqu, char *extra)
664 {
665         struct r8192_priv *priv = ieee80211_priv(dev);
666         return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
667 }
668
669
670 static int r8192_wx_set_frag(struct net_device *dev,
671                              struct iw_request_info *info,
672                              union iwreq_data *wrqu, char *extra)
673 {
674         struct r8192_priv *priv = ieee80211_priv(dev);
675
676         if (wrqu->frag.disabled)
677                 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
678         else {
679                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
680                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
681                         return -EINVAL;
682
683                 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
684         }
685
686         return 0;
687 }
688
689
690 static int r8192_wx_get_frag(struct net_device *dev,
691                              struct iw_request_info *info,
692                              union iwreq_data *wrqu, char *extra)
693 {
694         struct r8192_priv *priv = ieee80211_priv(dev);
695
696         wrqu->frag.value = priv->ieee80211->fts;
697         wrqu->frag.fixed = 0;   /* no auto select */
698         wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
699
700         return 0;
701 }
702
703
704 static int r8192_wx_set_wap(struct net_device *dev,
705                          struct iw_request_info *info,
706                          union iwreq_data *awrq,
707                          char *extra)
708 {
709
710         int ret;
711         struct r8192_priv *priv = ieee80211_priv(dev);
712 //        struct sockaddr *temp = (struct sockaddr *)awrq;
713
714         down(&priv->wx_sem);
715
716         ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
717
718         up(&priv->wx_sem);
719
720         return ret;
721
722 }
723
724
725 static int r8192_wx_get_wap(struct net_device *dev,
726                             struct iw_request_info *info,
727                             union iwreq_data *wrqu, char *extra)
728 {
729         struct r8192_priv *priv = ieee80211_priv(dev);
730
731         return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
732 }
733
734
735 static int r8192_wx_get_enc(struct net_device *dev,
736                             struct iw_request_info *info,
737                             union iwreq_data *wrqu, char *key)
738 {
739         struct r8192_priv *priv = ieee80211_priv(dev);
740
741         return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
742 }
743
744 static int r8192_wx_set_enc(struct net_device *dev,
745                             struct iw_request_info *info,
746                             union iwreq_data *wrqu, char *key)
747 {
748         struct r8192_priv *priv = ieee80211_priv(dev);
749         int ret;
750
751         struct ieee80211_device *ieee = priv->ieee80211;
752         //u32 TargetContent;
753         u32 hwkey[4]={0,0,0,0};
754         u8 mask=0xff;
755         u32 key_idx=0;
756         u8 zero_addr[4][6] ={   {0x00,0x00,0x00,0x00,0x00,0x00},
757                                 {0x00,0x00,0x00,0x00,0x00,0x01},
758                                 {0x00,0x00,0x00,0x00,0x00,0x02},
759                                 {0x00,0x00,0x00,0x00,0x00,0x03} };
760         int i;
761
762        if(!priv->up) return -ENETDOWN;
763
764         down(&priv->wx_sem);
765
766         RT_TRACE(COMP_SEC, "Setting SW wep key");
767         ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
768
769         up(&priv->wx_sem);
770
771
772         //sometimes, the length is zero while we do not type key value
773         if(wrqu->encoding.length!=0){
774
775                 for(i=0 ; i<4 ; i++){
776                         hwkey[i] |=  key[4*i+0]&mask;
777                         if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
778                         if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
779                         hwkey[i] |= (key[4*i+1]&mask)<<8;
780                         hwkey[i] |= (key[4*i+2]&mask)<<16;
781                         hwkey[i] |= (key[4*i+3]&mask)<<24;
782                 }
783
784                 #define CONF_WEP40  0x4
785                 #define CONF_WEP104 0x14
786
787                 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
788                         case 0: key_idx = ieee->tx_keyidx; break;
789                         case 1: key_idx = 0; break;
790                         case 2: key_idx = 1; break;
791                         case 3: key_idx = 2; break;
792                         case 4: key_idx = 3; break;
793                         default: break;
794                 }
795
796                 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
797                 if(wrqu->encoding.length==0x5){
798                 ieee->pairwise_key_type = KEY_TYPE_WEP40;
799                         EnableHWSecurityConfig8192(dev);
800                         setKey( dev,
801                                 key_idx,                //EntryNo
802                                 key_idx,                //KeyIndex
803                                 KEY_TYPE_WEP40,         //KeyType
804                                 zero_addr[key_idx],
805                                 0,                      //DefaultKey
806                                 hwkey);                 //KeyContent
807
808 #if 0
809                         if(key_idx == 0){
810
811                                 //write_nic_byte(dev, SECR, 7);
812                                 setKey( dev,
813                                         4,                      //EntryNo
814                                         key_idx,                      //KeyIndex
815                                         KEY_TYPE_WEP40,        //KeyType
816                                         broadcast_addr,         //addr
817                                         0,                      //DefaultKey
818                                         hwkey);                 //KeyContent
819                         }
820 #endif
821                 }
822
823                 else if(wrqu->encoding.length==0xd){
824                         ieee->pairwise_key_type = KEY_TYPE_WEP104;
825                                 EnableHWSecurityConfig8192(dev);
826                         setKey( dev,
827                                 key_idx,                //EntryNo
828                                 key_idx,                //KeyIndex
829                                 KEY_TYPE_WEP104,        //KeyType
830                                 zero_addr[key_idx],
831                                 0,                      //DefaultKey
832                                 hwkey);                 //KeyContent
833 #if 0
834                         if(key_idx == 0){
835
836                                 //write_nic_byte(dev, SECR, 7);
837                                 setKey( dev,
838                                         4,                      //EntryNo
839                                         key_idx,                      //KeyIndex
840                                         KEY_TYPE_WEP104,        //KeyType
841                                         broadcast_addr,         //addr
842                                         0,                      //DefaultKey
843                                         hwkey);                 //KeyContent
844                         }
845 #endif
846                 }
847                 else printk("wrong type in WEP, not WEP40 and WEP104\n");
848
849
850         }
851
852 #if 0
853         //consider the setting different key index situation
854         //wrqu->encoding.flags = 801 means that we set key with index "1"
855         if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
856                 printk("===>1\n");
857                 //write_nic_byte(dev, SECR, 7);
858                 EnableHWSecurityConfig8192(dev);
859                 //copy wpa config from default key(key0~key3) to broadcast key(key5)
860                 //
861                 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
862                 write_cam(dev, (4*6),   0xffff0000|read_cam(dev, key_idx*6) );
863                 write_cam(dev, (4*6)+1, 0xffffffff);
864                 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
865                 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
866                 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
867                 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
868         }
869 #endif
870
871         return ret;
872 }
873
874
875 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
876  iwreq_data *wrqu, char *p){
877
878         struct r8192_priv *priv = ieee80211_priv(dev);
879         int *parms=(int*)p;
880         int mode=parms[0];
881
882         priv->ieee80211->active_scan = mode;
883
884         return 1;
885 }
886
887
888
889 static int r8192_wx_set_retry(struct net_device *dev,
890                                 struct iw_request_info *info,
891                                 union iwreq_data *wrqu, char *extra)
892 {
893         struct r8192_priv *priv = ieee80211_priv(dev);
894         int err = 0;
895
896         down(&priv->wx_sem);
897
898         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
899             wrqu->retry.disabled){
900                 err = -EINVAL;
901                 goto exit;
902         }
903         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
904                 err = -EINVAL;
905                 goto exit;
906         }
907
908         if(wrqu->retry.value > R8180_MAX_RETRY){
909                 err= -EINVAL;
910                 goto exit;
911         }
912         if (wrqu->retry.flags & IW_RETRY_MAX) {
913                 priv->retry_rts = wrqu->retry.value;
914                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
915
916         }else {
917                 priv->retry_data = wrqu->retry.value;
918                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
919         }
920
921         /* FIXME !
922          * We might try to write directly the TX config register
923          * or to restart just the (R)TX process.
924          * I'm unsure if whole reset is really needed
925          */
926
927         rtl8192_commit(dev);
928         /*
929         if(priv->up){
930                 rtl8180_rtx_disable(dev);
931                 rtl8180_rx_enable(dev);
932                 rtl8180_tx_enable(dev);
933
934         }
935         */
936 exit:
937         up(&priv->wx_sem);
938
939         return err;
940 }
941
942 static int r8192_wx_get_retry(struct net_device *dev,
943                                 struct iw_request_info *info,
944                                 union iwreq_data *wrqu, char *extra)
945 {
946         struct r8192_priv *priv = ieee80211_priv(dev);
947
948
949         wrqu->retry.disabled = 0; /* can't be disabled */
950
951         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
952             IW_RETRY_LIFETIME)
953                 return -EINVAL;
954
955         if (wrqu->retry.flags & IW_RETRY_MAX) {
956                 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
957                 wrqu->retry.value = priv->retry_rts;
958         } else {
959                 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
960                 wrqu->retry.value = priv->retry_data;
961         }
962         //DMESG("returning %d",wrqu->retry.value);
963
964
965         return 0;
966 }
967
968 static int r8192_wx_get_sens(struct net_device *dev,
969                                 struct iw_request_info *info,
970                                 union iwreq_data *wrqu, char *extra)
971 {
972         struct r8192_priv *priv = ieee80211_priv(dev);
973         if(priv->rf_set_sens == NULL)
974                 return -1; /* we have not this support for this radio */
975         wrqu->sens.value = priv->sens;
976         return 0;
977 }
978
979
980 static int r8192_wx_set_sens(struct net_device *dev,
981                                 struct iw_request_info *info,
982                                 union iwreq_data *wrqu, char *extra)
983 {
984
985         struct r8192_priv *priv = ieee80211_priv(dev);
986
987         short err = 0;
988         down(&priv->wx_sem);
989         //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
990         if(priv->rf_set_sens == NULL) {
991                 err= -1; /* we have not this support for this radio */
992                 goto exit;
993         }
994         if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
995                 priv->sens = wrqu->sens.value;
996         else
997                 err= -EINVAL;
998
999 exit:
1000         up(&priv->wx_sem);
1001
1002         return err;
1003 }
1004
1005 #if (WIRELESS_EXT >= 18)
1006 static int r8192_wx_set_enc_ext(struct net_device *dev,
1007                                         struct iw_request_info *info,
1008                                         union iwreq_data *wrqu, char *extra)
1009 {
1010         int ret=0;
1011         struct r8192_priv *priv = ieee80211_priv(dev);
1012         struct ieee80211_device* ieee = priv->ieee80211;
1013
1014         down(&priv->wx_sem);
1015         ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1016
1017         {
1018                 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1019                 u8 zero[6] = {0};
1020                 u32 key[4] = {0};
1021                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1022                 struct iw_point *encoding = &wrqu->encoding;
1023 #if 0
1024                 static u8 CAM_CONST_ADDR[4][6] = {
1025                         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1026                         {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1027                         {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1028                         {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1029 #endif
1030                 u8 idx = 0, alg = 0, group = 0;
1031                 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1032                 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1033                 {
1034                         ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1035                         CamResetAllEntry(dev);
1036                         goto end_hw_sec;
1037                 }
1038                 alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
1039                 idx = encoding->flags & IW_ENCODE_INDEX;
1040                 if (idx)
1041                         idx --;
1042                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1043
1044                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40))
1045                 {
1046                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1047                                 alg = KEY_TYPE_WEP104;
1048                         ieee->pairwise_key_type = alg;
1049                         EnableHWSecurityConfig8192(dev);
1050                 }
1051                 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1052
1053                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1054                 {
1055                         if (ext->key_len == 13)
1056                                 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1057                         setKey( dev,
1058                                         idx,//EntryNo
1059                                         idx, //KeyIndex
1060                                         alg,  //KeyType
1061                                         zero, //MacAddr
1062                                         0,              //DefaultKey
1063                                         key);           //KeyContent
1064                 }
1065                 else if (group)
1066                 {
1067                         ieee->group_key_type = alg;
1068                         setKey( dev,
1069                                         idx,//EntryNo
1070                                         idx, //KeyIndex
1071                                         alg,  //KeyType
1072                                         broadcast_addr, //MacAddr
1073                                         0,              //DefaultKey
1074                                         key);           //KeyContent
1075                 }
1076                 else //pairwise key
1077                 {
1078                         if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
1079                                                         write_nic_byte(dev, 0x173, 1); //fix aes bug
1080                         }
1081                         setKey( dev,
1082                                         4,//EntryNo
1083                                         idx, //KeyIndex
1084                                         alg,  //KeyType
1085                                         (u8*)ieee->ap_mac_addr, //MacAddr
1086                                         0,              //DefaultKey
1087                                         key);           //KeyContent
1088                 }
1089
1090
1091         }
1092
1093 end_hw_sec:
1094         up(&priv->wx_sem);
1095         return ret;
1096
1097 }
1098 static int r8192_wx_set_auth(struct net_device *dev,
1099                                         struct iw_request_info *info,
1100                                         union iwreq_data *data, char *extra)
1101 {
1102         int ret=0;
1103         //printk("====>%s()\n", __FUNCTION__);
1104         struct r8192_priv *priv = ieee80211_priv(dev);
1105         down(&priv->wx_sem);
1106         ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1107         up(&priv->wx_sem);
1108         return ret;
1109 }
1110
1111 static int r8192_wx_set_mlme(struct net_device *dev,
1112                                         struct iw_request_info *info,
1113                                         union iwreq_data *wrqu, char *extra)
1114 {
1115         //printk("====>%s()\n", __FUNCTION__);
1116
1117         int ret=0;
1118         struct r8192_priv *priv = ieee80211_priv(dev);
1119         down(&priv->wx_sem);
1120         ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1121         up(&priv->wx_sem);
1122         return ret;
1123 }
1124 #endif
1125 static int r8192_wx_set_gen_ie(struct net_device *dev,
1126                                         struct iw_request_info *info,
1127                                         union iwreq_data *data, char *extra)
1128 {
1129            //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1130         int ret=0;
1131         struct r8192_priv *priv = ieee80211_priv(dev);
1132         down(&priv->wx_sem);
1133         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1134         up(&priv->wx_sem);
1135         //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1136         return ret;
1137 }
1138
1139 static int dummy(struct net_device *dev, struct iw_request_info *a,
1140                  union iwreq_data *wrqu,char *b)
1141 {
1142         return -1;
1143 }
1144
1145
1146 static iw_handler r8192_wx_handlers[] =
1147 {
1148         NULL,                     /* SIOCSIWCOMMIT */
1149         r8192_wx_get_name,        /* SIOCGIWNAME */
1150         dummy,                    /* SIOCSIWNWID */
1151         dummy,                    /* SIOCGIWNWID */
1152         r8192_wx_set_freq,        /* SIOCSIWFREQ */
1153         r8192_wx_get_freq,        /* SIOCGIWFREQ */
1154         r8192_wx_set_mode,        /* SIOCSIWMODE */
1155         r8192_wx_get_mode,        /* SIOCGIWMODE */
1156         r8192_wx_set_sens,        /* SIOCSIWSENS */
1157         r8192_wx_get_sens,        /* SIOCGIWSENS */
1158         NULL,                     /* SIOCSIWRANGE */
1159         rtl8180_wx_get_range,     /* SIOCGIWRANGE */
1160         NULL,                     /* SIOCSIWPRIV */
1161         NULL,                     /* SIOCGIWPRIV */
1162         NULL,                     /* SIOCSIWSTATS */
1163         NULL,                     /* SIOCGIWSTATS */
1164         dummy,                    /* SIOCSIWSPY */
1165         dummy,                    /* SIOCGIWSPY */
1166         NULL,                     /* SIOCGIWTHRSPY */
1167         NULL,                     /* SIOCWIWTHRSPY */
1168         r8192_wx_set_wap,         /* SIOCSIWAP */
1169         r8192_wx_get_wap,         /* SIOCGIWAP */
1170 #if (WIRELESS_EXT >= 18)
1171         r8192_wx_set_mlme,                     /* MLME-- */
1172 #else
1173          NULL,
1174 #endif
1175         dummy,                     /* SIOCGIWAPLIST -- depricated */
1176         r8192_wx_set_scan,        /* SIOCSIWSCAN */
1177         r8192_wx_get_scan,        /* SIOCGIWSCAN */
1178         r8192_wx_set_essid,       /* SIOCSIWESSID */
1179         r8192_wx_get_essid,       /* SIOCGIWESSID */
1180         dummy,                    /* SIOCSIWNICKN */
1181         dummy,                    /* SIOCGIWNICKN */
1182         NULL,                     /* -- hole -- */
1183         NULL,                     /* -- hole -- */
1184         r8192_wx_set_rate,        /* SIOCSIWRATE */
1185         r8192_wx_get_rate,        /* SIOCGIWRATE */
1186         r8192_wx_set_rts,                    /* SIOCSIWRTS */
1187         r8192_wx_get_rts,                    /* SIOCGIWRTS */
1188         r8192_wx_set_frag,        /* SIOCSIWFRAG */
1189         r8192_wx_get_frag,        /* SIOCGIWFRAG */
1190         dummy,                    /* SIOCSIWTXPOW */
1191         dummy,                    /* SIOCGIWTXPOW */
1192         r8192_wx_set_retry,       /* SIOCSIWRETRY */
1193         r8192_wx_get_retry,       /* SIOCGIWRETRY */
1194         r8192_wx_set_enc,         /* SIOCSIWENCODE */
1195         r8192_wx_get_enc,         /* SIOCGIWENCODE */
1196         r8192_wx_set_power,                    /* SIOCSIWPOWER */
1197         r8192_wx_get_power,                    /* SIOCGIWPOWER */
1198         NULL,                   /*---hole---*/
1199         NULL,                   /*---hole---*/
1200         r8192_wx_set_gen_ie,//NULL,                     /* SIOCSIWGENIE */
1201         NULL,                   /* SIOCSIWGENIE */
1202 #if (WIRELESS_EXT >= 18)
1203         r8192_wx_set_auth,//NULL,                       /* SIOCSIWAUTH */
1204         NULL,//r8192_wx_get_auth,//NULL,                        /* SIOCSIWAUTH */
1205         r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
1206 #else
1207         NULL,
1208         NULL,
1209         NULL,
1210 #endif
1211         NULL,//r8192_wx_get_enc_ext,//NULL,                     /* SIOCSIWENCODEEXT */
1212         NULL,                   /* SIOCSIWPMKSA */
1213         NULL,                    /*---hole---*/
1214
1215 };
1216
1217
1218 static const struct iw_priv_args r8192_private_args[] = {
1219
1220         {
1221                 SIOCIWFIRSTPRIV + 0x0,
1222                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1223         },
1224
1225         {
1226                 SIOCIWFIRSTPRIV + 0x1,
1227                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1228
1229         },
1230         {
1231                 SIOCIWFIRSTPRIV + 0x2,
1232                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1233         }
1234 #ifdef JOHN_IOCTL
1235         ,
1236         {
1237                 SIOCIWFIRSTPRIV + 0x3,
1238                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1239         }
1240         ,
1241         {
1242                 SIOCIWFIRSTPRIV + 0x4,
1243                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1244         }
1245         ,
1246         {
1247                 SIOCIWFIRSTPRIV + 0x5,
1248                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1249         }
1250         ,
1251         {
1252                 SIOCIWFIRSTPRIV + 0x6,
1253                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1254         }
1255         ,
1256         {
1257                 SIOCIWFIRSTPRIV + 0x7,
1258                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1259         }
1260         ,
1261         {
1262                 SIOCIWFIRSTPRIV + 0x8,
1263                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1264         }
1265         ,
1266         {
1267                 SIOCIWFIRSTPRIV + 0x9,
1268                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1269         }
1270
1271 #endif
1272         ,
1273         {
1274                 SIOCIWFIRSTPRIV + 0x3,
1275                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1276
1277         }
1278
1279 };
1280
1281
1282 static iw_handler r8192_private_handler[] = {
1283 //      r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
1284         r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
1285 //      r8192_wx_set_forceassociate,
1286 //      r8192_wx_set_beaconinterval,
1287 //      r8192_wx_set_monitor_type,
1288         r8192_wx_set_scan_type,
1289         r8192_wx_set_rawtx,
1290 #ifdef JOHN_IOCTL
1291         r8192_wx_read_regs,
1292         r8192_wx_write_regs,
1293         r8192_wx_read_bb,
1294         r8192_wx_write_bb,
1295         r8192_wx_read_nicb,
1296         r8192_wx_write_nicb,
1297         r8192_wx_get_ap_status
1298 #endif
1299         r8192_wx_force_reset,
1300 };
1301
1302 //#if WIRELESS_EXT >= 17
1303 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1304 {
1305        struct r8192_priv *priv = ieee80211_priv(dev);
1306         struct ieee80211_device* ieee = priv->ieee80211;
1307         struct iw_statistics* wstats = &priv->wstats;
1308         int tmp_level = 0;
1309         int tmp_qual = 0;
1310         int tmp_noise = 0;
1311         if(ieee->state < IEEE80211_LINKED)
1312         {
1313                 wstats->qual.qual = 0;
1314                 wstats->qual.level = 0;
1315                 wstats->qual.noise = 0;
1316                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1317                 return wstats;
1318         }
1319
1320        tmp_level = (&ieee->current_network)->stats.rssi;
1321         tmp_qual = (&ieee->current_network)->stats.signal;
1322         tmp_noise = (&ieee->current_network)->stats.noise;
1323         //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1324
1325         wstats->qual.level = tmp_level;
1326         wstats->qual.qual = tmp_qual;
1327         wstats->qual.noise = tmp_noise;
1328         wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1329         return wstats;
1330 }
1331 //#endif
1332
1333
1334 struct iw_handler_def  r8192_wx_handlers_def={
1335         .standard = r8192_wx_handlers,
1336         .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1337         .private = r8192_private_handler,
1338         .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1339         .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1340 #if WIRELESS_EXT >= 17
1341         .get_wireless_stats = r8192_get_wireless_stats,
1342 #endif
1343         .private_args = (struct iw_priv_args *)r8192_private_args,
1344 };