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