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