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