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