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