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