staging: rtl8192u: fix checkpatch braces warning
[firefly-linux-kernel-4.4.55.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  <andrea.merello@gmail.com>
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 static int r8192_wx_force_reset(struct net_device *dev,
131                 struct iw_request_info *info,
132                 union iwreq_data *wrqu, char *extra)
133 {
134         struct r8192_priv *priv = ieee80211_priv(dev);
135
136         down(&priv->wx_sem);
137
138         printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
139         priv->force_reset = *extra;
140         up(&priv->wx_sem);
141         return 0;
142
143 }
144
145
146 static int r8192_wx_set_rawtx(struct net_device *dev,
147                                struct iw_request_info *info,
148                                union iwreq_data *wrqu, char *extra)
149 {
150         struct r8192_priv *priv = ieee80211_priv(dev);
151         int ret;
152
153         down(&priv->wx_sem);
154
155         ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
156
157         up(&priv->wx_sem);
158
159         return ret;
160
161 }
162
163 static int r8192_wx_set_crcmon(struct net_device *dev,
164                                struct iw_request_info *info,
165                                union iwreq_data *wrqu, char *extra)
166 {
167         struct r8192_priv *priv = ieee80211_priv(dev);
168         int *parms = (int *)extra;
169         int enable = (parms[0] > 0);
170         short prev = priv->crcmon;
171
172         down(&priv->wx_sem);
173
174         if(enable)
175                 priv->crcmon=1;
176         else
177                 priv->crcmon=0;
178
179         DMESG("bad CRC in monitor mode are %s",
180               priv->crcmon ? "accepted" : "rejected");
181
182         if(prev != priv->crcmon && priv->up){
183                 //rtl8180_down(dev);
184                 //rtl8180_up(dev);
185         }
186
187         up(&priv->wx_sem);
188
189         return 0;
190 }
191
192 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
193                              union iwreq_data *wrqu, char *b)
194 {
195         struct r8192_priv *priv = ieee80211_priv(dev);
196         int ret;
197         down(&priv->wx_sem);
198
199         ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
200
201         rtl8192_set_rxconf(dev);
202
203         up(&priv->wx_sem);
204         return ret;
205 }
206
207 struct  iw_range_with_scan_capa {
208         /* Informative stuff (to choose between different interface) */
209         __u32           throughput;     /* To give an idea... */
210         /* In theory this value should be the maximum benchmarked
211          * TCP/IP throughput, because with most of these devices the
212          * bit rate is meaningless (overhead an co) to estimate how
213          * fast the connection will go and pick the fastest one.
214          * I suggest people to play with Netperf or any benchmark...
215          */
216
217         /* NWID (or domain id) */
218         __u32           min_nwid;       /* Minimal NWID we are able to set */
219         __u32           max_nwid;       /* Maximal NWID we are able to set */
220
221         /* Old Frequency (backward compat - moved lower ) */
222         __u16           old_num_channels;
223         __u8            old_num_frequency;
224
225         /* Scan capabilities */
226         __u8            scan_capa;
227 };
228 static int rtl8180_wx_get_range(struct net_device *dev,
229                                 struct iw_request_info *info,
230                                 union iwreq_data *wrqu, char *extra)
231 {
232         struct iw_range *range = (struct iw_range *)extra;
233         struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
234         struct r8192_priv *priv = ieee80211_priv(dev);
235         u16 val;
236         int i;
237
238         wrqu->data.length = sizeof(*range);
239         memset(range, 0, sizeof(*range));
240
241         /* Let's try to keep this struct in the same order as in
242          * linux/include/wireless.h
243          */
244
245         /* TODO: See what values we can set, and remove the ones we can't
246          * set, or fill them with some default data.
247          */
248
249         /* ~5 Mb/s real (802.11b) */
250         range->throughput = 5 * 1000 * 1000;
251
252         // TODO: Not used in 802.11b?
253 //      range->min_nwid;        /* Minimal NWID we are able to set */
254         // TODO: Not used in 802.11b?
255 //      range->max_nwid;        /* Maximal NWID we are able to set */
256
257         /* Old Frequency (backward compat - moved lower ) */
258 //      range->old_num_channels;
259 //      range->old_num_frequency;
260 //      range->old_freq[6]; /* Filler to keep "version" at the same offset */
261         if(priv->rf_set_sens != NULL)
262                 range->sensitivity = priv->max_sens;    /* signal level threshold range */
263
264         range->max_qual.qual = 100;
265         /* TODO: Find real max RSSI and stick here */
266         range->max_qual.level = 0;
267         range->max_qual.noise = -98;
268         range->max_qual.updated = 7; /* Updated all three */
269
270         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
271         /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
272         range->avg_qual.level = 20 + -98;
273         range->avg_qual.noise = 0;
274         range->avg_qual.updated = 7; /* Updated all three */
275
276         range->num_bitrates = RATE_COUNT;
277
278         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
279                 range->bitrate[i] = rtl8180_rates[i];
280
281         range->min_frag = MIN_FRAG_THRESHOLD;
282         range->max_frag = MAX_FRAG_THRESHOLD;
283
284         range->min_pmp=0;
285         range->max_pmp = 5000000;
286         range->min_pmt = 0;
287         range->max_pmt = 65535*1000;
288         range->pmp_flags = IW_POWER_PERIOD;
289         range->pmt_flags = IW_POWER_TIMEOUT;
290         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
291
292         range->we_version_compiled = WIRELESS_EXT;
293         range->we_version_source = 16;
294
295 //      range->retry_capa;      /* What retry options are supported */
296 //      range->retry_flags;     /* How to decode max/min retry limit */
297 //      range->r_time_flags;    /* How to decode max/min retry life */
298 //      range->min_retry;       /* Minimal number of retries */
299 //      range->max_retry;       /* Maximal number of retries */
300 //      range->min_r_time;      /* Minimal retry lifetime */
301 //      range->max_r_time;      /* Maximal retry lifetime */
302
303
304         for (i = 0, val = 0; i < 14; i++) {
305
306                 // Include only legal frequencies for some countries
307                 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
308                         range->freq[val].i = i + 1;
309                         range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
310                         range->freq[val].e = 1;
311                         val++;
312                 } else {
313                         // FIXME: do we need to set anything for channels
314                         // we don't use ?
315                 }
316
317                 if (val == IW_MAX_FREQUENCIES)
318                 break;
319         }
320         range->num_frequency = val;
321         range->num_channels = val;
322 #if WIRELESS_EXT > 17
323         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
324                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
325 #endif
326         tmp->scan_capa = 0x01;
327         return 0;
328 }
329
330
331 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
332                              union iwreq_data *wrqu, char *b)
333 {
334         struct r8192_priv *priv = ieee80211_priv(dev);
335         struct ieee80211_device *ieee = priv->ieee80211;
336         int ret = 0;
337
338         if(!priv->up) return -ENETDOWN;
339
340         if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
341                 return -EAGAIN;
342         if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
343         {
344                 struct iw_scan_req *req = (struct iw_scan_req *)b;
345                 if (req->essid_len)
346                 {
347                         //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
348                         ieee->current_network.ssid_len = req->essid_len;
349                         memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
350                         //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
351                 }
352         }
353
354         down(&priv->wx_sem);
355         if(priv->ieee80211->state != IEEE80211_LINKED){
356                 priv->ieee80211->scanning = 0;
357                 ieee80211_softmac_scan_syncro(priv->ieee80211);
358                 ret = 0;
359         }
360         else
361         ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
362         up(&priv->wx_sem);
363         return ret;
364 }
365
366
367 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
368                              union iwreq_data *wrqu, char *b)
369 {
370
371         int ret;
372         struct r8192_priv *priv = ieee80211_priv(dev);
373
374         if(!priv->up) return -ENETDOWN;
375
376         down(&priv->wx_sem);
377
378         ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
379
380         up(&priv->wx_sem);
381
382         return ret;
383 }
384
385 static int r8192_wx_set_essid(struct net_device *dev,
386                               struct iw_request_info *a,
387                               union iwreq_data *wrqu, char *b)
388 {
389         struct r8192_priv *priv = ieee80211_priv(dev);
390         int ret;
391         down(&priv->wx_sem);
392
393         ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
394
395         up(&priv->wx_sem);
396
397         return ret;
398 }
399
400
401
402
403 static int r8192_wx_get_essid(struct net_device *dev,
404                               struct iw_request_info *a,
405                               union iwreq_data *wrqu, char *b)
406 {
407         int ret;
408         struct r8192_priv *priv = ieee80211_priv(dev);
409
410         down(&priv->wx_sem);
411
412         ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
413
414         up(&priv->wx_sem);
415
416         return ret;
417 }
418
419
420 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
421                              union iwreq_data *wrqu, char *b)
422 {
423         int ret;
424         struct r8192_priv *priv = ieee80211_priv(dev);
425
426         down(&priv->wx_sem);
427
428         ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
429
430         up(&priv->wx_sem);
431         return ret;
432 }
433
434 static int r8192_wx_get_name(struct net_device *dev,
435                              struct iw_request_info *info,
436                              union iwreq_data *wrqu, char *extra)
437 {
438         struct r8192_priv *priv = ieee80211_priv(dev);
439         return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
440 }
441
442
443 static int r8192_wx_set_frag(struct net_device *dev,
444                              struct iw_request_info *info,
445                              union iwreq_data *wrqu, char *extra)
446 {
447         struct r8192_priv *priv = ieee80211_priv(dev);
448
449         if (wrqu->frag.disabled)
450                 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
451         else {
452                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
453                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
454                         return -EINVAL;
455
456                 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
457         }
458
459         return 0;
460 }
461
462
463 static int r8192_wx_get_frag(struct net_device *dev,
464                              struct iw_request_info *info,
465                              union iwreq_data *wrqu, char *extra)
466 {
467         struct r8192_priv *priv = ieee80211_priv(dev);
468
469         wrqu->frag.value = priv->ieee80211->fts;
470         wrqu->frag.fixed = 0;   /* no auto select */
471         wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
472
473         return 0;
474 }
475
476
477 static int r8192_wx_set_wap(struct net_device *dev,
478                          struct iw_request_info *info,
479                          union iwreq_data *awrq,
480                          char *extra)
481 {
482
483         int ret;
484         struct r8192_priv *priv = ieee80211_priv(dev);
485 //        struct sockaddr *temp = (struct sockaddr *)awrq;
486         down(&priv->wx_sem);
487
488         ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
489
490         up(&priv->wx_sem);
491
492         return ret;
493
494 }
495
496
497 static int r8192_wx_get_wap(struct net_device *dev,
498                             struct iw_request_info *info,
499                             union iwreq_data *wrqu, char *extra)
500 {
501         struct r8192_priv *priv = ieee80211_priv(dev);
502
503         return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
504 }
505
506
507 static int r8192_wx_get_enc(struct net_device *dev,
508                             struct iw_request_info *info,
509                             union iwreq_data *wrqu, char *key)
510 {
511         struct r8192_priv *priv = ieee80211_priv(dev);
512
513         return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
514 }
515
516 static int r8192_wx_set_enc(struct net_device *dev,
517                             struct iw_request_info *info,
518                             union iwreq_data *wrqu, char *key)
519 {
520         struct r8192_priv *priv = ieee80211_priv(dev);
521         struct ieee80211_device *ieee = priv->ieee80211;
522         int ret;
523
524         //u32 TargetContent;
525         u32 hwkey[4]={0,0,0,0};
526         u8 mask=0xff;
527         u32 key_idx=0;
528         //u8 broadcast_addr[6] ={       0xff,0xff,0xff,0xff,0xff,0xff};
529         u8 zero_addr[4][6] ={   {0x00,0x00,0x00,0x00,0x00,0x00},
530                                 {0x00,0x00,0x00,0x00,0x00,0x01},
531                                 {0x00,0x00,0x00,0x00,0x00,0x02},
532                                 {0x00,0x00,0x00,0x00,0x00,0x03} };
533         int i;
534
535        if(!priv->up) return -ENETDOWN;
536
537         down(&priv->wx_sem);
538
539         RT_TRACE(COMP_SEC, "Setting SW wep key");
540         ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
541
542         up(&priv->wx_sem);
543
544
545
546         //sometimes, the length is zero while we do not type key value
547         if(wrqu->encoding.length!=0){
548
549                 for(i=0 ; i<4 ; i++){
550                         hwkey[i] |=  key[4*i+0]&mask;
551                         if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
552                         if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
553                         hwkey[i] |= (key[4*i+1]&mask)<<8;
554                         hwkey[i] |= (key[4*i+2]&mask)<<16;
555                         hwkey[i] |= (key[4*i+3]&mask)<<24;
556                 }
557
558                 #define CONF_WEP40  0x4
559                 #define CONF_WEP104 0x14
560
561                 switch (wrqu->encoding.flags & IW_ENCODE_INDEX){
562                 case 0: key_idx = ieee->tx_keyidx; break;
563                 case 1: key_idx = 0; break;
564                 case 2: key_idx = 1; break;
565                 case 3: key_idx = 2; break;
566                 case 4: key_idx = 3; break;
567                 default: break;
568                 }
569
570                 if(wrqu->encoding.length==0x5){
571                                 ieee->pairwise_key_type = KEY_TYPE_WEP40;
572                         EnableHWSecurityConfig8192(dev);
573
574                         setKey( dev,
575                                 key_idx,                //EntryNo
576                                 key_idx,                //KeyIndex
577                                 KEY_TYPE_WEP40,         //KeyType
578                                 zero_addr[key_idx],
579                                 0,                      //DefaultKey
580                                 hwkey);                 //KeyContent
581
582                 }
583
584                 else if(wrqu->encoding.length==0xd){
585                                 ieee->pairwise_key_type = KEY_TYPE_WEP104;
586                                 EnableHWSecurityConfig8192(dev);
587
588                         setKey( dev,
589                                 key_idx,                //EntryNo
590                                 key_idx,                //KeyIndex
591                                 KEY_TYPE_WEP104,        //KeyType
592                                 zero_addr[key_idx],
593                                 0,                      //DefaultKey
594                                 hwkey);                 //KeyContent
595
596                 }
597                 else printk("wrong type in WEP, not WEP40 and WEP104\n");
598
599         }
600
601         return ret;
602 }
603
604
605 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
606  iwreq_data *wrqu, char *p){
607
608         struct r8192_priv *priv = ieee80211_priv(dev);
609         int *parms=(int *)p;
610         int mode=parms[0];
611
612         priv->ieee80211->active_scan = mode;
613
614         return 1;
615 }
616
617
618
619 static int r8192_wx_set_retry(struct net_device *dev,
620                                 struct iw_request_info *info,
621                                 union iwreq_data *wrqu, char *extra)
622 {
623         struct r8192_priv *priv = ieee80211_priv(dev);
624         int err = 0;
625
626         down(&priv->wx_sem);
627
628         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
629             wrqu->retry.disabled){
630                 err = -EINVAL;
631                 goto exit;
632         }
633         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
634                 err = -EINVAL;
635                 goto exit;
636         }
637
638         if(wrqu->retry.value > R8180_MAX_RETRY){
639                 err= -EINVAL;
640                 goto exit;
641         }
642         if (wrqu->retry.flags & IW_RETRY_MAX) {
643                 priv->retry_rts = wrqu->retry.value;
644                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
645
646         }else {
647                 priv->retry_data = wrqu->retry.value;
648                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
649         }
650
651         /* FIXME !
652          * We might try to write directly the TX config register
653          * or to restart just the (R)TX process.
654          * I'm unsure if whole reset is really needed
655          */
656
657         rtl8192_commit(dev);
658         /*
659         if(priv->up){
660                 rtl8180_rtx_disable(dev);
661                 rtl8180_rx_enable(dev);
662                 rtl8180_tx_enable(dev);
663
664         }
665         */
666 exit:
667         up(&priv->wx_sem);
668
669         return err;
670 }
671
672 static int r8192_wx_get_retry(struct net_device *dev,
673                                 struct iw_request_info *info,
674                                 union iwreq_data *wrqu, char *extra)
675 {
676         struct r8192_priv *priv = ieee80211_priv(dev);
677
678
679         wrqu->retry.disabled = 0; /* can't be disabled */
680
681         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
682             IW_RETRY_LIFETIME)
683                 return -EINVAL;
684
685         if (wrqu->retry.flags & IW_RETRY_MAX) {
686                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
687                 wrqu->retry.value = priv->retry_rts;
688         } else {
689                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
690                 wrqu->retry.value = priv->retry_data;
691         }
692         //printk("returning %d",wrqu->retry.value);
693
694
695         return 0;
696 }
697
698 static int r8192_wx_get_sens(struct net_device *dev,
699                                 struct iw_request_info *info,
700                                 union iwreq_data *wrqu, char *extra)
701 {
702         struct r8192_priv *priv = ieee80211_priv(dev);
703         if(priv->rf_set_sens == NULL)
704                 return -1; /* we have not this support for this radio */
705         wrqu->sens.value = priv->sens;
706         return 0;
707 }
708
709
710 static int r8192_wx_set_sens(struct net_device *dev,
711                                 struct iw_request_info *info,
712                                 union iwreq_data *wrqu, char *extra)
713 {
714
715         struct r8192_priv *priv = ieee80211_priv(dev);
716
717         short err = 0;
718         down(&priv->wx_sem);
719         //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
720         if(priv->rf_set_sens == NULL) {
721                 err= -1; /* we have not this support for this radio */
722                 goto exit;
723         }
724         if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
725                 priv->sens = wrqu->sens.value;
726         else
727                 err= -EINVAL;
728
729 exit:
730         up(&priv->wx_sem);
731
732         return err;
733 }
734
735 #if (WIRELESS_EXT >= 18)
736 //hw security need to reorganized.
737 static int r8192_wx_set_enc_ext(struct net_device *dev,
738                                         struct iw_request_info *info,
739                                         union iwreq_data *wrqu, char *extra)
740 {
741         int ret=0;
742         struct r8192_priv *priv = ieee80211_priv(dev);
743         struct ieee80211_device *ieee = priv->ieee80211;
744         //printk("===>%s()\n", __FUNCTION__);
745
746
747         down(&priv->wx_sem);
748         ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
749
750         {
751                 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
752                 u8 zero[6] = {0};
753                 u32 key[4] = {0};
754                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
755                 struct iw_point *encoding = &wrqu->encoding;
756                 u8 idx = 0, alg = 0, group = 0;
757                 if ((encoding->flags & IW_ENCODE_DISABLED) ||
758                 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
759                         goto end_hw_sec;
760
761                 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;
762                 idx = encoding->flags & IW_ENCODE_INDEX;
763                 if (idx)
764                         idx --;
765                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
766
767                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40))
768                 {
769                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
770                                 alg = KEY_TYPE_WEP104;
771                         ieee->pairwise_key_type = alg;
772                         EnableHWSecurityConfig8192(dev);
773                 }
774                 memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
775
776                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
777                 {
778
779                         setKey( dev,
780                                         idx,//EntryNo
781                                         idx, //KeyIndex
782                                         alg,  //KeyType
783                                         zero, //MacAddr
784                                         0,              //DefaultKey
785                                         key);           //KeyContent
786                 }
787                 else if (group)
788                 {
789                         ieee->group_key_type = alg;
790                         setKey( dev,
791                                         idx,//EntryNo
792                                         idx, //KeyIndex
793                                         alg,  //KeyType
794                                         broadcast_addr, //MacAddr
795                                         0,              //DefaultKey
796                                         key);           //KeyContent
797                 }
798                 else //pairwise key
799                 {
800                         setKey( dev,
801                                         4,//EntryNo
802                                         idx, //KeyIndex
803                                         alg,  //KeyType
804                                         (u8 *)ieee->ap_mac_addr, //MacAddr
805                                         0,              //DefaultKey
806                                         key);           //KeyContent
807                 }
808
809
810         }
811
812 end_hw_sec:
813
814         up(&priv->wx_sem);
815         return ret;
816
817 }
818 static int r8192_wx_set_auth(struct net_device *dev,
819                                         struct iw_request_info *info,
820                                         union iwreq_data *data, char *extra)
821 {
822         int ret=0;
823         //printk("====>%s()\n", __FUNCTION__);
824         struct r8192_priv *priv = ieee80211_priv(dev);
825         down(&priv->wx_sem);
826         ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
827         up(&priv->wx_sem);
828         return ret;
829 }
830
831 static int r8192_wx_set_mlme(struct net_device *dev,
832                                         struct iw_request_info *info,
833                                         union iwreq_data *wrqu, char *extra)
834 {
835         //printk("====>%s()\n", __FUNCTION__);
836
837         int ret=0;
838         struct r8192_priv *priv = ieee80211_priv(dev);
839         down(&priv->wx_sem);
840         ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
841
842         up(&priv->wx_sem);
843         return ret;
844 }
845 #endif
846 static int r8192_wx_set_gen_ie(struct net_device *dev,
847                                         struct iw_request_info *info,
848                                         union iwreq_data *data, char *extra)
849 {
850            //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
851         int ret=0;
852         struct r8192_priv *priv = ieee80211_priv(dev);
853         down(&priv->wx_sem);
854         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
855         up(&priv->wx_sem);
856         //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
857         return ret;
858
859
860 }
861
862 static int dummy(struct net_device *dev, struct iw_request_info *a,
863                  union iwreq_data *wrqu,char *b)
864 {
865         return -1;
866 }
867
868
869 static iw_handler r8192_wx_handlers[] =
870 {
871         NULL,                     /* SIOCSIWCOMMIT */
872         r8192_wx_get_name,        /* SIOCGIWNAME */
873         dummy,                    /* SIOCSIWNWID */
874         dummy,                    /* SIOCGIWNWID */
875         r8192_wx_set_freq,        /* SIOCSIWFREQ */
876         r8192_wx_get_freq,        /* SIOCGIWFREQ */
877         r8192_wx_set_mode,        /* SIOCSIWMODE */
878         r8192_wx_get_mode,        /* SIOCGIWMODE */
879         r8192_wx_set_sens,        /* SIOCSIWSENS */
880         r8192_wx_get_sens,        /* SIOCGIWSENS */
881         NULL,                     /* SIOCSIWRANGE */
882         rtl8180_wx_get_range,     /* SIOCGIWRANGE */
883         NULL,                     /* SIOCSIWPRIV */
884         NULL,                     /* SIOCGIWPRIV */
885         NULL,                     /* SIOCSIWSTATS */
886         NULL,                     /* SIOCGIWSTATS */
887         dummy,                    /* SIOCSIWSPY */
888         dummy,                    /* SIOCGIWSPY */
889         NULL,                     /* SIOCGIWTHRSPY */
890         NULL,                     /* SIOCWIWTHRSPY */
891         r8192_wx_set_wap,         /* SIOCSIWAP */
892         r8192_wx_get_wap,         /* SIOCGIWAP */
893 #if (WIRELESS_EXT >= 18)
894         r8192_wx_set_mlme,                     /* MLME-- */
895 #else
896          NULL,
897 #endif
898         dummy,                     /* SIOCGIWAPLIST -- deprecated */
899         r8192_wx_set_scan,        /* SIOCSIWSCAN */
900         r8192_wx_get_scan,        /* SIOCGIWSCAN */
901         r8192_wx_set_essid,       /* SIOCSIWESSID */
902         r8192_wx_get_essid,       /* SIOCGIWESSID */
903         dummy,                    /* SIOCSIWNICKN */
904         dummy,                    /* SIOCGIWNICKN */
905         NULL,                     /* -- hole -- */
906         NULL,                     /* -- hole -- */
907         r8192_wx_set_rate,        /* SIOCSIWRATE */
908         r8192_wx_get_rate,        /* SIOCGIWRATE */
909         r8192_wx_set_rts,                    /* SIOCSIWRTS */
910         r8192_wx_get_rts,                    /* SIOCGIWRTS */
911         r8192_wx_set_frag,        /* SIOCSIWFRAG */
912         r8192_wx_get_frag,        /* SIOCGIWFRAG */
913         dummy,                    /* SIOCSIWTXPOW */
914         dummy,                    /* SIOCGIWTXPOW */
915         r8192_wx_set_retry,       /* SIOCSIWRETRY */
916         r8192_wx_get_retry,       /* SIOCGIWRETRY */
917         r8192_wx_set_enc,         /* SIOCSIWENCODE */
918         r8192_wx_get_enc,         /* SIOCGIWENCODE */
919         r8192_wx_set_power,                    /* SIOCSIWPOWER */
920         r8192_wx_get_power,                    /* SIOCGIWPOWER */
921         NULL,                   /*---hole---*/
922         NULL,                   /*---hole---*/
923         r8192_wx_set_gen_ie,//NULL,                     /* SIOCSIWGENIE */
924         NULL,                   /* SIOCSIWGENIE */
925
926 #if (WIRELESS_EXT >= 18)
927         r8192_wx_set_auth,//NULL,                       /* SIOCSIWAUTH */
928         NULL,//r8192_wx_get_auth,//NULL,                        /* SIOCSIWAUTH */
929         r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
930         NULL,//r8192_wx_get_enc_ext,//NULL,                     /* SIOCSIWENCODEEXT */
931 #else
932         NULL,
933         NULL,
934         NULL,
935         NULL,
936 #endif
937         NULL,                   /* SIOCSIWPMKSA */
938         NULL,                    /*---hole---*/
939
940 };
941
942
943 static const struct iw_priv_args r8192_private_args[] = {
944
945         {
946                 SIOCIWFIRSTPRIV + 0x0,
947                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
948         },
949
950         {
951                 SIOCIWFIRSTPRIV + 0x1,
952                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
953
954         },
955         {
956                 SIOCIWFIRSTPRIV + 0x2,
957                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
958         },
959         {
960                 SIOCIWFIRSTPRIV + 0x3,
961                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
962
963         }
964
965 };
966
967
968 static iw_handler r8192_private_handler[] = {
969 //      r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
970         r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
971 //      r8192_wx_set_forceassociate,
972 //      r8192_wx_set_beaconinterval,
973 //      r8192_wx_set_monitor_type,
974         r8192_wx_set_scan_type,
975         r8192_wx_set_rawtx,
976         //r8192_wx_null,
977         r8192_wx_force_reset,
978 };
979
980 //#if WIRELESS_EXT >= 17
981 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
982 {
983        struct r8192_priv *priv = ieee80211_priv(dev);
984         struct ieee80211_device *ieee = priv->ieee80211;
985         struct iw_statistics *wstats = &priv->wstats;
986         int tmp_level = 0;
987         int tmp_qual = 0;
988         int tmp_noise = 0;
989         if(ieee->state < IEEE80211_LINKED)
990         {
991                 wstats->qual.qual = 0;
992                 wstats->qual.level = 0;
993                 wstats->qual.noise = 0;
994                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
995                 return wstats;
996         }
997
998        tmp_level = (&ieee->current_network)->stats.rssi;
999         tmp_qual = (&ieee->current_network)->stats.signal;
1000         tmp_noise = (&ieee->current_network)->stats.noise;
1001         //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1002
1003         wstats->qual.level = tmp_level;
1004         wstats->qual.qual = tmp_qual;
1005         wstats->qual.noise = tmp_noise;
1006         wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1007         return wstats;
1008 }
1009 //#endif
1010
1011
1012 struct iw_handler_def  r8192_wx_handlers_def={
1013         .standard = r8192_wx_handlers,
1014         .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1015         .private = r8192_private_handler,
1016         .num_private = ARRAY_SIZE(r8192_private_handler),
1017         .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1018 #if WIRELESS_EXT >= 17
1019         .get_wireless_stats = r8192_get_wireless_stats,
1020 #endif
1021         .private_args = (struct iw_priv_args *)r8192_private_args,
1022 };