blob: 3e2576347d29ee73df1d22a7d42e0e5cd36b8624 [file] [log] [blame]
Jerry Chuang8fc85982009-11-03 07:17:11 -02001/*
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
Justin P. Mattockffae3052012-04-30 13:45:41 -070016 We want to thank the Authors of those projects and the Ndiswrapper
Jerry Chuang8fc85982009-11-03 07:17:11 -020017 project Authors.
18*/
19
20#include <linux/string.h>
21#include "r8192U.h"
22#include "r8192U_hw.h"
23
Jerry Chuang8fc85982009-11-03 07:17:11 -020024#include "dot11d.h"
Jerry Chuang8fc85982009-11-03 07:17:11 -020025
26#define RATE_COUNT 12
27u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
28 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
29
30
31#ifndef ENETDOWN
32#define ENETDOWN 1
33#endif
34
35static int r8192_wx_get_freq(struct net_device *dev,
36 struct iw_request_info *a,
37 union iwreq_data *wrqu, char *b)
38{
39 struct r8192_priv *priv = ieee80211_priv(dev);
40
41 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
42}
43
44
Jerry Chuang8fc85982009-11-03 07:17:11 -020045static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
46 union iwreq_data *wrqu, char *b)
47{
48 struct r8192_priv *priv=ieee80211_priv(dev);
49
50 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
51}
52
53
54
55static int r8192_wx_get_rate(struct net_device *dev,
56 struct iw_request_info *info,
57 union iwreq_data *wrqu, char *extra)
58{
59 struct r8192_priv *priv = ieee80211_priv(dev);
60 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
61}
62
63
64
65static int r8192_wx_set_rate(struct net_device *dev,
66 struct iw_request_info *info,
67 union iwreq_data *wrqu, char *extra)
68{
69 int ret;
70 struct r8192_priv *priv = ieee80211_priv(dev);
71
72 down(&priv->wx_sem);
73
74 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
75
76 up(&priv->wx_sem);
77
78 return ret;
79}
80
81
82static int r8192_wx_set_rts(struct net_device *dev,
83 struct iw_request_info *info,
84 union iwreq_data *wrqu, char *extra)
85{
86 int ret;
87 struct r8192_priv *priv = ieee80211_priv(dev);
88
89 down(&priv->wx_sem);
90
91 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
92
93 up(&priv->wx_sem);
94
95 return ret;
96}
97
98static int r8192_wx_get_rts(struct net_device *dev,
99 struct iw_request_info *info,
100 union iwreq_data *wrqu, char *extra)
101{
102 struct r8192_priv *priv = ieee80211_priv(dev);
103 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
104}
105
106static int r8192_wx_set_power(struct net_device *dev,
107 struct iw_request_info *info,
108 union iwreq_data *wrqu, char *extra)
109{
110 int ret;
111 struct r8192_priv *priv = ieee80211_priv(dev);
112
113 down(&priv->wx_sem);
114
115 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
116
117 up(&priv->wx_sem);
118
119 return ret;
120}
121
122static int r8192_wx_get_power(struct net_device *dev,
123 struct iw_request_info *info,
124 union iwreq_data *wrqu, char *extra)
125{
126 struct r8192_priv *priv = ieee80211_priv(dev);
127 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
128}
129
130#ifdef JOHN_IOCTL
131u16 read_rtl8225(struct net_device *dev, u8 addr);
132void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
133u32 john_read_rtl8225(struct net_device *dev, u8 adr);
134void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
135
136static int r8192_wx_read_regs(struct net_device *dev,
137 struct iw_request_info *info,
138 union iwreq_data *wrqu, char *extra)
139{
140 struct r8192_priv *priv = ieee80211_priv(dev);
141 u8 addr;
142 u16 data1;
143
144 down(&priv->wx_sem);
145
146
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300147 get_user(addr,(u8 *)wrqu->data.pointer);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200148 data1 = read_rtl8225(dev, addr);
149 wrqu->data.length = data1;
150
151 up(&priv->wx_sem);
152 return 0;
153
154}
155
156static int r8192_wx_write_regs(struct net_device *dev,
157 struct iw_request_info *info,
158 union iwreq_data *wrqu, char *extra)
159{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200160 struct r8192_priv *priv = ieee80211_priv(dev);
161 u8 addr;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200162
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200163 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200164
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300165 get_user(addr, (u8 *)wrqu->data.pointer);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200166 write_rtl8225(dev, addr, wrqu->data.length);
167
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200168 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200169 return 0;
170
171}
172
173void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
174u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
175
176static int r8192_wx_read_bb(struct net_device *dev,
177 struct iw_request_info *info,
178 union iwreq_data *wrqu, char *extra)
179{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200180 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200181 u8 databb;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200182
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200183 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200184
185 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
186 wrqu->data.length = databb;
187
188 up(&priv->wx_sem);
189 return 0;
190}
191
192void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
193static int r8192_wx_write_bb(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200194 struct iw_request_info *info,
195 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200196{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200197 struct r8192_priv *priv = ieee80211_priv(dev);
198 u8 databb;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200199
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200200 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200201
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300202 get_user(databb, (u8 *)wrqu->data.pointer);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200203 rtl8187_write_phy(dev, wrqu->data.length, databb);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200204
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200205 up(&priv->wx_sem);
206 return 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200207
208}
209
210
211static int r8192_wx_write_nicb(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200212 struct iw_request_info *info,
213 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200214{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200215 struct r8192_priv *priv = ieee80211_priv(dev);
216 u32 addr;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200217
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200218 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200219
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300220 get_user(addr, (u32 *)wrqu->data.pointer);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200221 write_nic_byte(dev, addr, wrqu->data.length);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200222
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200223 up(&priv->wx_sem);
224 return 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200225
226}
227static int r8192_wx_read_nicb(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200228 struct iw_request_info *info,
229 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200230{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200231 struct r8192_priv *priv = ieee80211_priv(dev);
232 u32 addr;
233 u16 data1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200234
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200235 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200236
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300237 get_user(addr,(u32 *)wrqu->data.pointer);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300238 read_nic_byte(dev, addr, &data1);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200239 wrqu->data.length = data1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200240
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200241 up(&priv->wx_sem);
242 return 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200243}
244
245static int r8192_wx_get_ap_status(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200246 struct iw_request_info *info,
247 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200248{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200249 struct r8192_priv *priv = ieee80211_priv(dev);
250 struct ieee80211_device *ieee = priv->ieee80211;
251 struct ieee80211_network *target;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200252 int name_len;
253
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200254 down(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200255
256 //count the length of input ssid
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300257 for(name_len=0 ; ((char *)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200258
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700259 //search for the corresponding info which is received
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200260 list_for_each_entry(target, &ieee->network_list, list) {
261 if ( (target->ssid_len == name_len) &&
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300262 (strncmp(target->ssid, (char *)wrqu->data.pointer, name_len)==0)){
Jerry Chuang8fc85982009-11-03 07:17:11 -0200263 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
264 //set flags=1 to indicate this ap is WPA
265 wrqu->data.flags = 1;
266 else wrqu->data.flags = 0;
267
268
269 break;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200270 }
271 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200272
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200273 up(&priv->wx_sem);
274 return 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200275}
276
277
278
279#endif
Jerry Chuang8fc85982009-11-03 07:17:11 -0200280static int r8192_wx_force_reset(struct net_device *dev,
281 struct iw_request_info *info,
282 union iwreq_data *wrqu, char *extra)
283{
284 struct r8192_priv *priv = ieee80211_priv(dev);
285
286 down(&priv->wx_sem);
287
288 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
289 priv->force_reset = *extra;
290 up(&priv->wx_sem);
291 return 0;
292
293}
294
295
296static int r8192_wx_set_rawtx(struct net_device *dev,
297 struct iw_request_info *info,
298 union iwreq_data *wrqu, char *extra)
299{
300 struct r8192_priv *priv = ieee80211_priv(dev);
301 int ret;
302
303 down(&priv->wx_sem);
304
305 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
306
307 up(&priv->wx_sem);
308
309 return ret;
310
311}
312
313static int r8192_wx_set_crcmon(struct net_device *dev,
314 struct iw_request_info *info,
315 union iwreq_data *wrqu, char *extra)
316{
317 struct r8192_priv *priv = ieee80211_priv(dev);
318 int *parms = (int *)extra;
319 int enable = (parms[0] > 0);
320 short prev = priv->crcmon;
321
322 down(&priv->wx_sem);
323
324 if(enable)
325 priv->crcmon=1;
326 else
327 priv->crcmon=0;
328
329 DMESG("bad CRC in monitor mode are %s",
330 priv->crcmon ? "accepted" : "rejected");
331
332 if(prev != priv->crcmon && priv->up){
333 //rtl8180_down(dev);
334 //rtl8180_up(dev);
335 }
336
337 up(&priv->wx_sem);
338
339 return 0;
340}
341
342static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
343 union iwreq_data *wrqu, char *b)
344{
345 struct r8192_priv *priv = ieee80211_priv(dev);
346 int ret;
347 down(&priv->wx_sem);
348
349 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
350
351 rtl8192_set_rxconf(dev);
352
353 up(&priv->wx_sem);
354 return ret;
355}
356
Jennifer Naumann0db7a342012-12-05 21:40:19 +0100357struct iw_range_with_scan_capa {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200358 /* Informative stuff (to choose between different interface) */
359 __u32 throughput; /* To give an idea... */
360 /* In theory this value should be the maximum benchmarked
361 * TCP/IP throughput, because with most of these devices the
362 * bit rate is meaningless (overhead an co) to estimate how
363 * fast the connection will go and pick the fastest one.
364 * I suggest people to play with Netperf or any benchmark...
365 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200366
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200367 /* NWID (or domain id) */
368 __u32 min_nwid; /* Minimal NWID we are able to set */
369 __u32 max_nwid; /* Maximal NWID we are able to set */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200370
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200371 /* Old Frequency (backward compat - moved lower ) */
372 __u16 old_num_channels;
373 __u8 old_num_frequency;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200374
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200375 /* Scan capabilities */
376 __u8 scan_capa;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200377};
378static int rtl8180_wx_get_range(struct net_device *dev,
379 struct iw_request_info *info,
380 union iwreq_data *wrqu, char *extra)
381{
382 struct iw_range *range = (struct iw_range *)extra;
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300383 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200384 struct r8192_priv *priv = ieee80211_priv(dev);
385 u16 val;
386 int i;
387
388 wrqu->data.length = sizeof(*range);
389 memset(range, 0, sizeof(*range));
390
391 /* Let's try to keep this struct in the same order as in
392 * linux/include/wireless.h
393 */
394
395 /* TODO: See what values we can set, and remove the ones we can't
396 * set, or fill them with some default data.
397 */
398
399 /* ~5 Mb/s real (802.11b) */
400 range->throughput = 5 * 1000 * 1000;
401
402 // TODO: Not used in 802.11b?
403// range->min_nwid; /* Minimal NWID we are able to set */
404 // TODO: Not used in 802.11b?
405// range->max_nwid; /* Maximal NWID we are able to set */
406
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200407 /* Old Frequency (backward compat - moved lower ) */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200408// range->old_num_channels;
409// range->old_num_frequency;
410// range->old_freq[6]; /* Filler to keep "version" at the same offset */
411 if(priv->rf_set_sens != NULL)
412 range->sensitivity = priv->max_sens; /* signal level threshold range */
413
414 range->max_qual.qual = 100;
415 /* TODO: Find real max RSSI and stick here */
416 range->max_qual.level = 0;
417 range->max_qual.noise = -98;
418 range->max_qual.updated = 7; /* Updated all three */
419
420 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700421 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200422 range->avg_qual.level = 20 + -98;
423 range->avg_qual.noise = 0;
424 range->avg_qual.updated = 7; /* Updated all three */
425
426 range->num_bitrates = RATE_COUNT;
427
428 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
429 range->bitrate[i] = rtl8180_rates[i];
430 }
431
432 range->min_frag = MIN_FRAG_THRESHOLD;
433 range->max_frag = MAX_FRAG_THRESHOLD;
434
435 range->min_pmp=0;
436 range->max_pmp = 5000000;
437 range->min_pmt = 0;
438 range->max_pmt = 65535*1000;
439 range->pmp_flags = IW_POWER_PERIOD;
440 range->pmt_flags = IW_POWER_TIMEOUT;
441 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
442
443 range->we_version_compiled = WIRELESS_EXT;
444 range->we_version_source = 16;
445
446// range->retry_capa; /* What retry options are supported */
447// range->retry_flags; /* How to decode max/min retry limit */
448// range->r_time_flags; /* How to decode max/min retry life */
449// range->min_retry; /* Minimal number of retries */
450// range->max_retry; /* Maximal number of retries */
451// range->min_r_time; /* Minimal retry lifetime */
452// range->max_r_time; /* Maximal retry lifetime */
453
454
455 for (i = 0, val = 0; i < 14; i++) {
456
457 // Include only legal frequencies for some countries
Jerry Chuang8fc85982009-11-03 07:17:11 -0200458 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200459 range->freq[val].i = i + 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200460 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
461 range->freq[val].e = 1;
462 val++;
463 } else {
464 // FIXME: do we need to set anything for channels
465 // we don't use ?
466 }
467
468 if (val == IW_MAX_FREQUENCIES)
469 break;
470 }
471 range->num_frequency = val;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200472 range->num_channels = val;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200473#if WIRELESS_EXT > 17
474 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
475 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
476#endif
477 tmp->scan_capa = 0x01;
478 return 0;
479}
480
481
482static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
483 union iwreq_data *wrqu, char *b)
484{
485 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300486 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200487 int ret = 0;
488
489 if(!priv->up) return -ENETDOWN;
490
491 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
492 return -EAGAIN;
493 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
494 {
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300495 struct iw_scan_req *req = (struct iw_scan_req *)b;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200496 if (req->essid_len)
497 {
498 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
499 ieee->current_network.ssid_len = req->essid_len;
500 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
501 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
502 }
503 }
504
505 down(&priv->wx_sem);
506 if(priv->ieee80211->state != IEEE80211_LINKED){
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200507 priv->ieee80211->scanning = 0;
508 ieee80211_softmac_scan_syncro(priv->ieee80211);
509 ret = 0;
510 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200511 else
512 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
513 up(&priv->wx_sem);
514 return ret;
515}
516
517
518static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
519 union iwreq_data *wrqu, char *b)
520{
521
522 int ret;
523 struct r8192_priv *priv = ieee80211_priv(dev);
524
525 if(!priv->up) return -ENETDOWN;
526
527 down(&priv->wx_sem);
528
529 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
530
531 up(&priv->wx_sem);
532
533 return ret;
534}
535
536static int r8192_wx_set_essid(struct net_device *dev,
537 struct iw_request_info *a,
538 union iwreq_data *wrqu, char *b)
539{
540 struct r8192_priv *priv = ieee80211_priv(dev);
541 int ret;
542 down(&priv->wx_sem);
543
544 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
545
546 up(&priv->wx_sem);
547
548 return ret;
549}
550
551
552
553
554static int r8192_wx_get_essid(struct net_device *dev,
555 struct iw_request_info *a,
556 union iwreq_data *wrqu, char *b)
557{
558 int ret;
559 struct r8192_priv *priv = ieee80211_priv(dev);
560
561 down(&priv->wx_sem);
562
563 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
564
565 up(&priv->wx_sem);
566
567 return ret;
568}
569
570
571static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
572 union iwreq_data *wrqu, char *b)
573{
574 int ret;
575 struct r8192_priv *priv = ieee80211_priv(dev);
576
577 down(&priv->wx_sem);
578
579 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
580
581 up(&priv->wx_sem);
582 return ret;
583}
584
585static int r8192_wx_get_name(struct net_device *dev,
586 struct iw_request_info *info,
587 union iwreq_data *wrqu, char *extra)
588{
589 struct r8192_priv *priv = ieee80211_priv(dev);
590 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
591}
592
593
594static int r8192_wx_set_frag(struct net_device *dev,
595 struct iw_request_info *info,
596 union iwreq_data *wrqu, char *extra)
597{
598 struct r8192_priv *priv = ieee80211_priv(dev);
599
600 if (wrqu->frag.disabled)
601 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
602 else {
603 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
604 wrqu->frag.value > MAX_FRAG_THRESHOLD)
605 return -EINVAL;
606
607 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
608 }
609
610 return 0;
611}
612
613
614static int r8192_wx_get_frag(struct net_device *dev,
615 struct iw_request_info *info,
616 union iwreq_data *wrqu, char *extra)
617{
618 struct r8192_priv *priv = ieee80211_priv(dev);
619
620 wrqu->frag.value = priv->ieee80211->fts;
621 wrqu->frag.fixed = 0; /* no auto select */
622 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
623
624 return 0;
625}
626
627
628static int r8192_wx_set_wap(struct net_device *dev,
629 struct iw_request_info *info,
630 union iwreq_data *awrq,
631 char *extra)
632{
633
634 int ret;
635 struct r8192_priv *priv = ieee80211_priv(dev);
636// struct sockaddr *temp = (struct sockaddr *)awrq;
637 down(&priv->wx_sem);
638
639 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
640
641 up(&priv->wx_sem);
642
643 return ret;
644
645}
646
647
648static int r8192_wx_get_wap(struct net_device *dev,
649 struct iw_request_info *info,
650 union iwreq_data *wrqu, char *extra)
651{
652 struct r8192_priv *priv = ieee80211_priv(dev);
653
654 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
655}
656
657
658static int r8192_wx_get_enc(struct net_device *dev,
659 struct iw_request_info *info,
660 union iwreq_data *wrqu, char *key)
661{
662 struct r8192_priv *priv = ieee80211_priv(dev);
663
664 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
665}
666
667static int r8192_wx_set_enc(struct net_device *dev,
668 struct iw_request_info *info,
669 union iwreq_data *wrqu, char *key)
670{
671 struct r8192_priv *priv = ieee80211_priv(dev);
672 struct ieee80211_device *ieee = priv->ieee80211;
673 int ret;
674
675 //u32 TargetContent;
676 u32 hwkey[4]={0,0,0,0};
677 u8 mask=0xff;
678 u32 key_idx=0;
679 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
680 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
681 {0x00,0x00,0x00,0x00,0x00,0x01},
682 {0x00,0x00,0x00,0x00,0x00,0x02},
683 {0x00,0x00,0x00,0x00,0x00,0x03} };
684 int i;
685
686 if(!priv->up) return -ENETDOWN;
687
688 down(&priv->wx_sem);
689
690 RT_TRACE(COMP_SEC, "Setting SW wep key");
691 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
692
693 up(&priv->wx_sem);
694
695
696
697 //sometimes, the length is zero while we do not type key value
698 if(wrqu->encoding.length!=0){
699
700 for(i=0 ; i<4 ; i++){
701 hwkey[i] |= key[4*i+0]&mask;
702 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
703 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
704 hwkey[i] |= (key[4*i+1]&mask)<<8;
705 hwkey[i] |= (key[4*i+2]&mask)<<16;
706 hwkey[i] |= (key[4*i+3]&mask)<<24;
707 }
708
709 #define CONF_WEP40 0x4
710 #define CONF_WEP104 0x14
711
Xenia Ragiadakouad638452013-05-12 03:15:08 +0300712 switch (wrqu->encoding.flags & IW_ENCODE_INDEX){
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100713 case 0: key_idx = ieee->tx_keyidx; break;
714 case 1: key_idx = 0; break;
715 case 2: key_idx = 1; break;
716 case 3: key_idx = 2; break;
717 case 4: key_idx = 3; break;
718 default: break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200719 }
720
721 if(wrqu->encoding.length==0x5){
722 ieee->pairwise_key_type = KEY_TYPE_WEP40;
723 EnableHWSecurityConfig8192(dev);
724
725 setKey( dev,
726 key_idx, //EntryNo
727 key_idx, //KeyIndex
728 KEY_TYPE_WEP40, //KeyType
729 zero_addr[key_idx],
730 0, //DefaultKey
731 hwkey); //KeyContent
732
733 }
734
735 else if(wrqu->encoding.length==0xd){
736 ieee->pairwise_key_type = KEY_TYPE_WEP104;
737 EnableHWSecurityConfig8192(dev);
738
739 setKey( dev,
740 key_idx, //EntryNo
741 key_idx, //KeyIndex
742 KEY_TYPE_WEP104, //KeyType
743 zero_addr[key_idx],
744 0, //DefaultKey
745 hwkey); //KeyContent
746
747 }
748 else printk("wrong type in WEP, not WEP40 and WEP104\n");
749
750 }
751
752 return ret;
753}
754
755
756static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
757 iwreq_data *wrqu, char *p){
758
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200759 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300760 int *parms=(int *)p;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200761 int mode=parms[0];
762
763 priv->ieee80211->active_scan = mode;
764
765 return 1;
766}
767
768
769
770static int r8192_wx_set_retry(struct net_device *dev,
771 struct iw_request_info *info,
772 union iwreq_data *wrqu, char *extra)
773{
774 struct r8192_priv *priv = ieee80211_priv(dev);
775 int err = 0;
776
777 down(&priv->wx_sem);
778
779 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
780 wrqu->retry.disabled){
781 err = -EINVAL;
782 goto exit;
783 }
784 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
785 err = -EINVAL;
786 goto exit;
787 }
788
789 if(wrqu->retry.value > R8180_MAX_RETRY){
790 err= -EINVAL;
791 goto exit;
792 }
793 if (wrqu->retry.flags & IW_RETRY_MAX) {
794 priv->retry_rts = wrqu->retry.value;
795 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
796
797 }else {
798 priv->retry_data = wrqu->retry.value;
799 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
800 }
801
802 /* FIXME !
803 * We might try to write directly the TX config register
804 * or to restart just the (R)TX process.
805 * I'm unsure if whole reset is really needed
806 */
807
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200808 rtl8192_commit(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200809 /*
810 if(priv->up){
811 rtl8180_rtx_disable(dev);
812 rtl8180_rx_enable(dev);
813 rtl8180_tx_enable(dev);
814
815 }
816 */
817exit:
818 up(&priv->wx_sem);
819
820 return err;
821}
822
823static int r8192_wx_get_retry(struct net_device *dev,
824 struct iw_request_info *info,
825 union iwreq_data *wrqu, char *extra)
826{
827 struct r8192_priv *priv = ieee80211_priv(dev);
828
829
830 wrqu->retry.disabled = 0; /* can't be disabled */
831
832 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
833 IW_RETRY_LIFETIME)
834 return -EINVAL;
835
836 if (wrqu->retry.flags & IW_RETRY_MAX) {
837 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
838 wrqu->retry.value = priv->retry_rts;
839 } else {
840 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
841 wrqu->retry.value = priv->retry_data;
842 }
843 //printk("returning %d",wrqu->retry.value);
844
845
846 return 0;
847}
848
849static int r8192_wx_get_sens(struct net_device *dev,
850 struct iw_request_info *info,
851 union iwreq_data *wrqu, char *extra)
852{
853 struct r8192_priv *priv = ieee80211_priv(dev);
854 if(priv->rf_set_sens == NULL)
855 return -1; /* we have not this support for this radio */
856 wrqu->sens.value = priv->sens;
857 return 0;
858}
859
860
861static int r8192_wx_set_sens(struct net_device *dev,
862 struct iw_request_info *info,
863 union iwreq_data *wrqu, char *extra)
864{
865
866 struct r8192_priv *priv = ieee80211_priv(dev);
867
868 short err = 0;
869 down(&priv->wx_sem);
870 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
871 if(priv->rf_set_sens == NULL) {
872 err= -1; /* we have not this support for this radio */
873 goto exit;
874 }
875 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
876 priv->sens = wrqu->sens.value;
877 else
878 err= -EINVAL;
879
880exit:
881 up(&priv->wx_sem);
882
883 return err;
884}
885
886#if (WIRELESS_EXT >= 18)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200887//hw security need to reorganized.
888static int r8192_wx_set_enc_ext(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200889 struct iw_request_info *info,
890 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200891{
892 int ret=0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200893 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300894 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200895 //printk("===>%s()\n", __FUNCTION__);
896
897
898 down(&priv->wx_sem);
899 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
900
901 {
902 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
903 u8 zero[6] = {0};
904 u32 key[4] = {0};
905 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
906 struct iw_point *encoding = &wrqu->encoding;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200907 u8 idx = 0, alg = 0, group = 0;
908 if ((encoding->flags & IW_ENCODE_DISABLED) ||
909 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
910 goto end_hw_sec;
911
912 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;
913 idx = encoding->flags & IW_ENCODE_INDEX;
914 if (idx)
915 idx --;
916 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
917
918 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
919 {
920 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
921 alg = KEY_TYPE_WEP104;
922 ieee->pairwise_key_type = alg;
923 EnableHWSecurityConfig8192(dev);
924 }
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300925 memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
Jerry Chuang8fc85982009-11-03 07:17:11 -0200926
927 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
928 {
929
930 setKey( dev,
931 idx,//EntryNo
932 idx, //KeyIndex
933 alg, //KeyType
934 zero, //MacAddr
935 0, //DefaultKey
936 key); //KeyContent
937 }
938 else if (group)
939 {
940 ieee->group_key_type = alg;
941 setKey( dev,
942 idx,//EntryNo
943 idx, //KeyIndex
944 alg, //KeyType
945 broadcast_addr, //MacAddr
946 0, //DefaultKey
947 key); //KeyContent
948 }
949 else //pairwise key
950 {
951 setKey( dev,
952 4,//EntryNo
953 idx, //KeyIndex
954 alg, //KeyType
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300955 (u8 *)ieee->ap_mac_addr, //MacAddr
Jerry Chuang8fc85982009-11-03 07:17:11 -0200956 0, //DefaultKey
957 key); //KeyContent
958 }
959
960
961 }
962
963end_hw_sec:
964
965 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200966 return ret;
967
968}
969static int r8192_wx_set_auth(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200970 struct iw_request_info *info,
971 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200972{
973 int ret=0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200974 //printk("====>%s()\n", __FUNCTION__);
975 struct r8192_priv *priv = ieee80211_priv(dev);
976 down(&priv->wx_sem);
977 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
978 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200979 return ret;
980}
981
982static int r8192_wx_set_mlme(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200983 struct iw_request_info *info,
984 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200985{
986 //printk("====>%s()\n", __FUNCTION__);
987
988 int ret=0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200989 struct r8192_priv *priv = ieee80211_priv(dev);
990 down(&priv->wx_sem);
991 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
992
993 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200994 return ret;
995}
996#endif
997static int r8192_wx_set_gen_ie(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200998 struct iw_request_info *info,
999 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001000{
1001 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1002 int ret=0;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001003 struct r8192_priv *priv = ieee80211_priv(dev);
1004 down(&priv->wx_sem);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001005 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001006 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001007 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001008 return ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001009
1010
1011}
1012
1013static int dummy(struct net_device *dev, struct iw_request_info *a,
1014 union iwreq_data *wrqu,char *b)
1015{
1016 return -1;
1017}
1018
1019
1020static iw_handler r8192_wx_handlers[] =
1021{
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001022 NULL, /* SIOCSIWCOMMIT */
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001023 r8192_wx_get_name, /* SIOCGIWNAME */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001024 dummy, /* SIOCSIWNWID */
1025 dummy, /* SIOCGIWNWID */
1026 r8192_wx_set_freq, /* SIOCSIWFREQ */
1027 r8192_wx_get_freq, /* SIOCGIWFREQ */
1028 r8192_wx_set_mode, /* SIOCSIWMODE */
1029 r8192_wx_get_mode, /* SIOCGIWMODE */
1030 r8192_wx_set_sens, /* SIOCSIWSENS */
1031 r8192_wx_get_sens, /* SIOCGIWSENS */
1032 NULL, /* SIOCSIWRANGE */
1033 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1034 NULL, /* SIOCSIWPRIV */
1035 NULL, /* SIOCGIWPRIV */
1036 NULL, /* SIOCSIWSTATS */
1037 NULL, /* SIOCGIWSTATS */
1038 dummy, /* SIOCSIWSPY */
1039 dummy, /* SIOCGIWSPY */
1040 NULL, /* SIOCGIWTHRSPY */
1041 NULL, /* SIOCWIWTHRSPY */
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001042 r8192_wx_set_wap, /* SIOCSIWAP */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001043 r8192_wx_get_wap, /* SIOCGIWAP */
Jerry Chuang8fc85982009-11-03 07:17:11 -02001044#if (WIRELESS_EXT >= 18)
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001045 r8192_wx_set_mlme, /* MLME-- */
Jerry Chuang8fc85982009-11-03 07:17:11 -02001046#else
1047 NULL,
1048#endif
Justin P. Mattock589b3d02012-04-30 07:41:36 -07001049 dummy, /* SIOCGIWAPLIST -- deprecated */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001050 r8192_wx_set_scan, /* SIOCSIWSCAN */
1051 r8192_wx_get_scan, /* SIOCGIWSCAN */
1052 r8192_wx_set_essid, /* SIOCSIWESSID */
1053 r8192_wx_get_essid, /* SIOCGIWESSID */
1054 dummy, /* SIOCSIWNICKN */
1055 dummy, /* SIOCGIWNICKN */
1056 NULL, /* -- hole -- */
1057 NULL, /* -- hole -- */
1058 r8192_wx_set_rate, /* SIOCSIWRATE */
1059 r8192_wx_get_rate, /* SIOCGIWRATE */
1060 r8192_wx_set_rts, /* SIOCSIWRTS */
1061 r8192_wx_get_rts, /* SIOCGIWRTS */
1062 r8192_wx_set_frag, /* SIOCSIWFRAG */
1063 r8192_wx_get_frag, /* SIOCGIWFRAG */
1064 dummy, /* SIOCSIWTXPOW */
1065 dummy, /* SIOCGIWTXPOW */
1066 r8192_wx_set_retry, /* SIOCSIWRETRY */
1067 r8192_wx_get_retry, /* SIOCGIWRETRY */
1068 r8192_wx_set_enc, /* SIOCSIWENCODE */
1069 r8192_wx_get_enc, /* SIOCGIWENCODE */
1070 r8192_wx_set_power, /* SIOCSIWPOWER */
1071 r8192_wx_get_power, /* SIOCGIWPOWER */
Jerry Chuang8fc85982009-11-03 07:17:11 -02001072 NULL, /*---hole---*/
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001073 NULL, /*---hole---*/
1074 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1075 NULL, /* SIOCSIWGENIE */
Jerry Chuang8fc85982009-11-03 07:17:11 -02001076
1077#if (WIRELESS_EXT >= 18)
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001078 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1079 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1080 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1081 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
Jerry Chuang8fc85982009-11-03 07:17:11 -02001082#else
1083 NULL,
1084 NULL,
1085 NULL,
1086 NULL,
1087#endif
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001088 NULL, /* SIOCSIWPMKSA */
1089 NULL, /*---hole---*/
Jerry Chuang8fc85982009-11-03 07:17:11 -02001090
1091};
1092
1093
1094static const struct iw_priv_args r8192_private_args[] = {
1095
1096 {
1097 SIOCIWFIRSTPRIV + 0x0,
1098 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1099 },
1100
1101 {
1102 SIOCIWFIRSTPRIV + 0x1,
1103 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1104
1105 },
1106 {
1107 SIOCIWFIRSTPRIV + 0x2,
1108 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1109 }
1110#ifdef JOHN_IOCTL
1111 ,
1112 {
1113 SIOCIWFIRSTPRIV + 0x3,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001114 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
Jerry Chuang8fc85982009-11-03 07:17:11 -02001115 }
1116 ,
1117 {
1118 SIOCIWFIRSTPRIV + 0x4,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001119 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
Jerry Chuang8fc85982009-11-03 07:17:11 -02001120 }
1121 ,
1122 {
1123 SIOCIWFIRSTPRIV + 0x5,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001124 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
Jerry Chuang8fc85982009-11-03 07:17:11 -02001125 }
1126 ,
1127 {
1128 SIOCIWFIRSTPRIV + 0x6,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001129 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
Jerry Chuang8fc85982009-11-03 07:17:11 -02001130 }
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001131 ,
1132 {
1133 SIOCIWFIRSTPRIV + 0x7,
1134 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1135 }
1136 ,
1137 {
1138 SIOCIWFIRSTPRIV + 0x8,
1139 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1140 }
1141 ,
1142 {
1143 SIOCIWFIRSTPRIV + 0x9,
1144 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1145 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001146
1147#endif
1148 ,
1149 {
1150 SIOCIWFIRSTPRIV + 0x3,
1151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1152
1153 }
1154
1155};
1156
1157
1158static iw_handler r8192_private_handler[] = {
1159// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1160 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1161// r8192_wx_set_forceassociate,
1162// r8192_wx_set_beaconinterval,
1163// r8192_wx_set_monitor_type,
1164 r8192_wx_set_scan_type,
1165 r8192_wx_set_rawtx,
1166#ifdef JOHN_IOCTL
1167 r8192_wx_read_regs,
1168 r8192_wx_write_regs,
1169 r8192_wx_read_bb,
1170 r8192_wx_write_bb,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001171 r8192_wx_read_nicb,
1172 r8192_wx_write_nicb,
Jerry Chuang8fc85982009-11-03 07:17:11 -02001173 r8192_wx_get_ap_status,
1174#endif
1175 //r8192_wx_null,
1176 r8192_wx_force_reset,
1177};
1178
1179//#if WIRELESS_EXT >= 17
1180struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1181{
1182 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +03001183 struct ieee80211_device *ieee = priv->ieee80211;
1184 struct iw_statistics *wstats = &priv->wstats;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001185 int tmp_level = 0;
1186 int tmp_qual = 0;
1187 int tmp_noise = 0;
1188 if(ieee->state < IEEE80211_LINKED)
1189 {
1190 wstats->qual.qual = 0;
1191 wstats->qual.level = 0;
1192 wstats->qual.noise = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001193 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001194 return wstats;
1195 }
1196
1197 tmp_level = (&ieee->current_network)->stats.rssi;
1198 tmp_qual = (&ieee->current_network)->stats.signal;
1199 tmp_noise = (&ieee->current_network)->stats.noise;
1200 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1201
1202 wstats->qual.level = tmp_level;
1203 wstats->qual.qual = tmp_qual;
1204 wstats->qual.noise = tmp_noise;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001205 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001206 return wstats;
1207}
1208//#endif
1209
1210
1211struct iw_handler_def r8192_wx_handlers_def={
1212 .standard = r8192_wx_handlers,
Jim Cromieb330f602012-04-10 16:06:41 -06001213 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
Jerry Chuang8fc85982009-11-03 07:17:11 -02001214 .private = r8192_private_handler,
Jim Cromieb330f602012-04-10 16:06:41 -06001215 .num_private = ARRAY_SIZE(r8192_private_handler),
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001216 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
Jerry Chuang8fc85982009-11-03 07:17:11 -02001217#if WIRELESS_EXT >= 17
1218 .get_wireless_stats = r8192_get_wireless_stats,
1219#endif
1220 .private_args = (struct iw_priv_args *)r8192_private_args,
1221};