blob: 0b0f39ce3ced93f41271d82f3bedd4ec57e72bdd [file] [log] [blame]
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001/*
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 "r8192E.h"
22#include "r8192E_hw.h"
Greg Kroah-Hartman5e1ad182009-08-10 16:34:22 -070023#include "r8192E_wx.h"
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070024#ifdef ENABLE_DOT11D
david woo65a43782009-12-22 09:40:36 -080025#include "ieee80211/dot11d.h"
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070026#endif
27
28#define RATE_COUNT 12
Greg Kroah-Hartman5e1ad182009-08-10 16:34:22 -070029static u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070030 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31
32
33#ifndef ENETDOWN
34#define ENETDOWN 1
35#endif
36static int r8192_wx_get_freq(struct net_device *dev,
37 struct iw_request_info *a,
38 union iwreq_data *wrqu, char *b)
39{
40 struct r8192_priv *priv = ieee80211_priv(dev);
41
42 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
43}
44
45
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070046static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
48{
49 struct r8192_priv *priv=ieee80211_priv(dev);
50
51 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
52}
53
54
55
56static int r8192_wx_get_rate(struct net_device *dev,
57 struct iw_request_info *info,
58 union iwreq_data *wrqu, char *extra)
59{
60 struct r8192_priv *priv = ieee80211_priv(dev);
61 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
62}
63
64
65
66static int r8192_wx_set_rate(struct net_device *dev,
67 struct iw_request_info *info,
68 union iwreq_data *wrqu, char *extra)
69{
70 int ret;
71 struct r8192_priv *priv = ieee80211_priv(dev);
72
david woo65a43782009-12-22 09:40:36 -080073 if(priv->bHwRadioOff == true)
74 return 0;
75
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070076 down(&priv->wx_sem);
77
78 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
79
80 up(&priv->wx_sem);
81
82 return ret;
83}
84
85
86static int r8192_wx_set_rts(struct net_device *dev,
87 struct iw_request_info *info,
88 union iwreq_data *wrqu, char *extra)
89{
90 int ret;
91 struct r8192_priv *priv = ieee80211_priv(dev);
92
david woo65a43782009-12-22 09:40:36 -080093 if(priv->bHwRadioOff == true)
94 return 0;
95
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -070096 down(&priv->wx_sem);
97
98 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
99
100 up(&priv->wx_sem);
101
102 return ret;
103}
104
105static int r8192_wx_get_rts(struct net_device *dev,
106 struct iw_request_info *info,
107 union iwreq_data *wrqu, char *extra)
108{
109 struct r8192_priv *priv = ieee80211_priv(dev);
110 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
111}
112
113static int r8192_wx_set_power(struct net_device *dev,
114 struct iw_request_info *info,
115 union iwreq_data *wrqu, char *extra)
116{
117 int ret;
118 struct r8192_priv *priv = ieee80211_priv(dev);
119
david woo65a43782009-12-22 09:40:36 -0800120 if(priv->bHwRadioOff == true)
121 return 0;
122
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700123 down(&priv->wx_sem);
124
125 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
126
127 up(&priv->wx_sem);
128
129 return ret;
130}
131
132static int r8192_wx_get_power(struct net_device *dev,
133 struct iw_request_info *info,
134 union iwreq_data *wrqu, char *extra)
135{
136 struct r8192_priv *priv = ieee80211_priv(dev);
137 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
138}
139
140#ifdef JOHN_IOCTL
141u16 read_rtl8225(struct net_device *dev, u8 addr);
142void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
143u32 john_read_rtl8225(struct net_device *dev, u8 adr);
144void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
145
146static int r8192_wx_read_regs(struct net_device *dev,
147 struct iw_request_info *info,
148 union iwreq_data *wrqu, char *extra)
149{
150 struct r8192_priv *priv = ieee80211_priv(dev);
151 u8 addr;
152 u16 data1;
153
154 down(&priv->wx_sem);
155
156
157 get_user(addr,(u8*)wrqu->data.pointer);
158 data1 = read_rtl8225(dev, addr);
159 wrqu->data.length = data1;
160
161 up(&priv->wx_sem);
162 return 0;
163
164}
165
166static int r8192_wx_write_regs(struct net_device *dev,
167 struct iw_request_info *info,
168 union iwreq_data *wrqu, char *extra)
169{
170 struct r8192_priv *priv = ieee80211_priv(dev);
171 u8 addr;
172
173 down(&priv->wx_sem);
174
175 get_user(addr, (u8*)wrqu->data.pointer);
176 write_rtl8225(dev, addr, wrqu->data.length);
177
178 up(&priv->wx_sem);
179 return 0;
180
181}
182
183void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
184u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
185
186static int r8192_wx_read_bb(struct net_device *dev,
187 struct iw_request_info *info,
188 union iwreq_data *wrqu, char *extra)
189{
190 struct r8192_priv *priv = ieee80211_priv(dev);
191 u8 databb;
192#if 0
193 int i;
194 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
195#endif
196
197 down(&priv->wx_sem);
198
199 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
200 wrqu->data.length = databb;
201
202 up(&priv->wx_sem);
203 return 0;
204}
205
206void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
207static int r8192_wx_write_bb(struct net_device *dev,
208 struct iw_request_info *info,
209 union iwreq_data *wrqu, char *extra)
210{
211 struct r8192_priv *priv = ieee80211_priv(dev);
212 u8 databb;
213
214 down(&priv->wx_sem);
215
216 get_user(databb, (u8*)wrqu->data.pointer);
217 rtl8187_write_phy(dev, wrqu->data.length, databb);
218
219 up(&priv->wx_sem);
220 return 0;
221
222}
223
224
225static int r8192_wx_write_nicb(struct net_device *dev,
226 struct iw_request_info *info,
227 union iwreq_data *wrqu, char *extra)
228{
229 struct r8192_priv *priv = ieee80211_priv(dev);
230 u32 addr;
231
232 down(&priv->wx_sem);
233
234 get_user(addr, (u32*)wrqu->data.pointer);
235 write_nic_byte(dev, addr, wrqu->data.length);
236
237 up(&priv->wx_sem);
238 return 0;
239
240}
241static int r8192_wx_read_nicb(struct net_device *dev,
242 struct iw_request_info *info,
243 union iwreq_data *wrqu, char *extra)
244{
245 struct r8192_priv *priv = ieee80211_priv(dev);
246 u32 addr;
247 u16 data1;
248
249 down(&priv->wx_sem);
250
251 get_user(addr,(u32*)wrqu->data.pointer);
252 data1 = read_nic_byte(dev, addr);
253 wrqu->data.length = data1;
254
255 up(&priv->wx_sem);
256 return 0;
257}
258
259static int r8192_wx_get_ap_status(struct net_device *dev,
260 struct iw_request_info *info,
261 union iwreq_data *wrqu, char *extra)
262{
263 struct r8192_priv *priv = ieee80211_priv(dev);
264 struct ieee80211_device *ieee = priv->ieee80211;
265 struct ieee80211_network *target;
266 int name_len;
267
268 down(&priv->wx_sem);
269
270 //count the length of input ssid
271 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
272
273 //search for the correspoding info which is received
274 list_for_each_entry(target, &ieee->network_list, list) {
275 if ( (target->ssid_len == name_len) &&
276 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
277 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
278 //set flags=1 to indicate this ap is WPA
279 wrqu->data.flags = 1;
280 else wrqu->data.flags = 0;
281
282
283 break;
284 }
285 }
286
287 up(&priv->wx_sem);
288 return 0;
289}
290
291
292
293#endif
294
295static int r8192_wx_set_rawtx(struct net_device *dev,
296 struct iw_request_info *info,
297 union iwreq_data *wrqu, char *extra)
298{
299 struct r8192_priv *priv = ieee80211_priv(dev);
300 int ret;
301
david woo65a43782009-12-22 09:40:36 -0800302 if(priv->bHwRadioOff == true)
303 return 0;
304
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700305 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_force_reset(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
321 down(&priv->wx_sem);
322
323 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
324 priv->force_reset = *extra;
325 up(&priv->wx_sem);
326 return 0;
327
328}
329
330
331static int r8192_wx_set_crcmon(struct net_device *dev,
332 struct iw_request_info *info,
333 union iwreq_data *wrqu, char *extra)
334{
335 struct r8192_priv *priv = ieee80211_priv(dev);
336 int *parms = (int *)extra;
337 int enable = (parms[0] > 0);
338 short prev = priv->crcmon;
339
david woo65a43782009-12-22 09:40:36 -0800340 if(priv->bHwRadioOff == true)
341 return 0;
342
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700343 down(&priv->wx_sem);
344
345 if(enable)
346 priv->crcmon=1;
347 else
348 priv->crcmon=0;
349
350 DMESG("bad CRC in monitor mode are %s",
351 priv->crcmon ? "accepted" : "rejected");
352
353 if(prev != priv->crcmon && priv->up){
354 //rtl8180_down(dev);
355 //rtl8180_up(dev);
356 }
357
358 up(&priv->wx_sem);
359
360 return 0;
361}
362
363static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
364 union iwreq_data *wrqu, char *b)
365{
366 struct r8192_priv *priv = ieee80211_priv(dev);
367 RT_RF_POWER_STATE rtState;
368 int ret;
369
david woo65a43782009-12-22 09:40:36 -0800370 if(priv->bHwRadioOff == true)
371 return 0;
372
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700373 rtState = priv->ieee80211->eRFPowerState;
374 down(&priv->wx_sem);
375#ifdef ENABLE_IPS
376 if(wrqu->mode == IW_MODE_ADHOC){
377
378 if(priv->ieee80211->PowerSaveControl.bInactivePs){
379 if(rtState == eRfOff){
380 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
381 {
382 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
383 up(&priv->wx_sem);
384 return -1;
385 }
386 else{
david woo65a43782009-12-22 09:40:36 -0800387 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
388 down(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700389 IPSLeave(dev);
david woo65a43782009-12-22 09:40:36 -0800390 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700391 }
392 }
393 }
394 }
395#endif
396 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
397
398 //rtl8187_set_rxconf(dev);
399
400 up(&priv->wx_sem);
401 return ret;
402}
403
404struct iw_range_with_scan_capa
405{
406 /* Informative stuff (to choose between different interface) */
407 __u32 throughput; /* To give an idea... */
408 /* In theory this value should be the maximum benchmarked
409 * TCP/IP throughput, because with most of these devices the
410 * bit rate is meaningless (overhead an co) to estimate how
411 * fast the connection will go and pick the fastest one.
412 * I suggest people to play with Netperf or any benchmark...
413 */
414
415 /* NWID (or domain id) */
416 __u32 min_nwid; /* Minimal NWID we are able to set */
417 __u32 max_nwid; /* Maximal NWID we are able to set */
418
419 /* Old Frequency (backward compat - moved lower ) */
420 __u16 old_num_channels;
421 __u8 old_num_frequency;
422
423 /* Scan capabilities */
424 __u8 scan_capa;
425};
426static int rtl8180_wx_get_range(struct net_device *dev,
427 struct iw_request_info *info,
428 union iwreq_data *wrqu, char *extra)
429{
430 struct iw_range *range = (struct iw_range *)extra;
431 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
432 struct r8192_priv *priv = ieee80211_priv(dev);
433 u16 val;
434 int i;
435
436 wrqu->data.length = sizeof(*range);
437 memset(range, 0, sizeof(*range));
438
439 /* Let's try to keep this struct in the same order as in
440 * linux/include/wireless.h
441 */
442
443 /* TODO: See what values we can set, and remove the ones we can't
444 * set, or fill them with some default data.
445 */
446
447 /* ~5 Mb/s real (802.11b) */
david woo65a43782009-12-22 09:40:36 -0800448 range->throughput = 130 * 1000 * 1000;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700449
450 // TODO: Not used in 802.11b?
451// range->min_nwid; /* Minimal NWID we are able to set */
452 // TODO: Not used in 802.11b?
453// range->max_nwid; /* Maximal NWID we are able to set */
454
455 /* Old Frequency (backward compat - moved lower ) */
456// range->old_num_channels;
457// range->old_num_frequency;
458// range->old_freq[6]; /* Filler to keep "version" at the same offset */
459 if(priv->rf_set_sens != NULL)
460 range->sensitivity = priv->max_sens; /* signal level threshold range */
461
462 range->max_qual.qual = 100;
463 /* TODO: Find real max RSSI and stick here */
464 range->max_qual.level = 0;
465 range->max_qual.noise = -98;
466 range->max_qual.updated = 7; /* Updated all three */
467
468 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
André Goddard Rosabbc9a992009-11-14 13:09:06 -0200469 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700470 range->avg_qual.level = 20 + -98;
471 range->avg_qual.noise = 0;
472 range->avg_qual.updated = 7; /* Updated all three */
473
474 range->num_bitrates = RATE_COUNT;
475
476 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
477 range->bitrate[i] = rtl8180_rates[i];
478 }
479
480 range->min_frag = MIN_FRAG_THRESHOLD;
481 range->max_frag = MAX_FRAG_THRESHOLD;
482
483 range->min_pmp=0;
484 range->max_pmp = 5000000;
485 range->min_pmt = 0;
486 range->max_pmt = 65535*1000;
487 range->pmp_flags = IW_POWER_PERIOD;
488 range->pmt_flags = IW_POWER_TIMEOUT;
489 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
490 range->we_version_compiled = WIRELESS_EXT;
david woo65a43782009-12-22 09:40:36 -0800491 range->we_version_source = 18;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700492
493// range->retry_capa; /* What retry options are supported */
494// range->retry_flags; /* How to decode max/min retry limit */
495// range->r_time_flags; /* How to decode max/min retry life */
496// range->min_retry; /* Minimal number of retries */
497// range->max_retry; /* Maximal number of retries */
498// range->min_r_time; /* Minimal retry lifetime */
499// range->max_r_time; /* Maximal retry lifetime */
500
501
502 for (i = 0, val = 0; i < 14; i++) {
503
504 // Include only legal frequencies for some countries
505#ifdef ENABLE_DOT11D
506 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
507#else
508 if ((priv->ieee80211->channel_map)[i+1]) {
509#endif
510 range->freq[val].i = i + 1;
511 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
512 range->freq[val].e = 1;
513 val++;
514 } else {
515 // FIXME: do we need to set anything for channels
516 // we don't use ?
517 }
518
519 if (val == IW_MAX_FREQUENCIES)
520 break;
521 }
522 range->num_frequency = val;
523 range->num_channels = val;
524#if WIRELESS_EXT > 17
525 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
526 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
527#endif
528 tmp->scan_capa = 0x01;
529 return 0;
530}
531
532
533static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
534 union iwreq_data *wrqu, char *b)
535{
536 struct r8192_priv *priv = ieee80211_priv(dev);
537 struct ieee80211_device* ieee = priv->ieee80211;
538 RT_RF_POWER_STATE rtState;
539 int ret;
david woo65a43782009-12-22 09:40:36 -0800540
541 if(priv->bHwRadioOff == true)
542 return 0;
543
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700544 rtState = priv->ieee80211->eRFPowerState;
david woo65a43782009-12-22 09:40:36 -0800545
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700546 if(!priv->up) return -ENETDOWN;
547 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
548 return -EAGAIN;
549
550 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
551 {
552 struct iw_scan_req* req = (struct iw_scan_req*)b;
553 if (req->essid_len)
554 {
555 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
556 ieee->current_network.ssid_len = req->essid_len;
557 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
558 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
559 }
560 }
561
562 down(&priv->wx_sem);
563#ifdef ENABLE_IPS
564 priv->ieee80211->actscanning = true;
565 if(priv->ieee80211->state != IEEE80211_LINKED){
566 if(priv->ieee80211->PowerSaveControl.bInactivePs){
567 if(rtState == eRfOff){
568 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
569 {
570 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
571 up(&priv->wx_sem);
572 return -1;
573 }
574 else{
david woo65a43782009-12-22 09:40:36 -0800575 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
576 down(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700577 IPSLeave(dev);
david woo65a43782009-12-22 09:40:36 -0800578 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700579 }
580 }
581 }
582 priv->ieee80211->scanning = 0;
583 ieee80211_softmac_scan_syncro(priv->ieee80211);
584 ret = 0;
585 }
586 else
587#else
588
589 if(priv->ieee80211->state != IEEE80211_LINKED){
590 priv->ieee80211->scanning = 0;
591 ieee80211_softmac_scan_syncro(priv->ieee80211);
592 ret = 0;
593 }
594 else
595#endif
596 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
597
598 up(&priv->wx_sem);
599 return ret;
600}
601
602
603static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
604 union iwreq_data *wrqu, char *b)
605{
606
607 int ret;
608 struct r8192_priv *priv = ieee80211_priv(dev);
609
david woo65a43782009-12-22 09:40:36 -0800610 if(priv->bHwRadioOff == true)
611 return 0;
612
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700613 if(!priv->up) return -ENETDOWN;
614
615 down(&priv->wx_sem);
616
617 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
618
619 up(&priv->wx_sem);
620
621 return ret;
622}
623
624static int r8192_wx_set_essid(struct net_device *dev,
625 struct iw_request_info *a,
626 union iwreq_data *wrqu, char *b)
627{
628 struct r8192_priv *priv = ieee80211_priv(dev);
629 RT_RF_POWER_STATE rtState;
630 int ret;
631
david woo65a43782009-12-22 09:40:36 -0800632 if(priv->bHwRadioOff == true)
633 return 0;
634
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700635 rtState = priv->ieee80211->eRFPowerState;
636 down(&priv->wx_sem);
david woo65a43782009-12-22 09:40:36 -0800637
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700638#ifdef ENABLE_IPS
david woo65a43782009-12-22 09:40:36 -0800639 down(&priv->ieee80211->ips_sem);
640 IPSLeave(dev);
641 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700642#endif
643 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
644
645 up(&priv->wx_sem);
646
647 return ret;
648}
649
650
651
652
653static int r8192_wx_get_essid(struct net_device *dev,
654 struct iw_request_info *a,
655 union iwreq_data *wrqu, char *b)
656{
657 int ret;
658 struct r8192_priv *priv = ieee80211_priv(dev);
659
660 down(&priv->wx_sem);
661
662 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
663
664 up(&priv->wx_sem);
665
666 return ret;
667}
668
669
670static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
671 union iwreq_data *wrqu, char *b)
672{
673 int ret;
674 struct r8192_priv *priv = ieee80211_priv(dev);
675
david woo65a43782009-12-22 09:40:36 -0800676 if(priv->bHwRadioOff == true)
677 return 0;
678
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700679 down(&priv->wx_sem);
680
681 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
682
683 up(&priv->wx_sem);
684 return ret;
685}
686
687static int r8192_wx_get_name(struct net_device *dev,
688 struct iw_request_info *info,
689 union iwreq_data *wrqu, char *extra)
690{
691 struct r8192_priv *priv = ieee80211_priv(dev);
692 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
693}
694
695
696static int r8192_wx_set_frag(struct net_device *dev,
697 struct iw_request_info *info,
698 union iwreq_data *wrqu, char *extra)
699{
700 struct r8192_priv *priv = ieee80211_priv(dev);
701
david woo65a43782009-12-22 09:40:36 -0800702 if(priv->bHwRadioOff == true)
703 return 0;
704
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700705 if (wrqu->frag.disabled)
706 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
707 else {
708 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
709 wrqu->frag.value > MAX_FRAG_THRESHOLD)
710 return -EINVAL;
711
712 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
713 }
714
715 return 0;
716}
717
718
719static int r8192_wx_get_frag(struct net_device *dev,
720 struct iw_request_info *info,
721 union iwreq_data *wrqu, char *extra)
722{
723 struct r8192_priv *priv = ieee80211_priv(dev);
724
725 wrqu->frag.value = priv->ieee80211->fts;
726 wrqu->frag.fixed = 0; /* no auto select */
727 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
728
729 return 0;
730}
731
732
733static int r8192_wx_set_wap(struct net_device *dev,
734 struct iw_request_info *info,
735 union iwreq_data *awrq,
736 char *extra)
737{
738
739 int ret;
740 struct r8192_priv *priv = ieee80211_priv(dev);
741// struct sockaddr *temp = (struct sockaddr *)awrq;
742
david woo65a43782009-12-22 09:40:36 -0800743 if(priv->bHwRadioOff == true)
744 return 0;
745
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700746 down(&priv->wx_sem);
747
david woo65a43782009-12-22 09:40:36 -0800748#ifdef ENABLE_IPS
749 down(&priv->ieee80211->ips_sem);
750 IPSLeave(dev);
751 up(&priv->ieee80211->ips_sem);
752#endif
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700753 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
754
755 up(&priv->wx_sem);
756
757 return ret;
758
759}
760
761
762static int r8192_wx_get_wap(struct net_device *dev,
763 struct iw_request_info *info,
764 union iwreq_data *wrqu, char *extra)
765{
766 struct r8192_priv *priv = ieee80211_priv(dev);
767
768 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
769}
770
771
772static int r8192_wx_get_enc(struct net_device *dev,
773 struct iw_request_info *info,
774 union iwreq_data *wrqu, char *key)
775{
776 struct r8192_priv *priv = ieee80211_priv(dev);
777
778 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
779}
780
781static int r8192_wx_set_enc(struct net_device *dev,
782 struct iw_request_info *info,
783 union iwreq_data *wrqu, char *key)
784{
785 struct r8192_priv *priv = ieee80211_priv(dev);
786 int ret;
787
788 struct ieee80211_device *ieee = priv->ieee80211;
789 //u32 TargetContent;
790 u32 hwkey[4]={0,0,0,0};
791 u8 mask=0xff;
792 u32 key_idx=0;
david woo65a43782009-12-22 09:40:36 -0800793 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700794 {0x00,0x00,0x00,0x00,0x00,0x01},
795 {0x00,0x00,0x00,0x00,0x00,0x02},
796 {0x00,0x00,0x00,0x00,0x00,0x03} };
797 int i;
798
david woo65a43782009-12-22 09:40:36 -0800799 if(priv->bHwRadioOff == true)
800 return 0;
801
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700802 if(!priv->up) return -ENETDOWN;
803
david woo65a43782009-12-22 09:40:36 -0800804 priv->ieee80211->wx_set_enc = 1;
805#ifdef ENABLE_IPS
806 down(&priv->ieee80211->ips_sem);
807 IPSLeave(dev);
808 up(&priv->ieee80211->ips_sem);
809#endif
810
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700811 down(&priv->wx_sem);
812
813 RT_TRACE(COMP_SEC, "Setting SW wep key");
814 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
815
816 up(&priv->wx_sem);
817
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700818 //sometimes, the length is zero while we do not type key value
819 if(wrqu->encoding.length!=0){
820
821 for(i=0 ; i<4 ; i++){
822 hwkey[i] |= key[4*i+0]&mask;
823 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
824 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
825 hwkey[i] |= (key[4*i+1]&mask)<<8;
826 hwkey[i] |= (key[4*i+2]&mask)<<16;
827 hwkey[i] |= (key[4*i+3]&mask)<<24;
828 }
829
830 #define CONF_WEP40 0x4
831 #define CONF_WEP104 0x14
832
833 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
834 case 0: key_idx = ieee->tx_keyidx; break;
835 case 1: key_idx = 0; break;
836 case 2: key_idx = 1; break;
837 case 3: key_idx = 2; break;
838 case 4: key_idx = 3; break;
839 default: break;
840 }
841
842 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
843 if(wrqu->encoding.length==0x5){
844 ieee->pairwise_key_type = KEY_TYPE_WEP40;
845 EnableHWSecurityConfig8192(dev);
846 setKey( dev,
847 key_idx, //EntryNo
848 key_idx, //KeyIndex
849 KEY_TYPE_WEP40, //KeyType
850 zero_addr[key_idx],
851 0, //DefaultKey
852 hwkey); //KeyContent
853
854#if 0
855 if(key_idx == 0){
856
857 //write_nic_byte(dev, SECR, 7);
858 setKey( dev,
859 4, //EntryNo
860 key_idx, //KeyIndex
861 KEY_TYPE_WEP40, //KeyType
862 broadcast_addr, //addr
863 0, //DefaultKey
864 hwkey); //KeyContent
865 }
866#endif
867 }
868
869 else if(wrqu->encoding.length==0xd){
870 ieee->pairwise_key_type = KEY_TYPE_WEP104;
871 EnableHWSecurityConfig8192(dev);
872 setKey( dev,
873 key_idx, //EntryNo
874 key_idx, //KeyIndex
875 KEY_TYPE_WEP104, //KeyType
876 zero_addr[key_idx],
877 0, //DefaultKey
878 hwkey); //KeyContent
879#if 0
880 if(key_idx == 0){
881
882 //write_nic_byte(dev, SECR, 7);
883 setKey( dev,
884 4, //EntryNo
885 key_idx, //KeyIndex
886 KEY_TYPE_WEP104, //KeyType
887 broadcast_addr, //addr
888 0, //DefaultKey
889 hwkey); //KeyContent
890 }
891#endif
892 }
893 else printk("wrong type in WEP, not WEP40 and WEP104\n");
894
895
896 }
897
898#if 0
899 //consider the setting different key index situation
900 //wrqu->encoding.flags = 801 means that we set key with index "1"
901 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
902 printk("===>1\n");
903 //write_nic_byte(dev, SECR, 7);
904 EnableHWSecurityConfig8192(dev);
905 //copy wpa config from default key(key0~key3) to broadcast key(key5)
906 //
907 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
908 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
909 write_cam(dev, (4*6)+1, 0xffffffff);
910 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
911 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
912 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
913 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
914 }
915#endif
916
david woo65a43782009-12-22 09:40:36 -0800917 priv->ieee80211->wx_set_enc = 0;
918
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700919 return ret;
920}
921
922
923static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
924 iwreq_data *wrqu, char *p){
925
926 struct r8192_priv *priv = ieee80211_priv(dev);
927 int *parms=(int*)p;
928 int mode=parms[0];
929
930 priv->ieee80211->active_scan = mode;
931
932 return 1;
933}
934
935
936
937static int r8192_wx_set_retry(struct net_device *dev,
938 struct iw_request_info *info,
939 union iwreq_data *wrqu, char *extra)
940{
941 struct r8192_priv *priv = ieee80211_priv(dev);
942 int err = 0;
943
david woo65a43782009-12-22 09:40:36 -0800944 if(priv->bHwRadioOff == true)
945 return 0;
946
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700947 down(&priv->wx_sem);
948
949 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
950 wrqu->retry.disabled){
951 err = -EINVAL;
952 goto exit;
953 }
954 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
955 err = -EINVAL;
956 goto exit;
957 }
958
959 if(wrqu->retry.value > R8180_MAX_RETRY){
960 err= -EINVAL;
961 goto exit;
962 }
963 if (wrqu->retry.flags & IW_RETRY_MAX) {
964 priv->retry_rts = wrqu->retry.value;
965 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
966
967 }else {
968 priv->retry_data = wrqu->retry.value;
969 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
970 }
971
972 /* FIXME !
973 * We might try to write directly the TX config register
974 * or to restart just the (R)TX process.
975 * I'm unsure if whole reset is really needed
976 */
977
978 rtl8192_commit(dev);
979 /*
980 if(priv->up){
981 rtl8180_rtx_disable(dev);
982 rtl8180_rx_enable(dev);
983 rtl8180_tx_enable(dev);
984
985 }
986 */
987exit:
988 up(&priv->wx_sem);
989
990 return err;
991}
992
993static int r8192_wx_get_retry(struct net_device *dev,
994 struct iw_request_info *info,
995 union iwreq_data *wrqu, char *extra)
996{
997 struct r8192_priv *priv = ieee80211_priv(dev);
998
999
1000 wrqu->retry.disabled = 0; /* can't be disabled */
1001
1002 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
1003 IW_RETRY_LIFETIME)
1004 return -EINVAL;
1005
1006 if (wrqu->retry.flags & IW_RETRY_MAX) {
1007 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
1008 wrqu->retry.value = priv->retry_rts;
1009 } else {
1010 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
1011 wrqu->retry.value = priv->retry_data;
1012 }
1013 //DMESG("returning %d",wrqu->retry.value);
1014
1015
1016 return 0;
1017}
1018
1019static int r8192_wx_get_sens(struct net_device *dev,
1020 struct iw_request_info *info,
1021 union iwreq_data *wrqu, char *extra)
1022{
1023 struct r8192_priv *priv = ieee80211_priv(dev);
1024 if(priv->rf_set_sens == NULL)
1025 return -1; /* we have not this support for this radio */
1026 wrqu->sens.value = priv->sens;
1027 return 0;
1028}
1029
1030
1031static int r8192_wx_set_sens(struct net_device *dev,
1032 struct iw_request_info *info,
1033 union iwreq_data *wrqu, char *extra)
1034{
1035
1036 struct r8192_priv *priv = ieee80211_priv(dev);
1037
1038 short err = 0;
david woo65a43782009-12-22 09:40:36 -08001039
1040 if(priv->bHwRadioOff == true)
1041 return 0;
1042
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001043 down(&priv->wx_sem);
1044 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
1045 if(priv->rf_set_sens == NULL) {
1046 err= -1; /* we have not this support for this radio */
1047 goto exit;
1048 }
1049 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
1050 priv->sens = wrqu->sens.value;
1051 else
1052 err= -EINVAL;
1053
1054exit:
1055 up(&priv->wx_sem);
1056
1057 return err;
1058}
1059
1060#if (WIRELESS_EXT >= 18)
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001061static int r8192_wx_set_enc_ext(struct net_device *dev,
1062 struct iw_request_info *info,
1063 union iwreq_data *wrqu, char *extra)
1064{
1065 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001066 struct r8192_priv *priv = ieee80211_priv(dev);
1067 struct ieee80211_device* ieee = priv->ieee80211;
1068
david woo65a43782009-12-22 09:40:36 -08001069 if(priv->bHwRadioOff == true)
1070 return 0;
1071
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001072 down(&priv->wx_sem);
david woo65a43782009-12-22 09:40:36 -08001073
1074 priv->ieee80211->wx_set_enc = 1;
1075
1076#ifdef ENABLE_IPS
1077 down(&priv->ieee80211->ips_sem);
1078 IPSLeave(dev);
1079 up(&priv->ieee80211->ips_sem);
1080#endif
1081
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001082 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1083
1084 {
1085 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1086 u8 zero[6] = {0};
1087 u32 key[4] = {0};
1088 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1089 struct iw_point *encoding = &wrqu->encoding;
1090#if 0
1091 static u8 CAM_CONST_ADDR[4][6] = {
1092 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1093 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1094 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1095 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1096#endif
1097 u8 idx = 0, alg = 0, group = 0;
1098 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1099 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1100 {
1101 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1102 CamResetAllEntry(dev);
1103 goto end_hw_sec;
1104 }
1105 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;
1106 idx = encoding->flags & IW_ENCODE_INDEX;
1107 if (idx)
1108 idx --;
1109 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1110
1111 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1112 {
1113 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1114 alg = KEY_TYPE_WEP104;
1115 ieee->pairwise_key_type = alg;
1116 EnableHWSecurityConfig8192(dev);
1117 }
1118 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1119
1120 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1121 {
1122 if (ext->key_len == 13)
1123 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1124 setKey( dev,
1125 idx,//EntryNo
1126 idx, //KeyIndex
1127 alg, //KeyType
1128 zero, //MacAddr
1129 0, //DefaultKey
1130 key); //KeyContent
1131 }
1132 else if (group)
1133 {
1134 ieee->group_key_type = alg;
1135 setKey( dev,
1136 idx,//EntryNo
1137 idx, //KeyIndex
1138 alg, //KeyType
1139 broadcast_addr, //MacAddr
1140 0, //DefaultKey
1141 key); //KeyContent
1142 }
1143 else //pairwise key
1144 {
1145 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
1146 write_nic_byte(dev, 0x173, 1); //fix aes bug
1147 }
1148 setKey( dev,
1149 4,//EntryNo
1150 idx, //KeyIndex
1151 alg, //KeyType
1152 (u8*)ieee->ap_mac_addr, //MacAddr
1153 0, //DefaultKey
1154 key); //KeyContent
1155 }
1156
1157
1158 }
1159
1160end_hw_sec:
david woo65a43782009-12-22 09:40:36 -08001161 priv->ieee80211->wx_set_enc = 0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001162 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001163 return ret;
1164
1165}
1166static int r8192_wx_set_auth(struct net_device *dev,
1167 struct iw_request_info *info,
1168 union iwreq_data *data, char *extra)
1169{
1170 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001171 //printk("====>%s()\n", __FUNCTION__);
1172 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -08001173
1174 if(priv->bHwRadioOff == true)
1175 return 0;
1176
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001177 down(&priv->wx_sem);
1178 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1179 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001180 return ret;
1181}
1182
1183static int r8192_wx_set_mlme(struct net_device *dev,
1184 struct iw_request_info *info,
1185 union iwreq_data *wrqu, char *extra)
1186{
1187 //printk("====>%s()\n", __FUNCTION__);
1188
1189 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001190 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -08001191
1192 if(priv->bHwRadioOff == true)
1193 return 0;
1194
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001195 down(&priv->wx_sem);
1196 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1197 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001198 return ret;
1199}
1200#endif
1201static int r8192_wx_set_gen_ie(struct net_device *dev,
1202 struct iw_request_info *info,
1203 union iwreq_data *data, char *extra)
1204{
1205 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1206 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001207 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -08001208
1209 if(priv->bHwRadioOff == true)
1210 return 0;
1211
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001212 down(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001213 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001214 up(&priv->wx_sem);
1215 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001216 return ret;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001217}
1218
1219static int dummy(struct net_device *dev, struct iw_request_info *a,
1220 union iwreq_data *wrqu,char *b)
1221{
1222 return -1;
1223}
1224
david woo65a43782009-12-22 09:40:36 -08001225// check ac/dc status with the help of user space application */
1226static int r8192_wx_adapter_power_status(struct net_device *dev,
1227 struct iw_request_info *info,
1228 union iwreq_data *wrqu, char *extra)
1229{
1230 struct r8192_priv *priv = ieee80211_priv(dev);
1231#ifdef ENABLE_LPS
1232 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
1233 struct ieee80211_device* ieee = priv->ieee80211;
1234#endif
1235 down(&priv->wx_sem);
1236
1237#ifdef ENABLE_LPS
1238 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1239 // ieee->ps shall not be set under DC mode, otherwise it conflict
1240 // with Leisure power save mode setting.
1241 //
1242 if(*extra || priv->force_lps) {
1243 priv->ps_force = false;
1244 pPSC->bLeisurePs = true;
1245 } else {
1246 //LZM for PS-Poll AID issue. 090429
1247 if(priv->ieee80211->state == IEEE80211_LINKED)
1248 LeisurePSLeave(dev);
1249
1250 priv->ps_force = true;
1251 pPSC->bLeisurePs = false;
1252 ieee->ps = *extra;
1253 }
1254
1255#endif
1256 up(&priv->wx_sem);
1257 return 0;
1258
1259}
1260
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001261
1262static iw_handler r8192_wx_handlers[] =
1263{
1264 NULL, /* SIOCSIWCOMMIT */
1265 r8192_wx_get_name, /* SIOCGIWNAME */
1266 dummy, /* SIOCSIWNWID */
1267 dummy, /* SIOCGIWNWID */
1268 r8192_wx_set_freq, /* SIOCSIWFREQ */
1269 r8192_wx_get_freq, /* SIOCGIWFREQ */
1270 r8192_wx_set_mode, /* SIOCSIWMODE */
1271 r8192_wx_get_mode, /* SIOCGIWMODE */
1272 r8192_wx_set_sens, /* SIOCSIWSENS */
1273 r8192_wx_get_sens, /* SIOCGIWSENS */
1274 NULL, /* SIOCSIWRANGE */
1275 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1276 NULL, /* SIOCSIWPRIV */
1277 NULL, /* SIOCGIWPRIV */
1278 NULL, /* SIOCSIWSTATS */
1279 NULL, /* SIOCGIWSTATS */
1280 dummy, /* SIOCSIWSPY */
1281 dummy, /* SIOCGIWSPY */
1282 NULL, /* SIOCGIWTHRSPY */
1283 NULL, /* SIOCWIWTHRSPY */
1284 r8192_wx_set_wap, /* SIOCSIWAP */
1285 r8192_wx_get_wap, /* SIOCGIWAP */
1286#if (WIRELESS_EXT >= 18)
1287 r8192_wx_set_mlme, /* MLME-- */
1288#else
1289 NULL,
1290#endif
1291 dummy, /* SIOCGIWAPLIST -- depricated */
1292 r8192_wx_set_scan, /* SIOCSIWSCAN */
1293 r8192_wx_get_scan, /* SIOCGIWSCAN */
1294 r8192_wx_set_essid, /* SIOCSIWESSID */
1295 r8192_wx_get_essid, /* SIOCGIWESSID */
1296 dummy, /* SIOCSIWNICKN */
1297 dummy, /* SIOCGIWNICKN */
1298 NULL, /* -- hole -- */
1299 NULL, /* -- hole -- */
1300 r8192_wx_set_rate, /* SIOCSIWRATE */
1301 r8192_wx_get_rate, /* SIOCGIWRATE */
1302 r8192_wx_set_rts, /* SIOCSIWRTS */
1303 r8192_wx_get_rts, /* SIOCGIWRTS */
1304 r8192_wx_set_frag, /* SIOCSIWFRAG */
1305 r8192_wx_get_frag, /* SIOCGIWFRAG */
1306 dummy, /* SIOCSIWTXPOW */
1307 dummy, /* SIOCGIWTXPOW */
1308 r8192_wx_set_retry, /* SIOCSIWRETRY */
1309 r8192_wx_get_retry, /* SIOCGIWRETRY */
1310 r8192_wx_set_enc, /* SIOCSIWENCODE */
1311 r8192_wx_get_enc, /* SIOCGIWENCODE */
1312 r8192_wx_set_power, /* SIOCSIWPOWER */
1313 r8192_wx_get_power, /* SIOCGIWPOWER */
1314 NULL, /*---hole---*/
1315 NULL, /*---hole---*/
1316 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1317 NULL, /* SIOCSIWGENIE */
1318#if (WIRELESS_EXT >= 18)
1319 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1320 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1321 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1322#else
1323 NULL,
1324 NULL,
1325 NULL,
1326#endif
1327 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1328 NULL, /* SIOCSIWPMKSA */
1329 NULL, /*---hole---*/
1330
1331};
1332
1333
1334static const struct iw_priv_args r8192_private_args[] = {
1335
1336 {
1337 SIOCIWFIRSTPRIV + 0x0,
1338 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1339 },
1340
1341 {
1342 SIOCIWFIRSTPRIV + 0x1,
1343 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1344
1345 },
1346 {
1347 SIOCIWFIRSTPRIV + 0x2,
1348 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1349 }
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001350 ,
1351 {
1352 SIOCIWFIRSTPRIV + 0x3,
1353 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1354
1355 }
david woo65a43782009-12-22 09:40:36 -08001356 ,
1357 {
1358 SIOCIWFIRSTPRIV + 0x4,
1359 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1360 "set_power"
1361 }
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001362
1363};
1364
1365
1366static iw_handler r8192_private_handler[] = {
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001367 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001368 r8192_wx_set_scan_type,
1369 r8192_wx_set_rawtx,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001370 r8192_wx_force_reset,
david woo65a43782009-12-22 09:40:36 -08001371 r8192_wx_adapter_power_status,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001372};
1373
1374//#if WIRELESS_EXT >= 17
1375struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1376{
1377 struct r8192_priv *priv = ieee80211_priv(dev);
1378 struct ieee80211_device* ieee = priv->ieee80211;
1379 struct iw_statistics* wstats = &priv->wstats;
1380 int tmp_level = 0;
1381 int tmp_qual = 0;
1382 int tmp_noise = 0;
1383 if(ieee->state < IEEE80211_LINKED)
1384 {
1385 wstats->qual.qual = 0;
1386 wstats->qual.level = 0;
1387 wstats->qual.noise = 0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001388 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001389 return wstats;
1390 }
1391
1392 tmp_level = (&ieee->current_network)->stats.rssi;
1393 tmp_qual = (&ieee->current_network)->stats.signal;
1394 tmp_noise = (&ieee->current_network)->stats.noise;
1395 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1396
1397 wstats->qual.level = tmp_level;
1398 wstats->qual.qual = tmp_qual;
1399 wstats->qual.noise = tmp_noise;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001400 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001401 return wstats;
1402}
1403//#endif
1404
1405
1406struct iw_handler_def r8192_wx_handlers_def={
1407 .standard = r8192_wx_handlers,
1408 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1409 .private = r8192_private_handler,
1410 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1411 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1412#if WIRELESS_EXT >= 17
1413 .get_wireless_stats = r8192_get_wireless_stats,
1414#endif
1415 .private_args = (struct iw_priv_args *)r8192_private_args,
1416};