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