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