blob: adad91b0b6b105f3b81a1823c9f35959b3cbe65e [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
Mike McCormackab2161a2010-07-26 22:57:24 +090029static const 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
Mike McCormackf500e252010-08-10 23:44:45 +090073 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -080074 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
Mike McCormackf500e252010-08-10 23:44:45 +090093 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -080094 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
Mike McCormackf500e252010-08-10 23:44:45 +0900120 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800121 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
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700140static int r8192_wx_set_rawtx(struct net_device *dev,
141 struct iw_request_info *info,
142 union iwreq_data *wrqu, char *extra)
143{
144 struct r8192_priv *priv = ieee80211_priv(dev);
145 int ret;
146
Mike McCormackf500e252010-08-10 23:44:45 +0900147 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800148 return 0;
149
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700150 down(&priv->wx_sem);
151
152 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
153
154 up(&priv->wx_sem);
155
156 return ret;
157
158}
159
160static int r8192_wx_force_reset(struct net_device *dev,
161 struct iw_request_info *info,
162 union iwreq_data *wrqu, char *extra)
163{
164 struct r8192_priv *priv = ieee80211_priv(dev);
165
166 down(&priv->wx_sem);
167
168 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
169 priv->force_reset = *extra;
170 up(&priv->wx_sem);
171 return 0;
172
173}
174
175
176static int r8192_wx_set_crcmon(struct net_device *dev,
177 struct iw_request_info *info,
178 union iwreq_data *wrqu, char *extra)
179{
180 struct r8192_priv *priv = ieee80211_priv(dev);
181 int *parms = (int *)extra;
182 int enable = (parms[0] > 0);
183 short prev = priv->crcmon;
184
Mike McCormackf500e252010-08-10 23:44:45 +0900185 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800186 return 0;
187
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700188 down(&priv->wx_sem);
189
190 if(enable)
191 priv->crcmon=1;
192 else
193 priv->crcmon=0;
194
195 DMESG("bad CRC in monitor mode are %s",
196 priv->crcmon ? "accepted" : "rejected");
197
198 if(prev != priv->crcmon && priv->up){
199 //rtl8180_down(dev);
200 //rtl8180_up(dev);
201 }
202
203 up(&priv->wx_sem);
204
205 return 0;
206}
207
208static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
209 union iwreq_data *wrqu, char *b)
210{
211 struct r8192_priv *priv = ieee80211_priv(dev);
212 RT_RF_POWER_STATE rtState;
213 int ret;
214
Mike McCormackf500e252010-08-10 23:44:45 +0900215 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800216 return 0;
217
Mike McCormack45598542011-03-03 22:41:35 +0900218 rtState = priv->eRFPowerState;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700219 down(&priv->wx_sem);
220#ifdef ENABLE_IPS
221 if(wrqu->mode == IW_MODE_ADHOC){
222
Mike McCormack31d664e2011-03-03 22:44:47 +0900223 if (priv->PowerSaveControl.bInactivePs) {
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700224 if(rtState == eRfOff){
Mike McCormack181d1df2011-03-03 22:41:53 +0900225 if(priv->RfOffReason > RF_CHANGE_BY_IPS)
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700226 {
227 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
228 up(&priv->wx_sem);
229 return -1;
230 }
231 else{
david woo65a43782009-12-22 09:40:36 -0800232 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
233 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900234 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800235 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700236 }
237 }
238 }
239 }
240#endif
241 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
242
243 //rtl8187_set_rxconf(dev);
244
245 up(&priv->wx_sem);
246 return ret;
247}
248
249struct iw_range_with_scan_capa
250{
251 /* Informative stuff (to choose between different interface) */
252 __u32 throughput; /* To give an idea... */
253 /* In theory this value should be the maximum benchmarked
254 * TCP/IP throughput, because with most of these devices the
255 * bit rate is meaningless (overhead an co) to estimate how
256 * fast the connection will go and pick the fastest one.
257 * I suggest people to play with Netperf or any benchmark...
258 */
259
260 /* NWID (or domain id) */
261 __u32 min_nwid; /* Minimal NWID we are able to set */
262 __u32 max_nwid; /* Maximal NWID we are able to set */
263
264 /* Old Frequency (backward compat - moved lower ) */
265 __u16 old_num_channels;
266 __u8 old_num_frequency;
267
268 /* Scan capabilities */
269 __u8 scan_capa;
270};
271static int rtl8180_wx_get_range(struct net_device *dev,
272 struct iw_request_info *info,
273 union iwreq_data *wrqu, char *extra)
274{
275 struct iw_range *range = (struct iw_range *)extra;
276 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
277 struct r8192_priv *priv = ieee80211_priv(dev);
278 u16 val;
279 int i;
280
281 wrqu->data.length = sizeof(*range);
282 memset(range, 0, sizeof(*range));
283
284 /* Let's try to keep this struct in the same order as in
285 * linux/include/wireless.h
286 */
287
288 /* TODO: See what values we can set, and remove the ones we can't
289 * set, or fill them with some default data.
290 */
291
292 /* ~5 Mb/s real (802.11b) */
david woo65a43782009-12-22 09:40:36 -0800293 range->throughput = 130 * 1000 * 1000;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700294
295 // TODO: Not used in 802.11b?
296// range->min_nwid; /* Minimal NWID we are able to set */
297 // TODO: Not used in 802.11b?
298// range->max_nwid; /* Maximal NWID we are able to set */
299
300 /* Old Frequency (backward compat - moved lower ) */
301// range->old_num_channels;
302// range->old_num_frequency;
303// range->old_freq[6]; /* Filler to keep "version" at the same offset */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700304
305 range->max_qual.qual = 100;
306 /* TODO: Find real max RSSI and stick here */
307 range->max_qual.level = 0;
308 range->max_qual.noise = -98;
309 range->max_qual.updated = 7; /* Updated all three */
310
311 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
André Goddard Rosabbc9a992009-11-14 13:09:06 -0200312 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700313 range->avg_qual.level = 20 + -98;
314 range->avg_qual.noise = 0;
315 range->avg_qual.updated = 7; /* Updated all three */
316
317 range->num_bitrates = RATE_COUNT;
318
319 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
320 range->bitrate[i] = rtl8180_rates[i];
321 }
322
323 range->min_frag = MIN_FRAG_THRESHOLD;
324 range->max_frag = MAX_FRAG_THRESHOLD;
325
326 range->min_pmp=0;
327 range->max_pmp = 5000000;
328 range->min_pmt = 0;
329 range->max_pmt = 65535*1000;
330 range->pmp_flags = IW_POWER_PERIOD;
331 range->pmt_flags = IW_POWER_TIMEOUT;
332 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
333 range->we_version_compiled = WIRELESS_EXT;
david woo65a43782009-12-22 09:40:36 -0800334 range->we_version_source = 18;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700335
336// range->retry_capa; /* What retry options are supported */
337// range->retry_flags; /* How to decode max/min retry limit */
338// range->r_time_flags; /* How to decode max/min retry life */
339// range->min_retry; /* Minimal number of retries */
340// range->max_retry; /* Maximal number of retries */
341// range->min_r_time; /* Minimal retry lifetime */
342// range->max_r_time; /* Maximal retry lifetime */
343
344
345 for (i = 0, val = 0; i < 14; i++) {
346
347 // Include only legal frequencies for some countries
348#ifdef ENABLE_DOT11D
349 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
350#else
351 if ((priv->ieee80211->channel_map)[i+1]) {
352#endif
353 range->freq[val].i = i + 1;
354 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
355 range->freq[val].e = 1;
356 val++;
357 } else {
358 // FIXME: do we need to set anything for channels
359 // we don't use ?
360 }
361
362 if (val == IW_MAX_FREQUENCIES)
363 break;
364 }
365 range->num_frequency = val;
366 range->num_channels = val;
Mike McCormack890a6852011-01-31 22:09:02 +0900367
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700368 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
369 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
Mike McCormack890a6852011-01-31 22:09:02 +0900370
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700371 tmp->scan_capa = 0x01;
372 return 0;
373}
374
375
376static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
377 union iwreq_data *wrqu, char *b)
378{
379 struct r8192_priv *priv = ieee80211_priv(dev);
380 struct ieee80211_device* ieee = priv->ieee80211;
381 RT_RF_POWER_STATE rtState;
382 int ret;
david woo65a43782009-12-22 09:40:36 -0800383
Mike McCormackf500e252010-08-10 23:44:45 +0900384 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800385 return 0;
386
Mike McCormack45598542011-03-03 22:41:35 +0900387 rtState = priv->eRFPowerState;
david woo65a43782009-12-22 09:40:36 -0800388
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700389 if(!priv->up) return -ENETDOWN;
390 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
391 return -EAGAIN;
392
393 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
394 {
395 struct iw_scan_req* req = (struct iw_scan_req*)b;
396 if (req->essid_len)
397 {
398 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
399 ieee->current_network.ssid_len = req->essid_len;
400 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
401 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
402 }
403 }
404
405 down(&priv->wx_sem);
406#ifdef ENABLE_IPS
407 priv->ieee80211->actscanning = true;
408 if(priv->ieee80211->state != IEEE80211_LINKED){
Mike McCormack31d664e2011-03-03 22:44:47 +0900409 if (priv->PowerSaveControl.bInactivePs) {
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700410 if(rtState == eRfOff){
Mike McCormack181d1df2011-03-03 22:41:53 +0900411 if(priv->RfOffReason > RF_CHANGE_BY_IPS)
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700412 {
413 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
414 up(&priv->wx_sem);
415 return -1;
416 }
417 else{
david woo65a43782009-12-22 09:40:36 -0800418 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
419 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900420 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800421 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700422 }
423 }
424 }
425 priv->ieee80211->scanning = 0;
426 ieee80211_softmac_scan_syncro(priv->ieee80211);
427 ret = 0;
428 }
429 else
430#else
431
432 if(priv->ieee80211->state != IEEE80211_LINKED){
433 priv->ieee80211->scanning = 0;
434 ieee80211_softmac_scan_syncro(priv->ieee80211);
435 ret = 0;
436 }
437 else
438#endif
439 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
440
441 up(&priv->wx_sem);
442 return ret;
443}
444
445
446static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
447 union iwreq_data *wrqu, char *b)
448{
449
450 int ret;
451 struct r8192_priv *priv = ieee80211_priv(dev);
452
Mike McCormackf500e252010-08-10 23:44:45 +0900453 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800454 return 0;
455
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700456 if(!priv->up) return -ENETDOWN;
457
458 down(&priv->wx_sem);
459
460 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
461
462 up(&priv->wx_sem);
463
464 return ret;
465}
466
467static int r8192_wx_set_essid(struct net_device *dev,
468 struct iw_request_info *a,
469 union iwreq_data *wrqu, char *b)
470{
471 struct r8192_priv *priv = ieee80211_priv(dev);
472 RT_RF_POWER_STATE rtState;
473 int ret;
474
Mike McCormackf500e252010-08-10 23:44:45 +0900475 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800476 return 0;
477
Mike McCormack45598542011-03-03 22:41:35 +0900478 rtState = priv->eRFPowerState;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700479 down(&priv->wx_sem);
david woo65a43782009-12-22 09:40:36 -0800480
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700481#ifdef ENABLE_IPS
david woo65a43782009-12-22 09:40:36 -0800482 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900483 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800484 up(&priv->ieee80211->ips_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700485#endif
486 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
487
488 up(&priv->wx_sem);
489
490 return ret;
491}
492
493
494
495
496static int r8192_wx_get_essid(struct net_device *dev,
497 struct iw_request_info *a,
498 union iwreq_data *wrqu, char *b)
499{
500 int ret;
501 struct r8192_priv *priv = ieee80211_priv(dev);
502
503 down(&priv->wx_sem);
504
505 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
506
507 up(&priv->wx_sem);
508
509 return ret;
510}
511
512
513static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
514 union iwreq_data *wrqu, char *b)
515{
516 int ret;
517 struct r8192_priv *priv = ieee80211_priv(dev);
518
Mike McCormackf500e252010-08-10 23:44:45 +0900519 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800520 return 0;
521
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700522 down(&priv->wx_sem);
523
524 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
525
526 up(&priv->wx_sem);
527 return ret;
528}
529
530static int r8192_wx_get_name(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
533{
534 struct r8192_priv *priv = ieee80211_priv(dev);
535 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
536}
537
538
539static int r8192_wx_set_frag(struct net_device *dev,
540 struct iw_request_info *info,
541 union iwreq_data *wrqu, char *extra)
542{
543 struct r8192_priv *priv = ieee80211_priv(dev);
544
Mike McCormackf500e252010-08-10 23:44:45 +0900545 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800546 return 0;
547
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700548 if (wrqu->frag.disabled)
549 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
550 else {
551 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
552 wrqu->frag.value > MAX_FRAG_THRESHOLD)
553 return -EINVAL;
554
555 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
556 }
557
558 return 0;
559}
560
561
562static int r8192_wx_get_frag(struct net_device *dev,
563 struct iw_request_info *info,
564 union iwreq_data *wrqu, char *extra)
565{
566 struct r8192_priv *priv = ieee80211_priv(dev);
567
568 wrqu->frag.value = priv->ieee80211->fts;
569 wrqu->frag.fixed = 0; /* no auto select */
570 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
571
572 return 0;
573}
574
575
576static int r8192_wx_set_wap(struct net_device *dev,
577 struct iw_request_info *info,
578 union iwreq_data *awrq,
579 char *extra)
580{
581
582 int ret;
583 struct r8192_priv *priv = ieee80211_priv(dev);
584// struct sockaddr *temp = (struct sockaddr *)awrq;
585
Mike McCormackf500e252010-08-10 23:44:45 +0900586 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800587 return 0;
588
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700589 down(&priv->wx_sem);
590
david woo65a43782009-12-22 09:40:36 -0800591#ifdef ENABLE_IPS
592 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900593 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800594 up(&priv->ieee80211->ips_sem);
595#endif
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700596 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
597
598 up(&priv->wx_sem);
599
600 return ret;
601
602}
603
604
605static int r8192_wx_get_wap(struct net_device *dev,
606 struct iw_request_info *info,
607 union iwreq_data *wrqu, char *extra)
608{
609 struct r8192_priv *priv = ieee80211_priv(dev);
610
611 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
612}
613
614
615static int r8192_wx_get_enc(struct net_device *dev,
616 struct iw_request_info *info,
617 union iwreq_data *wrqu, char *key)
618{
619 struct r8192_priv *priv = ieee80211_priv(dev);
620
621 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
622}
623
624static int r8192_wx_set_enc(struct net_device *dev,
625 struct iw_request_info *info,
626 union iwreq_data *wrqu, char *key)
627{
628 struct r8192_priv *priv = ieee80211_priv(dev);
629 int ret;
630
631 struct ieee80211_device *ieee = priv->ieee80211;
632 //u32 TargetContent;
633 u32 hwkey[4]={0,0,0,0};
634 u8 mask=0xff;
635 u32 key_idx=0;
david woo65a43782009-12-22 09:40:36 -0800636 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700637 {0x00,0x00,0x00,0x00,0x00,0x01},
638 {0x00,0x00,0x00,0x00,0x00,0x02},
639 {0x00,0x00,0x00,0x00,0x00,0x03} };
640 int i;
641
Mike McCormackf500e252010-08-10 23:44:45 +0900642 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800643 return 0;
644
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700645 if(!priv->up) return -ENETDOWN;
646
david woo65a43782009-12-22 09:40:36 -0800647 priv->ieee80211->wx_set_enc = 1;
648#ifdef ENABLE_IPS
649 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900650 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800651 up(&priv->ieee80211->ips_sem);
652#endif
653
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700654 down(&priv->wx_sem);
655
Mike McCormack703fdcc2011-02-21 00:04:54 +0900656 RT_TRACE(COMP_SEC, "Setting SW wep key\n");
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700657 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
658
659 up(&priv->wx_sem);
660
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700661 //sometimes, the length is zero while we do not type key value
662 if(wrqu->encoding.length!=0){
663
664 for(i=0 ; i<4 ; i++){
665 hwkey[i] |= key[4*i+0]&mask;
666 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
667 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
668 hwkey[i] |= (key[4*i+1]&mask)<<8;
669 hwkey[i] |= (key[4*i+2]&mask)<<16;
670 hwkey[i] |= (key[4*i+3]&mask)<<24;
671 }
672
673 #define CONF_WEP40 0x4
674 #define CONF_WEP104 0x14
675
676 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
677 case 0: key_idx = ieee->tx_keyidx; break;
678 case 1: key_idx = 0; break;
679 case 2: key_idx = 1; break;
680 case 3: key_idx = 2; break;
681 case 4: key_idx = 3; break;
682 default: break;
683 }
684
685 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
686 if(wrqu->encoding.length==0x5){
687 ieee->pairwise_key_type = KEY_TYPE_WEP40;
Mike McCormack282fa9f2011-03-09 00:39:23 +0900688 EnableHWSecurityConfig8192(priv);
Mike McCormack043dfdd2011-03-09 00:39:32 +0900689 setKey(priv, key_idx, key_idx, KEY_TYPE_WEP40,
690 zero_addr[key_idx], 0, hwkey);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700691 }
692
693 else if(wrqu->encoding.length==0xd){
694 ieee->pairwise_key_type = KEY_TYPE_WEP104;
Mike McCormack282fa9f2011-03-09 00:39:23 +0900695 EnableHWSecurityConfig8192(priv);
Mike McCormack043dfdd2011-03-09 00:39:32 +0900696 setKey(priv, key_idx, key_idx, KEY_TYPE_WEP104,
697 zero_addr[key_idx], 0, hwkey);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700698 }
699 else printk("wrong type in WEP, not WEP40 and WEP104\n");
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700700 }
701
david woo65a43782009-12-22 09:40:36 -0800702 priv->ieee80211->wx_set_enc = 0;
703
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700704 return ret;
705}
706
707
708static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
709 iwreq_data *wrqu, char *p){
710
711 struct r8192_priv *priv = ieee80211_priv(dev);
712 int *parms=(int*)p;
713 int mode=parms[0];
714
715 priv->ieee80211->active_scan = mode;
716
717 return 1;
718}
719
720
721
722static int r8192_wx_set_retry(struct net_device *dev,
723 struct iw_request_info *info,
724 union iwreq_data *wrqu, char *extra)
725{
726 struct r8192_priv *priv = ieee80211_priv(dev);
727 int err = 0;
728
Mike McCormackf500e252010-08-10 23:44:45 +0900729 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800730 return 0;
731
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700732 down(&priv->wx_sem);
733
734 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
735 wrqu->retry.disabled){
736 err = -EINVAL;
737 goto exit;
738 }
739 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
740 err = -EINVAL;
741 goto exit;
742 }
743
744 if(wrqu->retry.value > R8180_MAX_RETRY){
745 err= -EINVAL;
746 goto exit;
747 }
748 if (wrqu->retry.flags & IW_RETRY_MAX) {
749 priv->retry_rts = wrqu->retry.value;
750 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
751
752 }else {
753 priv->retry_data = wrqu->retry.value;
754 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
755 }
756
757 /* FIXME !
758 * We might try to write directly the TX config register
759 * or to restart just the (R)TX process.
760 * I'm unsure if whole reset is really needed
761 */
762
Mike McCormackaf59c392011-03-03 22:45:42 +0900763 rtl8192_commit(priv);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700764 /*
765 if(priv->up){
766 rtl8180_rtx_disable(dev);
767 rtl8180_rx_enable(dev);
768 rtl8180_tx_enable(dev);
769
770 }
771 */
772exit:
773 up(&priv->wx_sem);
774
775 return err;
776}
777
778static int r8192_wx_get_retry(struct net_device *dev,
779 struct iw_request_info *info,
780 union iwreq_data *wrqu, char *extra)
781{
782 struct r8192_priv *priv = ieee80211_priv(dev);
783
784
785 wrqu->retry.disabled = 0; /* can't be disabled */
786
787 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
788 IW_RETRY_LIFETIME)
789 return -EINVAL;
790
791 if (wrqu->retry.flags & IW_RETRY_MAX) {
792 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
793 wrqu->retry.value = priv->retry_rts;
794 } else {
795 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
796 wrqu->retry.value = priv->retry_data;
797 }
798 //DMESG("returning %d",wrqu->retry.value);
799
800
801 return 0;
802}
803
804static int r8192_wx_get_sens(struct net_device *dev,
805 struct iw_request_info *info,
806 union iwreq_data *wrqu, char *extra)
807{
808 struct r8192_priv *priv = ieee80211_priv(dev);
809 if(priv->rf_set_sens == NULL)
810 return -1; /* we have not this support for this radio */
811 wrqu->sens.value = priv->sens;
812 return 0;
813}
814
815
816static int r8192_wx_set_sens(struct net_device *dev,
817 struct iw_request_info *info,
818 union iwreq_data *wrqu, char *extra)
819{
820
821 struct r8192_priv *priv = ieee80211_priv(dev);
822
823 short err = 0;
david woo65a43782009-12-22 09:40:36 -0800824
Mike McCormackf500e252010-08-10 23:44:45 +0900825 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800826 return 0;
827
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700828 down(&priv->wx_sem);
829 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
830 if(priv->rf_set_sens == NULL) {
831 err= -1; /* we have not this support for this radio */
832 goto exit;
833 }
834 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
835 priv->sens = wrqu->sens.value;
836 else
837 err= -EINVAL;
838
839exit:
840 up(&priv->wx_sem);
841
842 return err;
843}
844
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700845static int r8192_wx_set_enc_ext(struct net_device *dev,
846 struct iw_request_info *info,
847 union iwreq_data *wrqu, char *extra)
848{
849 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700850 struct r8192_priv *priv = ieee80211_priv(dev);
851 struct ieee80211_device* ieee = priv->ieee80211;
852
Mike McCormackf500e252010-08-10 23:44:45 +0900853 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800854 return 0;
855
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700856 down(&priv->wx_sem);
david woo65a43782009-12-22 09:40:36 -0800857
858 priv->ieee80211->wx_set_enc = 1;
859
860#ifdef ENABLE_IPS
861 down(&priv->ieee80211->ips_sem);
Mike McCormack58f6b582011-03-09 00:39:05 +0900862 IPSLeave(priv);
david woo65a43782009-12-22 09:40:36 -0800863 up(&priv->ieee80211->ips_sem);
864#endif
865
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700866 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
867
868 {
869 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
870 u8 zero[6] = {0};
871 u32 key[4] = {0};
872 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
873 struct iw_point *encoding = &wrqu->encoding;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700874 u8 idx = 0, alg = 0, group = 0;
Mike McCormack679b5f62011-02-06 22:53:45 +0900875
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700876 if ((encoding->flags & IW_ENCODE_DISABLED) ||
877 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
878 {
879 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
Mike McCormack480ab9d2011-03-03 22:45:24 +0900880 CamResetAllEntry(priv);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700881 goto end_hw_sec;
882 }
883 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;
884 idx = encoding->flags & IW_ENCODE_INDEX;
885 if (idx)
886 idx --;
887 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
888
889 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
890 {
891 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
892 alg = KEY_TYPE_WEP104;
893 ieee->pairwise_key_type = alg;
Mike McCormack282fa9f2011-03-09 00:39:23 +0900894 EnableHWSecurityConfig8192(priv);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700895 }
896 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
897
898 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
899 {
900 if (ext->key_len == 13)
901 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
Mike McCormack043dfdd2011-03-09 00:39:32 +0900902 setKey(priv, idx, idx, alg, zero, 0, key);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700903 }
904 else if (group)
905 {
906 ieee->group_key_type = alg;
Mike McCormack043dfdd2011-03-09 00:39:32 +0900907 setKey(priv, idx, idx, alg, broadcast_addr, 0, key);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700908 }
909 else //pairwise key
910 {
911 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
Mike McCormack3f9ab1e2011-02-06 22:53:26 +0900912 write_nic_byte(priv, 0x173, 1); //fix aes bug
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700913 }
Mike McCormack043dfdd2011-03-09 00:39:32 +0900914 setKey(priv, 4, idx, alg,
915 (u8*)ieee->ap_mac_addr, 0, key);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700916 }
917
918
919 }
920
921end_hw_sec:
david woo65a43782009-12-22 09:40:36 -0800922 priv->ieee80211->wx_set_enc = 0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700923 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700924 return ret;
925
926}
927static int r8192_wx_set_auth(struct net_device *dev,
928 struct iw_request_info *info,
929 union iwreq_data *data, char *extra)
930{
931 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700932 //printk("====>%s()\n", __FUNCTION__);
933 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -0800934
Mike McCormackf500e252010-08-10 23:44:45 +0900935 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800936 return 0;
937
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700938 down(&priv->wx_sem);
939 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
940 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700941 return ret;
942}
943
944static int r8192_wx_set_mlme(struct net_device *dev,
945 struct iw_request_info *info,
946 union iwreq_data *wrqu, char *extra)
947{
948 //printk("====>%s()\n", __FUNCTION__);
949
950 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700951 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -0800952
Mike McCormackf500e252010-08-10 23:44:45 +0900953 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800954 return 0;
955
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700956 down(&priv->wx_sem);
957 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
958 up(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700959 return ret;
960}
Mike McCormack890a6852011-01-31 22:09:02 +0900961
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700962static int r8192_wx_set_gen_ie(struct net_device *dev,
963 struct iw_request_info *info,
964 union iwreq_data *data, char *extra)
965{
966 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
967 int ret=0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700968 struct r8192_priv *priv = ieee80211_priv(dev);
david woo65a43782009-12-22 09:40:36 -0800969
Mike McCormackf500e252010-08-10 23:44:45 +0900970 if (priv->bHwRadioOff)
david woo65a43782009-12-22 09:40:36 -0800971 return 0;
972
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700973 down(&priv->wx_sem);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700974 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700975 up(&priv->wx_sem);
976 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700977 return ret;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -0700978}
979
980static int dummy(struct net_device *dev, struct iw_request_info *a,
981 union iwreq_data *wrqu,char *b)
982{
983 return -1;
984}
985
david woo65a43782009-12-22 09:40:36 -0800986// check ac/dc status with the help of user space application */
987static int r8192_wx_adapter_power_status(struct net_device *dev,
988 struct iw_request_info *info,
989 union iwreq_data *wrqu, char *extra)
990{
991 struct r8192_priv *priv = ieee80211_priv(dev);
992#ifdef ENABLE_LPS
Mike McCormack31d664e2011-03-03 22:44:47 +0900993 PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl;
david woo65a43782009-12-22 09:40:36 -0800994 struct ieee80211_device* ieee = priv->ieee80211;
995#endif
996 down(&priv->wx_sem);
997
998#ifdef ENABLE_LPS
999 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1000 // ieee->ps shall not be set under DC mode, otherwise it conflict
1001 // with Leisure power save mode setting.
1002 //
1003 if(*extra || priv->force_lps) {
1004 priv->ps_force = false;
1005 pPSC->bLeisurePs = true;
1006 } else {
1007 //LZM for PS-Poll AID issue. 090429
1008 if(priv->ieee80211->state == IEEE80211_LINKED)
Mike McCormackd1c580a2011-03-10 22:33:47 +09001009 LeisurePSLeave(priv->ieee80211);
david woo65a43782009-12-22 09:40:36 -08001010
1011 priv->ps_force = true;
1012 pPSC->bLeisurePs = false;
1013 ieee->ps = *extra;
1014 }
1015
1016#endif
1017 up(&priv->wx_sem);
1018 return 0;
1019
1020}
1021
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001022
1023static iw_handler r8192_wx_handlers[] =
1024{
1025 NULL, /* SIOCSIWCOMMIT */
1026 r8192_wx_get_name, /* SIOCGIWNAME */
1027 dummy, /* SIOCSIWNWID */
1028 dummy, /* SIOCGIWNWID */
1029 r8192_wx_set_freq, /* SIOCSIWFREQ */
1030 r8192_wx_get_freq, /* SIOCGIWFREQ */
1031 r8192_wx_set_mode, /* SIOCSIWMODE */
1032 r8192_wx_get_mode, /* SIOCGIWMODE */
1033 r8192_wx_set_sens, /* SIOCSIWSENS */
1034 r8192_wx_get_sens, /* SIOCGIWSENS */
1035 NULL, /* SIOCSIWRANGE */
1036 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1037 NULL, /* SIOCSIWPRIV */
1038 NULL, /* SIOCGIWPRIV */
1039 NULL, /* SIOCSIWSTATS */
1040 NULL, /* SIOCGIWSTATS */
1041 dummy, /* SIOCSIWSPY */
1042 dummy, /* SIOCGIWSPY */
1043 NULL, /* SIOCGIWTHRSPY */
1044 NULL, /* SIOCWIWTHRSPY */
1045 r8192_wx_set_wap, /* SIOCSIWAP */
1046 r8192_wx_get_wap, /* SIOCGIWAP */
Mike McCormack890a6852011-01-31 22:09:02 +09001047 r8192_wx_set_mlme, /* MLME-- */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001048 dummy, /* SIOCGIWAPLIST -- depricated */
1049 r8192_wx_set_scan, /* SIOCSIWSCAN */
1050 r8192_wx_get_scan, /* SIOCGIWSCAN */
1051 r8192_wx_set_essid, /* SIOCSIWESSID */
1052 r8192_wx_get_essid, /* SIOCGIWESSID */
1053 dummy, /* SIOCSIWNICKN */
1054 dummy, /* SIOCGIWNICKN */
1055 NULL, /* -- hole -- */
1056 NULL, /* -- hole -- */
1057 r8192_wx_set_rate, /* SIOCSIWRATE */
1058 r8192_wx_get_rate, /* SIOCGIWRATE */
1059 r8192_wx_set_rts, /* SIOCSIWRTS */
1060 r8192_wx_get_rts, /* SIOCGIWRTS */
1061 r8192_wx_set_frag, /* SIOCSIWFRAG */
1062 r8192_wx_get_frag, /* SIOCGIWFRAG */
1063 dummy, /* SIOCSIWTXPOW */
1064 dummy, /* SIOCGIWTXPOW */
1065 r8192_wx_set_retry, /* SIOCSIWRETRY */
1066 r8192_wx_get_retry, /* SIOCGIWRETRY */
1067 r8192_wx_set_enc, /* SIOCSIWENCODE */
1068 r8192_wx_get_enc, /* SIOCGIWENCODE */
1069 r8192_wx_set_power, /* SIOCSIWPOWER */
1070 r8192_wx_get_power, /* SIOCGIWPOWER */
1071 NULL, /*---hole---*/
1072 NULL, /*---hole---*/
1073 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1074 NULL, /* SIOCSIWGENIE */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001075 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1076 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1077 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001078 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1079 NULL, /* SIOCSIWPMKSA */
1080 NULL, /*---hole---*/
1081
1082};
1083
1084
1085static const struct iw_priv_args r8192_private_args[] = {
1086
1087 {
1088 SIOCIWFIRSTPRIV + 0x0,
1089 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1090 },
1091
1092 {
1093 SIOCIWFIRSTPRIV + 0x1,
1094 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1095
1096 },
1097 {
1098 SIOCIWFIRSTPRIV + 0x2,
1099 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1100 }
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001101 ,
1102 {
1103 SIOCIWFIRSTPRIV + 0x3,
1104 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1105
1106 }
david woo65a43782009-12-22 09:40:36 -08001107 ,
1108 {
1109 SIOCIWFIRSTPRIV + 0x4,
1110 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1111 "set_power"
1112 }
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001113
1114};
1115
1116
1117static iw_handler r8192_private_handler[] = {
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001118 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001119 r8192_wx_set_scan_type,
1120 r8192_wx_set_rawtx,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001121 r8192_wx_force_reset,
david woo65a43782009-12-22 09:40:36 -08001122 r8192_wx_adapter_power_status,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001123};
1124
Mike McCormack9f17b072011-02-21 00:04:21 +09001125static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001126{
1127 struct r8192_priv *priv = ieee80211_priv(dev);
1128 struct ieee80211_device* ieee = priv->ieee80211;
1129 struct iw_statistics* wstats = &priv->wstats;
1130 int tmp_level = 0;
1131 int tmp_qual = 0;
1132 int tmp_noise = 0;
1133 if(ieee->state < IEEE80211_LINKED)
1134 {
1135 wstats->qual.qual = 0;
1136 wstats->qual.level = 0;
1137 wstats->qual.noise = 0;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001138 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001139 return wstats;
1140 }
1141
1142 tmp_level = (&ieee->current_network)->stats.rssi;
1143 tmp_qual = (&ieee->current_network)->stats.signal;
1144 tmp_noise = (&ieee->current_network)->stats.noise;
1145 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1146
1147 wstats->qual.level = tmp_level;
1148 wstats->qual.qual = tmp_qual;
1149 wstats->qual.noise = tmp_noise;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001150 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001151 return wstats;
1152}
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001153
1154
1155struct iw_handler_def r8192_wx_handlers_def={
1156 .standard = r8192_wx_handlers,
1157 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1158 .private = r8192_private_handler,
1159 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1160 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001161 .get_wireless_stats = r8192_get_wireless_stats,
Greg Kroah-Hartmanecdfa442009-08-04 15:57:55 -07001162 .private_args = (struct iw_priv_args *)r8192_private_args,
1163};