staging: Convert __FUNCTION__ to __func__
[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",__func__, *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         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
323                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
324         tmp->scan_capa = 0x01;
325         return 0;
326 }
327
328
329 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
330                              union iwreq_data *wrqu, char *b)
331 {
332         struct r8192_priv *priv = ieee80211_priv(dev);
333         struct ieee80211_device *ieee = priv->ieee80211;
334         int ret = 0;
335
336         if(!priv->up) return -ENETDOWN;
337
338         if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
339                 return -EAGAIN;
340         if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
341         {
342                 struct iw_scan_req *req = (struct iw_scan_req *)b;
343                 if (req->essid_len)
344                 {
345                         //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
346                         ieee->current_network.ssid_len = req->essid_len;
347                         memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
348                         //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
349                 }
350         }
351
352         down(&priv->wx_sem);
353         if(priv->ieee80211->state != IEEE80211_LINKED){
354                 priv->ieee80211->scanning = 0;
355                 ieee80211_softmac_scan_syncro(priv->ieee80211);
356                 ret = 0;
357         }
358         else
359         ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
360         up(&priv->wx_sem);
361         return ret;
362 }
363
364
365 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
366                              union iwreq_data *wrqu, char *b)
367 {
368
369         int ret;
370         struct r8192_priv *priv = ieee80211_priv(dev);
371
372         if(!priv->up) return -ENETDOWN;
373
374         down(&priv->wx_sem);
375
376         ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
377
378         up(&priv->wx_sem);
379
380         return ret;
381 }
382
383 static int r8192_wx_set_essid(struct net_device *dev,
384                               struct iw_request_info *a,
385                               union iwreq_data *wrqu, char *b)
386 {
387         struct r8192_priv *priv = ieee80211_priv(dev);
388         int ret;
389         down(&priv->wx_sem);
390
391         ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
392
393         up(&priv->wx_sem);
394
395         return ret;
396 }
397
398
399
400
401 static int r8192_wx_get_essid(struct net_device *dev,
402                               struct iw_request_info *a,
403                               union iwreq_data *wrqu, char *b)
404 {
405         int ret;
406         struct r8192_priv *priv = ieee80211_priv(dev);
407
408         down(&priv->wx_sem);
409
410         ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
411
412         up(&priv->wx_sem);
413
414         return ret;
415 }
416
417
418 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
419                              union iwreq_data *wrqu, char *b)
420 {
421         int ret;
422         struct r8192_priv *priv = ieee80211_priv(dev);
423
424         down(&priv->wx_sem);
425
426         ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
427
428         up(&priv->wx_sem);
429         return ret;
430 }
431
432 static int r8192_wx_get_name(struct net_device *dev,
433                              struct iw_request_info *info,
434                              union iwreq_data *wrqu, char *extra)
435 {
436         struct r8192_priv *priv = ieee80211_priv(dev);
437         return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
438 }
439
440
441 static int r8192_wx_set_frag(struct net_device *dev,
442                              struct iw_request_info *info,
443                              union iwreq_data *wrqu, char *extra)
444 {
445         struct r8192_priv *priv = ieee80211_priv(dev);
446
447         if (wrqu->frag.disabled)
448                 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
449         else {
450                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
451                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
452                         return -EINVAL;
453
454                 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
455         }
456
457         return 0;
458 }
459
460
461 static int r8192_wx_get_frag(struct net_device *dev,
462                              struct iw_request_info *info,
463                              union iwreq_data *wrqu, char *extra)
464 {
465         struct r8192_priv *priv = ieee80211_priv(dev);
466
467         wrqu->frag.value = priv->ieee80211->fts;
468         wrqu->frag.fixed = 0;   /* no auto select */
469         wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
470
471         return 0;
472 }
473
474
475 static int r8192_wx_set_wap(struct net_device *dev,
476                          struct iw_request_info *info,
477                          union iwreq_data *awrq,
478                          char *extra)
479 {
480
481         int ret;
482         struct r8192_priv *priv = ieee80211_priv(dev);
483 //        struct sockaddr *temp = (struct sockaddr *)awrq;
484         down(&priv->wx_sem);
485
486         ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
487
488         up(&priv->wx_sem);
489
490         return ret;
491
492 }
493
494
495 static int r8192_wx_get_wap(struct net_device *dev,
496                             struct iw_request_info *info,
497                             union iwreq_data *wrqu, char *extra)
498 {
499         struct r8192_priv *priv = ieee80211_priv(dev);
500
501         return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
502 }
503
504
505 static int r8192_wx_get_enc(struct net_device *dev,
506                             struct iw_request_info *info,
507                             union iwreq_data *wrqu, char *key)
508 {
509         struct r8192_priv *priv = ieee80211_priv(dev);
510
511         return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
512 }
513
514 static int r8192_wx_set_enc(struct net_device *dev,
515                             struct iw_request_info *info,
516                             union iwreq_data *wrqu, char *key)
517 {
518         struct r8192_priv *priv = ieee80211_priv(dev);
519         struct ieee80211_device *ieee = priv->ieee80211;
520         int ret;
521
522         //u32 TargetContent;
523         u32 hwkey[4]={0,0,0,0};
524         u8 mask=0xff;
525         u32 key_idx=0;
526         //u8 broadcast_addr[6] ={       0xff,0xff,0xff,0xff,0xff,0xff};
527         u8 zero_addr[4][6] ={   {0x00,0x00,0x00,0x00,0x00,0x00},
528                                 {0x00,0x00,0x00,0x00,0x00,0x01},
529                                 {0x00,0x00,0x00,0x00,0x00,0x02},
530                                 {0x00,0x00,0x00,0x00,0x00,0x03} };
531         int i;
532
533        if(!priv->up) return -ENETDOWN;
534
535         down(&priv->wx_sem);
536
537         RT_TRACE(COMP_SEC, "Setting SW wep key");
538         ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
539
540         up(&priv->wx_sem);
541
542
543
544         //sometimes, the length is zero while we do not type key value
545         if(wrqu->encoding.length!=0){
546
547                 for(i=0 ; i<4 ; i++){
548                         hwkey[i] |=  key[4*i+0]&mask;
549                         if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
550                         if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
551                         hwkey[i] |= (key[4*i+1]&mask)<<8;
552                         hwkey[i] |= (key[4*i+2]&mask)<<16;
553                         hwkey[i] |= (key[4*i+3]&mask)<<24;
554                 }
555
556                 #define CONF_WEP40  0x4
557                 #define CONF_WEP104 0x14
558
559                 switch (wrqu->encoding.flags & IW_ENCODE_INDEX){
560                 case 0: key_idx = ieee->tx_keyidx; break;
561                 case 1: key_idx = 0; break;
562                 case 2: key_idx = 1; break;
563                 case 3: key_idx = 2; break;
564                 case 4: key_idx = 3; break;
565                 default: break;
566                 }
567
568                 if(wrqu->encoding.length==0x5){
569                                 ieee->pairwise_key_type = KEY_TYPE_WEP40;
570                         EnableHWSecurityConfig8192(dev);
571
572                         setKey( dev,
573                                 key_idx,                //EntryNo
574                                 key_idx,                //KeyIndex
575                                 KEY_TYPE_WEP40,         //KeyType
576                                 zero_addr[key_idx],
577                                 0,                      //DefaultKey
578                                 hwkey);                 //KeyContent
579
580                 }
581
582                 else if(wrqu->encoding.length==0xd){
583                                 ieee->pairwise_key_type = KEY_TYPE_WEP104;
584                                 EnableHWSecurityConfig8192(dev);
585
586                         setKey( dev,
587                                 key_idx,                //EntryNo
588                                 key_idx,                //KeyIndex
589                                 KEY_TYPE_WEP104,        //KeyType
590                                 zero_addr[key_idx],
591                                 0,                      //DefaultKey
592                                 hwkey);                 //KeyContent
593
594                 }
595                 else printk("wrong type in WEP, not WEP40 and WEP104\n");
596
597         }
598
599         return ret;
600 }
601
602
603 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
604  iwreq_data *wrqu, char *p){
605
606         struct r8192_priv *priv = ieee80211_priv(dev);
607         int *parms=(int *)p;
608         int mode=parms[0];
609
610         priv->ieee80211->active_scan = mode;
611
612         return 1;
613 }
614
615
616
617 static int r8192_wx_set_retry(struct net_device *dev,
618                                 struct iw_request_info *info,
619                                 union iwreq_data *wrqu, char *extra)
620 {
621         struct r8192_priv *priv = ieee80211_priv(dev);
622         int err = 0;
623
624         down(&priv->wx_sem);
625
626         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
627             wrqu->retry.disabled){
628                 err = -EINVAL;
629                 goto exit;
630         }
631         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
632                 err = -EINVAL;
633                 goto exit;
634         }
635
636         if(wrqu->retry.value > R8180_MAX_RETRY){
637                 err= -EINVAL;
638                 goto exit;
639         }
640         if (wrqu->retry.flags & IW_RETRY_MAX) {
641                 priv->retry_rts = wrqu->retry.value;
642                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
643
644         }else {
645                 priv->retry_data = wrqu->retry.value;
646                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
647         }
648
649         /* FIXME !
650          * We might try to write directly the TX config register
651          * or to restart just the (R)TX process.
652          * I'm unsure if whole reset is really needed
653          */
654
655         rtl8192_commit(dev);
656         /*
657         if(priv->up){
658                 rtl8180_rtx_disable(dev);
659                 rtl8180_rx_enable(dev);
660                 rtl8180_tx_enable(dev);
661
662         }
663         */
664 exit:
665         up(&priv->wx_sem);
666
667         return err;
668 }
669
670 static int r8192_wx_get_retry(struct net_device *dev,
671                                 struct iw_request_info *info,
672                                 union iwreq_data *wrqu, char *extra)
673 {
674         struct r8192_priv *priv = ieee80211_priv(dev);
675
676
677         wrqu->retry.disabled = 0; /* can't be disabled */
678
679         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
680             IW_RETRY_LIFETIME)
681                 return -EINVAL;
682
683         if (wrqu->retry.flags & IW_RETRY_MAX) {
684                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
685                 wrqu->retry.value = priv->retry_rts;
686         } else {
687                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
688                 wrqu->retry.value = priv->retry_data;
689         }
690         //printk("returning %d",wrqu->retry.value);
691
692
693         return 0;
694 }
695
696 static int r8192_wx_get_sens(struct net_device *dev,
697                                 struct iw_request_info *info,
698                                 union iwreq_data *wrqu, char *extra)
699 {
700         struct r8192_priv *priv = ieee80211_priv(dev);
701         if(priv->rf_set_sens == NULL)
702                 return -1; /* we have not this support for this radio */
703         wrqu->sens.value = priv->sens;
704         return 0;
705 }
706
707
708 static int r8192_wx_set_sens(struct net_device *dev,
709                                 struct iw_request_info *info,
710                                 union iwreq_data *wrqu, char *extra)
711 {
712
713         struct r8192_priv *priv = ieee80211_priv(dev);
714
715         short err = 0;
716         down(&priv->wx_sem);
717         //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
718         if(priv->rf_set_sens == NULL) {
719                 err= -1; /* we have not this support for this radio */
720                 goto exit;
721         }
722         if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
723                 priv->sens = wrqu->sens.value;
724         else
725                 err= -EINVAL;
726
727 exit:
728         up(&priv->wx_sem);
729
730         return err;
731 }
732
733 //hw security need to reorganized.
734 static int r8192_wx_set_enc_ext(struct net_device *dev,
735                                         struct iw_request_info *info,
736                                         union iwreq_data *wrqu, char *extra)
737 {
738         int ret=0;
739         struct r8192_priv *priv = ieee80211_priv(dev);
740         struct ieee80211_device *ieee = priv->ieee80211;
741         //printk("===>%s()\n", __func__);
742
743
744         down(&priv->wx_sem);
745         ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
746
747         {
748                 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
749                 u8 zero[6] = {0};
750                 u32 key[4] = {0};
751                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
752                 struct iw_point *encoding = &wrqu->encoding;
753                 u8 idx = 0, alg = 0, group = 0;
754                 if ((encoding->flags & IW_ENCODE_DISABLED) ||
755                 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
756                         goto end_hw_sec;
757
758                 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;
759                 idx = encoding->flags & IW_ENCODE_INDEX;
760                 if (idx)
761                         idx --;
762                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
763
764                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40))
765                 {
766                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
767                                 alg = KEY_TYPE_WEP104;
768                         ieee->pairwise_key_type = alg;
769                         EnableHWSecurityConfig8192(dev);
770                 }
771                 memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
772
773                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
774                 {
775
776                         setKey( dev,
777                                         idx,//EntryNo
778                                         idx, //KeyIndex
779                                         alg,  //KeyType
780                                         zero, //MacAddr
781                                         0,              //DefaultKey
782                                         key);           //KeyContent
783                 }
784                 else if (group)
785                 {
786                         ieee->group_key_type = alg;
787                         setKey( dev,
788                                         idx,//EntryNo
789                                         idx, //KeyIndex
790                                         alg,  //KeyType
791                                         broadcast_addr, //MacAddr
792                                         0,              //DefaultKey
793                                         key);           //KeyContent
794                 }
795                 else //pairwise key
796                 {
797                         setKey( dev,
798                                         4,//EntryNo
799                                         idx, //KeyIndex
800                                         alg,  //KeyType
801                                         (u8 *)ieee->ap_mac_addr, //MacAddr
802                                         0,              //DefaultKey
803                                         key);           //KeyContent
804                 }
805
806
807         }
808
809 end_hw_sec:
810
811         up(&priv->wx_sem);
812         return ret;
813
814 }
815 static int r8192_wx_set_auth(struct net_device *dev,
816                                         struct iw_request_info *info,
817                                         union iwreq_data *data, char *extra)
818 {
819         int ret=0;
820         //printk("====>%s()\n", __func__);
821         struct r8192_priv *priv = ieee80211_priv(dev);
822         down(&priv->wx_sem);
823         ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
824         up(&priv->wx_sem);
825         return ret;
826 }
827
828 static int r8192_wx_set_mlme(struct net_device *dev,
829                                         struct iw_request_info *info,
830                                         union iwreq_data *wrqu, char *extra)
831 {
832         //printk("====>%s()\n", __func__);
833
834         int ret=0;
835         struct r8192_priv *priv = ieee80211_priv(dev);
836         down(&priv->wx_sem);
837         ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
838
839         up(&priv->wx_sem);
840         return ret;
841 }
842
843 static int r8192_wx_set_gen_ie(struct net_device *dev,
844                                         struct iw_request_info *info,
845                                         union iwreq_data *data, char *extra)
846 {
847            //printk("====>%s(), len:%d\n", __func__, data->length);
848         int ret=0;
849         struct r8192_priv *priv = ieee80211_priv(dev);
850         down(&priv->wx_sem);
851         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
852         up(&priv->wx_sem);
853         //printk("<======%s(), ret:%d\n", __func__, ret);
854         return ret;
855
856
857 }
858
859 static int dummy(struct net_device *dev, struct iw_request_info *a,
860                  union iwreq_data *wrqu,char *b)
861 {
862         return -1;
863 }
864
865
866 static iw_handler r8192_wx_handlers[] =
867 {
868         NULL,                     /* SIOCSIWCOMMIT */
869         r8192_wx_get_name,        /* SIOCGIWNAME */
870         dummy,                    /* SIOCSIWNWID */
871         dummy,                    /* SIOCGIWNWID */
872         r8192_wx_set_freq,        /* SIOCSIWFREQ */
873         r8192_wx_get_freq,        /* SIOCGIWFREQ */
874         r8192_wx_set_mode,        /* SIOCSIWMODE */
875         r8192_wx_get_mode,        /* SIOCGIWMODE */
876         r8192_wx_set_sens,        /* SIOCSIWSENS */
877         r8192_wx_get_sens,        /* SIOCGIWSENS */
878         NULL,                     /* SIOCSIWRANGE */
879         rtl8180_wx_get_range,     /* SIOCGIWRANGE */
880         NULL,                     /* SIOCSIWPRIV */
881         NULL,                     /* SIOCGIWPRIV */
882         NULL,                     /* SIOCSIWSTATS */
883         NULL,                     /* SIOCGIWSTATS */
884         dummy,                    /* SIOCSIWSPY */
885         dummy,                    /* SIOCGIWSPY */
886         NULL,                     /* SIOCGIWTHRSPY */
887         NULL,                     /* SIOCWIWTHRSPY */
888         r8192_wx_set_wap,         /* SIOCSIWAP */
889         r8192_wx_get_wap,         /* SIOCGIWAP */
890         r8192_wx_set_mlme,                     /* MLME-- */
891         dummy,                     /* SIOCGIWAPLIST -- deprecated */
892         r8192_wx_set_scan,        /* SIOCSIWSCAN */
893         r8192_wx_get_scan,        /* SIOCGIWSCAN */
894         r8192_wx_set_essid,       /* SIOCSIWESSID */
895         r8192_wx_get_essid,       /* SIOCGIWESSID */
896         dummy,                    /* SIOCSIWNICKN */
897         dummy,                    /* SIOCGIWNICKN */
898         NULL,                     /* -- hole -- */
899         NULL,                     /* -- hole -- */
900         r8192_wx_set_rate,        /* SIOCSIWRATE */
901         r8192_wx_get_rate,        /* SIOCGIWRATE */
902         r8192_wx_set_rts,                    /* SIOCSIWRTS */
903         r8192_wx_get_rts,                    /* SIOCGIWRTS */
904         r8192_wx_set_frag,        /* SIOCSIWFRAG */
905         r8192_wx_get_frag,        /* SIOCGIWFRAG */
906         dummy,                    /* SIOCSIWTXPOW */
907         dummy,                    /* SIOCGIWTXPOW */
908         r8192_wx_set_retry,       /* SIOCSIWRETRY */
909         r8192_wx_get_retry,       /* SIOCGIWRETRY */
910         r8192_wx_set_enc,         /* SIOCSIWENCODE */
911         r8192_wx_get_enc,         /* SIOCGIWENCODE */
912         r8192_wx_set_power,                    /* SIOCSIWPOWER */
913         r8192_wx_get_power,                    /* SIOCGIWPOWER */
914         NULL,                   /*---hole---*/
915         NULL,                   /*---hole---*/
916         r8192_wx_set_gen_ie,//NULL,                     /* SIOCSIWGENIE */
917         NULL,                   /* SIOCSIWGENIE */
918
919         r8192_wx_set_auth,//NULL,                       /* SIOCSIWAUTH */
920         NULL,//r8192_wx_get_auth,//NULL,                        /* SIOCSIWAUTH */
921         r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
922         NULL,//r8192_wx_get_enc_ext,//NULL,                     /* SIOCSIWENCODEEXT */
923         NULL,                   /* SIOCSIWPMKSA */
924         NULL,                    /*---hole---*/
925
926 };
927
928
929 static const struct iw_priv_args r8192_private_args[] = {
930
931         {
932                 SIOCIWFIRSTPRIV + 0x0,
933                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
934         },
935
936         {
937                 SIOCIWFIRSTPRIV + 0x1,
938                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
939
940         },
941         {
942                 SIOCIWFIRSTPRIV + 0x2,
943                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
944         },
945         {
946                 SIOCIWFIRSTPRIV + 0x3,
947                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
948
949         }
950
951 };
952
953
954 static iw_handler r8192_private_handler[] = {
955 //      r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
956         r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
957 //      r8192_wx_set_forceassociate,
958 //      r8192_wx_set_beaconinterval,
959 //      r8192_wx_set_monitor_type,
960         r8192_wx_set_scan_type,
961         r8192_wx_set_rawtx,
962         //r8192_wx_null,
963         r8192_wx_force_reset,
964 };
965
966 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
967 {
968        struct r8192_priv *priv = ieee80211_priv(dev);
969         struct ieee80211_device *ieee = priv->ieee80211;
970         struct iw_statistics *wstats = &priv->wstats;
971         int tmp_level = 0;
972         int tmp_qual = 0;
973         int tmp_noise = 0;
974         if(ieee->state < IEEE80211_LINKED)
975         {
976                 wstats->qual.qual = 0;
977                 wstats->qual.level = 0;
978                 wstats->qual.noise = 0;
979                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
980                 return wstats;
981         }
982
983        tmp_level = (&ieee->current_network)->stats.rssi;
984         tmp_qual = (&ieee->current_network)->stats.signal;
985         tmp_noise = (&ieee->current_network)->stats.noise;
986         //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
987
988         wstats->qual.level = tmp_level;
989         wstats->qual.qual = tmp_qual;
990         wstats->qual.noise = tmp_noise;
991         wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
992         return wstats;
993 }
994
995
996 struct iw_handler_def  r8192_wx_handlers_def={
997         .standard = r8192_wx_handlers,
998         .num_standard = ARRAY_SIZE(r8192_wx_handlers),
999         .private = r8192_private_handler,
1000         .num_private = ARRAY_SIZE(r8192_private_handler),
1001         .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1002         .get_wireless_stats = r8192_get_wireless_stats,
1003         .private_args = (struct iw_priv_args *)r8192_private_args,
1004 };