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