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