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