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