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