blob: cccc88bcbf39ecdc76cc5aebf2cd452752ade2ec [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.
Andrea Merello559a4c32013-08-26 13:53:30 +02005 Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
Jerry Chuang8fc85982009-11-03 07:17:11 -02006 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
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070027u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
28 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
Jerry Chuang8fc85982009-11-03 07:17:11 -020029
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
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070041 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -020042}
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{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070048 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -020049
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070050 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -020051}
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);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -070060
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070061 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020062}
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
73 down(&priv->wx_sem);
74
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070075 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020076
77 up(&priv->wx_sem);
78
79 return ret;
80}
81
82
83static int r8192_wx_set_rts(struct net_device *dev,
84 struct iw_request_info *info,
85 union iwreq_data *wrqu, char *extra)
86{
87 int ret;
88 struct r8192_priv *priv = ieee80211_priv(dev);
89
90 down(&priv->wx_sem);
91
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070092 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020093
94 up(&priv->wx_sem);
95
96 return ret;
97}
98
99static int r8192_wx_get_rts(struct net_device *dev,
100 struct iw_request_info *info,
101 union iwreq_data *wrqu, char *extra)
102{
103 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700104
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700105 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200106}
107
108static int r8192_wx_set_power(struct net_device *dev,
109 struct iw_request_info *info,
110 union iwreq_data *wrqu, char *extra)
111{
112 int ret;
113 struct r8192_priv *priv = ieee80211_priv(dev);
114
115 down(&priv->wx_sem);
116
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700117 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200118
119 up(&priv->wx_sem);
120
121 return ret;
122}
123
124static int r8192_wx_get_power(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
127{
128 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700129
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700130 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200131}
132
Jerry Chuang8fc85982009-11-03 07:17:11 -0200133static int r8192_wx_force_reset(struct net_device *dev,
134 struct iw_request_info *info,
135 union iwreq_data *wrqu, char *extra)
136{
137 struct r8192_priv *priv = ieee80211_priv(dev);
138
139 down(&priv->wx_sem);
140
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700141 printk("%s(): force reset ! extra is %d\n", __func__, *extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200142 priv->force_reset = *extra;
143 up(&priv->wx_sem);
144 return 0;
145
146}
147
148
149static int r8192_wx_set_rawtx(struct net_device *dev,
150 struct iw_request_info *info,
151 union iwreq_data *wrqu, char *extra)
152{
153 struct r8192_priv *priv = ieee80211_priv(dev);
154 int ret;
155
156 down(&priv->wx_sem);
157
158 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
159
160 up(&priv->wx_sem);
161
162 return ret;
163
164}
165
166static int r8192_wx_set_crcmon(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 int *parms = (int *)extra;
172 int enable = (parms[0] > 0);
173 short prev = priv->crcmon;
174
175 down(&priv->wx_sem);
176
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700177 if (enable)
178 priv->crcmon = 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200179 else
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700180 priv->crcmon = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200181
182 DMESG("bad CRC in monitor mode are %s",
183 priv->crcmon ? "accepted" : "rejected");
184
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700185 if (prev != priv->crcmon && priv->up) {
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700186 /* rtl8180_down(dev); */
187 /* rtl8180_up(dev); */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200188 }
189
190 up(&priv->wx_sem);
191
192 return 0;
193}
194
195static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
196 union iwreq_data *wrqu, char *b)
197{
198 struct r8192_priv *priv = ieee80211_priv(dev);
199 int ret;
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700200
Jerry Chuang8fc85982009-11-03 07:17:11 -0200201 down(&priv->wx_sem);
202
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700203 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200204
205 rtl8192_set_rxconf(dev);
206
207 up(&priv->wx_sem);
208 return ret;
209}
210
Jennifer Naumann0db7a342012-12-05 21:40:19 +0100211struct iw_range_with_scan_capa {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200212 /* Informative stuff (to choose between different interface) */
213 __u32 throughput; /* To give an idea... */
214 /* In theory this value should be the maximum benchmarked
215 * TCP/IP throughput, because with most of these devices the
216 * bit rate is meaningless (overhead an co) to estimate how
217 * fast the connection will go and pick the fastest one.
218 * I suggest people to play with Netperf or any benchmark...
219 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200220
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200221 /* NWID (or domain id) */
222 __u32 min_nwid; /* Minimal NWID we are able to set */
223 __u32 max_nwid; /* Maximal NWID we are able to set */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200224
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200225 /* Old Frequency (backward compat - moved lower ) */
226 __u16 old_num_channels;
227 __u8 old_num_frequency;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200228
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200229 /* Scan capabilities */
230 __u8 scan_capa;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200231};
232static int rtl8180_wx_get_range(struct net_device *dev,
233 struct iw_request_info *info,
234 union iwreq_data *wrqu, char *extra)
235{
236 struct iw_range *range = (struct iw_range *)extra;
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300237 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200238 struct r8192_priv *priv = ieee80211_priv(dev);
239 u16 val;
240 int i;
241
242 wrqu->data.length = sizeof(*range);
243 memset(range, 0, sizeof(*range));
244
245 /* Let's try to keep this struct in the same order as in
246 * linux/include/wireless.h
247 */
248
249 /* TODO: See what values we can set, and remove the ones we can't
250 * set, or fill them with some default data.
251 */
252
253 /* ~5 Mb/s real (802.11b) */
254 range->throughput = 5 * 1000 * 1000;
255
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700256 /* TODO: Not used in 802.11b? */
257 /* range->min_nwid; */ /* Minimal NWID we are able to set */
258 /* TODO: Not used in 802.11b? */
259 /* range->max_nwid; */ /* Maximal NWID we are able to set */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200260
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200261 /* Old Frequency (backward compat - moved lower ) */
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700262 /* range->old_num_channels; */
263 /* range->old_num_frequency; */
264 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700265 if (priv->rf_set_sens != NULL)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200266 range->sensitivity = priv->max_sens; /* signal level threshold range */
267
268 range->max_qual.qual = 100;
269 /* TODO: Find real max RSSI and stick here */
270 range->max_qual.level = 0;
271 range->max_qual.noise = -98;
272 range->max_qual.updated = 7; /* Updated all three */
273
274 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700275 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200276 range->avg_qual.level = 20 + -98;
277 range->avg_qual.noise = 0;
278 range->avg_qual.updated = 7; /* Updated all three */
279
280 range->num_bitrates = RATE_COUNT;
281
Rui Miguel Silva2930d0b92014-04-28 12:12:54 +0100282 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200283 range->bitrate[i] = rtl8180_rates[i];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200284
285 range->min_frag = MIN_FRAG_THRESHOLD;
286 range->max_frag = MAX_FRAG_THRESHOLD;
287
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700288 range->min_pmp = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200289 range->max_pmp = 5000000;
290 range->min_pmt = 0;
291 range->max_pmt = 65535*1000;
292 range->pmp_flags = IW_POWER_PERIOD;
293 range->pmt_flags = IW_POWER_TIMEOUT;
294 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
295
296 range->we_version_compiled = WIRELESS_EXT;
297 range->we_version_source = 16;
298
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700299 /* range->retry_capa; */ /* What retry options are supported */
300 /* range->retry_flags; */ /* How to decode max/min retry limit */
301 /* range->r_time_flags; */ /* How to decode max/min retry life */
Chaitanya Hazarey0b5b4e22014-06-20 10:49:55 -0700302 /* range->min_retry; */ /* Minimal number of retries */
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700303 /* range->max_retry; */ /* Maximal number of retries */
304 /* range->min_r_time; */ /* Minimal retry lifetime */
305 /* range->max_r_time; */ /* Maximal retry lifetime */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200306
307
308 for (i = 0, val = 0; i < 14; i++) {
309
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700310 /* Include only legal frequencies for some countries */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200311 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200312 range->freq[val].i = i + 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200313 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
314 range->freq[val].e = 1;
315 val++;
316 } else {
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700317 /* FIXME: do we need to set anything for channels */
318 /* we don't use ? */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200319 }
320
321 if (val == IW_MAX_FREQUENCIES)
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700322 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200323 }
324 range->num_frequency = val;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200325 range->num_channels = val;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200326 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
327 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200328 tmp->scan_capa = 0x01;
329 return 0;
330}
331
332
333static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
334 union iwreq_data *wrqu, char *b)
335{
336 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300337 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200338 int ret = 0;
339
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700340 if (!priv->up)
341 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200342
343 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
344 return -EAGAIN;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700345 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300346 struct iw_scan_req *req = (struct iw_scan_req *)b;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700347 if (req->essid_len) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200348 ieee->current_network.ssid_len = req->essid_len;
349 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200350 }
351 }
352
353 down(&priv->wx_sem);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700354 if (priv->ieee80211->state != IEEE80211_LINKED) {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200355 priv->ieee80211->scanning = 0;
356 ieee80211_softmac_scan_syncro(priv->ieee80211);
357 ret = 0;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700358 } else {
359 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200360 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200361 up(&priv->wx_sem);
362 return ret;
363}
364
365
366static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
367 union iwreq_data *wrqu, char *b)
368{
369
370 int ret;
371 struct r8192_priv *priv = ieee80211_priv(dev);
372
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700373 if (!priv->up)
374 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200375
376 down(&priv->wx_sem);
377
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700378 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200379
380 up(&priv->wx_sem);
381
382 return ret;
383}
384
385static int r8192_wx_set_essid(struct net_device *dev,
386 struct iw_request_info *a,
387 union iwreq_data *wrqu, char *b)
388{
389 struct r8192_priv *priv = ieee80211_priv(dev);
390 int ret;
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700391
Jerry Chuang8fc85982009-11-03 07:17:11 -0200392 down(&priv->wx_sem);
393
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700394 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200395
396 up(&priv->wx_sem);
397
398 return ret;
399}
400
401
402
403
404static int r8192_wx_get_essid(struct net_device *dev,
405 struct iw_request_info *a,
406 union iwreq_data *wrqu, char *b)
407{
408 int ret;
409 struct r8192_priv *priv = ieee80211_priv(dev);
410
411 down(&priv->wx_sem);
412
413 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
414
415 up(&priv->wx_sem);
416
417 return ret;
418}
419
420
421static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
422 union iwreq_data *wrqu, char *b)
423{
424 int ret;
425 struct r8192_priv *priv = ieee80211_priv(dev);
426
427 down(&priv->wx_sem);
428
429 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
430
431 up(&priv->wx_sem);
432 return ret;
433}
434
435static int r8192_wx_get_name(struct net_device *dev,
436 struct iw_request_info *info,
437 union iwreq_data *wrqu, char *extra)
438{
439 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700440
Jerry Chuang8fc85982009-11-03 07:17:11 -0200441 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
442}
443
444
445static int r8192_wx_set_frag(struct net_device *dev,
446 struct iw_request_info *info,
447 union iwreq_data *wrqu, char *extra)
448{
449 struct r8192_priv *priv = ieee80211_priv(dev);
450
451 if (wrqu->frag.disabled)
452 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
453 else {
454 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
455 wrqu->frag.value > MAX_FRAG_THRESHOLD)
456 return -EINVAL;
457
458 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
459 }
460
461 return 0;
462}
463
464
465static int r8192_wx_get_frag(struct net_device *dev,
466 struct iw_request_info *info,
467 union iwreq_data *wrqu, char *extra)
468{
469 struct r8192_priv *priv = ieee80211_priv(dev);
470
471 wrqu->frag.value = priv->ieee80211->fts;
472 wrqu->frag.fixed = 0; /* no auto select */
473 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
474
475 return 0;
476}
477
478
479static int r8192_wx_set_wap(struct net_device *dev,
480 struct iw_request_info *info,
481 union iwreq_data *awrq,
482 char *extra)
483{
484
485 int ret;
486 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700487 /* struct sockaddr *temp = (struct sockaddr *)awrq; */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200488 down(&priv->wx_sem);
489
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700490 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200491
492 up(&priv->wx_sem);
493
494 return ret;
495
496}
497
498
499static int r8192_wx_get_wap(struct net_device *dev,
500 struct iw_request_info *info,
501 union iwreq_data *wrqu, char *extra)
502{
503 struct r8192_priv *priv = ieee80211_priv(dev);
504
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700505 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200506}
507
508
509static int r8192_wx_get_enc(struct net_device *dev,
510 struct iw_request_info *info,
511 union iwreq_data *wrqu, char *key)
512{
513 struct r8192_priv *priv = ieee80211_priv(dev);
514
515 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
516}
517
518static int r8192_wx_set_enc(struct net_device *dev,
519 struct iw_request_info *info,
520 union iwreq_data *wrqu, char *key)
521{
522 struct r8192_priv *priv = ieee80211_priv(dev);
523 struct ieee80211_device *ieee = priv->ieee80211;
524 int ret;
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700525 u32 hwkey[4] = {0, 0, 0, 0};
526 u8 mask = 0xff;
527 u32 key_idx = 0;
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700528 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
529 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
530 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
531 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
Jerry Chuang8fc85982009-11-03 07:17:11 -0200532 int i;
533
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700534 if (!priv->up)
535 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200536
537 down(&priv->wx_sem);
538
539 RT_TRACE(COMP_SEC, "Setting SW wep key");
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700540 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200541
542 up(&priv->wx_sem);
543
544
545
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700546 /* sometimes, the length is zero while we do not type key value */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700547 if (wrqu->encoding.length != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200548
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700549 for (i = 0; i < 4; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200550 hwkey[i] |= key[4*i+0]&mask;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700551 if (i == 1 && (4*i+1) == wrqu->encoding.length)
552 mask = 0x00;
553 if (i == 3 && (4*i+1) == wrqu->encoding.length)
554 mask = 0x00;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200555 hwkey[i] |= (key[4*i+1]&mask)<<8;
556 hwkey[i] |= (key[4*i+2]&mask)<<16;
557 hwkey[i] |= (key[4*i+3]&mask)<<24;
558 }
559
560 #define CONF_WEP40 0x4
561 #define CONF_WEP104 0x14
562
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700563 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700564 case 0:
565 key_idx = ieee->tx_keyidx;
566 break;
567 case 1:
568 key_idx = 0;
569 break;
570 case 2:
571 key_idx = 1;
572 break;
573 case 3:
574 key_idx = 2;
575 break;
576 case 4:
577 key_idx = 3;
578 break;
579 default:
580 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200581 }
582
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700583 if (wrqu->encoding.length == 0x5) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200584 ieee->pairwise_key_type = KEY_TYPE_WEP40;
585 EnableHWSecurityConfig8192(dev);
586
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700587 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700588 key_idx, /* EntryNo */
589 key_idx, /* KeyIndex */
590 KEY_TYPE_WEP40, /* KeyType */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200591 zero_addr[key_idx],
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700592 0, /* DefaultKey */
593 hwkey); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200594
595 }
596
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700597 else if (wrqu->encoding.length == 0xd) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200598 ieee->pairwise_key_type = KEY_TYPE_WEP104;
599 EnableHWSecurityConfig8192(dev);
600
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700601 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700602 key_idx, /* EntryNo */
603 key_idx, /* KeyIndex */
604 KEY_TYPE_WEP104, /* KeyType */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200605 zero_addr[key_idx],
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700606 0, /* DefaultKey */
607 hwkey); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200608
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700609 } else {
610 printk("wrong type in WEP, not WEP40 and WEP104\n");
Jerry Chuang8fc85982009-11-03 07:17:11 -0200611 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200612
613 }
614
615 return ret;
616}
617
618
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700619static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
Chaitanya Hazareye00b8fd2014-05-28 16:23:47 -0700620 union iwreq_data *wrqu, char *p)
621{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200622
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200623 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700624 int *parms = (int *)p;
625 int mode = parms[0];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200626
627 priv->ieee80211->active_scan = mode;
628
629 return 1;
630}
631
632
633
634static int r8192_wx_set_retry(struct net_device *dev,
635 struct iw_request_info *info,
636 union iwreq_data *wrqu, char *extra)
637{
638 struct r8192_priv *priv = ieee80211_priv(dev);
639 int err = 0;
640
641 down(&priv->wx_sem);
642
643 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
644 wrqu->retry.disabled){
645 err = -EINVAL;
646 goto exit;
647 }
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700648 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200649 err = -EINVAL;
650 goto exit;
651 }
652
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700653 if (wrqu->retry.value > R8180_MAX_RETRY) {
654 err = -EINVAL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200655 goto exit;
656 }
657 if (wrqu->retry.flags & IW_RETRY_MAX) {
658 priv->retry_rts = wrqu->retry.value;
659 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
660
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700661 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200662 priv->retry_data = wrqu->retry.value;
663 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
664 }
665
666 /* FIXME !
667 * We might try to write directly the TX config register
668 * or to restart just the (R)TX process.
669 * I'm unsure if whole reset is really needed
670 */
671
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200672 rtl8192_commit(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200673exit:
674 up(&priv->wx_sem);
675
676 return err;
677}
678
679static int r8192_wx_get_retry(struct net_device *dev,
680 struct iw_request_info *info,
681 union iwreq_data *wrqu, char *extra)
682{
683 struct r8192_priv *priv = ieee80211_priv(dev);
684
685
686 wrqu->retry.disabled = 0; /* can't be disabled */
687
688 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
689 IW_RETRY_LIFETIME)
690 return -EINVAL;
691
692 if (wrqu->retry.flags & IW_RETRY_MAX) {
693 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
694 wrqu->retry.value = priv->retry_rts;
695 } else {
696 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
697 wrqu->retry.value = priv->retry_data;
698 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200699
700
701 return 0;
702}
703
704static int r8192_wx_get_sens(struct net_device *dev,
705 struct iw_request_info *info,
706 union iwreq_data *wrqu, char *extra)
707{
708 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700709
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700710 if (priv->rf_set_sens == NULL)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200711 return -1; /* we have not this support for this radio */
712 wrqu->sens.value = priv->sens;
713 return 0;
714}
715
716
717static int r8192_wx_set_sens(struct net_device *dev,
718 struct iw_request_info *info,
719 union iwreq_data *wrqu, char *extra)
720{
721
722 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200723 short err = 0;
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700724
Jerry Chuang8fc85982009-11-03 07:17:11 -0200725 down(&priv->wx_sem);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700726 if (priv->rf_set_sens == NULL) {
727 err = -1; /* we have not this support for this radio */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200728 goto exit;
729 }
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700730 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200731 priv->sens = wrqu->sens.value;
732 else
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700733 err = -EINVAL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200734
735exit:
736 up(&priv->wx_sem);
737
738 return err;
739}
740
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700741/* hw security need to reorganized. */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200742static int r8192_wx_set_enc_ext(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200743 struct iw_request_info *info,
744 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200745{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700746 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200747 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300748 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200749
750
751 down(&priv->wx_sem);
752 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
753
754 {
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700755 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
Jerry Chuang8fc85982009-11-03 07:17:11 -0200756 u8 zero[6] = {0};
757 u32 key[4] = {0};
758 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
759 struct iw_point *encoding = &wrqu->encoding;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200760 u8 idx = 0, alg = 0, group = 0;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700761 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700762 /* none is not allowed to use hwsec WB 2008.07.01 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200763 goto end_hw_sec;
764
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700765 /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700766 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200767 idx = encoding->flags & IW_ENCODE_INDEX;
768 if (idx)
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700769 idx--;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200770 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
771
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700772 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) {
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700773 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
Jerry Chuang8fc85982009-11-03 07:17:11 -0200774 alg = KEY_TYPE_WEP104;
775 ieee->pairwise_key_type = alg;
776 EnableHWSecurityConfig8192(dev);
777 }
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700778 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200779
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700780 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200781
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700782 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700783 idx, /* EntryNao */
784 idx, /* KeyIndex */
785 alg, /* KeyType */
786 zero, /* MacAddr */
787 0, /* DefaultKey */
788 key); /* KeyContent */
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700789 } else if (group) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200790 ieee->group_key_type = alg;
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700791 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700792 idx, /* EntryNo */
793 idx, /* KeyIndex */
794 alg, /* KeyType */
795 broadcast_addr, /* MacAddr */
796 0, /* DefaultKey */
797 key); /* KeyContent */
798 } else { /* pairwise key */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700799 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700800 4, /* EntryNo */
801 idx, /* KeyIndex */
802 alg, /* KeyType */
803 (u8 *)ieee->ap_mac_addr,/* MacAddr */
804 0, /* DefaultKey */
Chaitanya Hazarey0b5b4e22014-06-20 10:49:55 -0700805 key); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200806 }
807
808
809 }
810
811end_hw_sec:
812
813 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200814 return ret;
815
816}
817static int r8192_wx_set_auth(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200818 struct iw_request_info *info,
819 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200820{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700821 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200822 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700823
Jerry Chuang8fc85982009-11-03 07:17:11 -0200824 down(&priv->wx_sem);
825 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
826 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200827 return ret;
828}
829
830static int r8192_wx_set_mlme(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200831 struct iw_request_info *info,
832 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200833{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200834
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700835 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200836 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700837
Jerry Chuang8fc85982009-11-03 07:17:11 -0200838 down(&priv->wx_sem);
839 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
840
841 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200842 return ret;
843}
Joel Pelaez Jorgee6c1ef62014-05-23 14:27:43 -0500844
Jerry Chuang8fc85982009-11-03 07:17:11 -0200845static int r8192_wx_set_gen_ie(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200846 struct iw_request_info *info,
847 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200848{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700849 int ret = 0;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200850 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700851
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200852 down(&priv->wx_sem);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200853 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200854 up(&priv->wx_sem);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200855 return ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200856
857
858}
859
860static int dummy(struct net_device *dev, struct iw_request_info *a,
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700861 union iwreq_data *wrqu, char *b)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200862{
863 return -1;
864}
865
866
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700867static iw_handler r8192_wx_handlers[] = {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200868 NULL, /* SIOCSIWCOMMIT */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100869 r8192_wx_get_name, /* SIOCGIWNAME */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200870 dummy, /* SIOCSIWNWID */
871 dummy, /* SIOCGIWNWID */
872 r8192_wx_set_freq, /* SIOCSIWFREQ */
873 r8192_wx_get_freq, /* SIOCGIWFREQ */
874 r8192_wx_set_mode, /* SIOCSIWMODE */
875 r8192_wx_get_mode, /* SIOCGIWMODE */
876 r8192_wx_set_sens, /* SIOCSIWSENS */
877 r8192_wx_get_sens, /* SIOCGIWSENS */
878 NULL, /* SIOCSIWRANGE */
879 rtl8180_wx_get_range, /* SIOCGIWRANGE */
880 NULL, /* SIOCSIWPRIV */
881 NULL, /* SIOCGIWPRIV */
882 NULL, /* SIOCSIWSTATS */
883 NULL, /* SIOCGIWSTATS */
884 dummy, /* SIOCSIWSPY */
885 dummy, /* SIOCGIWSPY */
886 NULL, /* SIOCGIWTHRSPY */
887 NULL, /* SIOCWIWTHRSPY */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100888 r8192_wx_set_wap, /* SIOCSIWAP */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200889 r8192_wx_get_wap, /* SIOCGIWAP */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200890 r8192_wx_set_mlme, /* MLME-- */
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700891 dummy, /* SIOCGIWAPLIST -- deprecated */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200892 r8192_wx_set_scan, /* SIOCSIWSCAN */
893 r8192_wx_get_scan, /* SIOCGIWSCAN */
894 r8192_wx_set_essid, /* SIOCSIWESSID */
895 r8192_wx_get_essid, /* SIOCGIWESSID */
896 dummy, /* SIOCSIWNICKN */
897 dummy, /* SIOCGIWNICKN */
898 NULL, /* -- hole -- */
899 NULL, /* -- hole -- */
900 r8192_wx_set_rate, /* SIOCSIWRATE */
901 r8192_wx_get_rate, /* SIOCGIWRATE */
902 r8192_wx_set_rts, /* SIOCSIWRTS */
903 r8192_wx_get_rts, /* SIOCGIWRTS */
904 r8192_wx_set_frag, /* SIOCSIWFRAG */
905 r8192_wx_get_frag, /* SIOCGIWFRAG */
906 dummy, /* SIOCSIWTXPOW */
907 dummy, /* SIOCGIWTXPOW */
908 r8192_wx_set_retry, /* SIOCSIWRETRY */
909 r8192_wx_get_retry, /* SIOCGIWRETRY */
910 r8192_wx_set_enc, /* SIOCSIWENCODE */
911 r8192_wx_get_enc, /* SIOCGIWENCODE */
912 r8192_wx_set_power, /* SIOCSIWPOWER */
913 r8192_wx_get_power, /* SIOCGIWPOWER */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200914 NULL, /*---hole---*/
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100915 NULL, /*---hole---*/
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700916 r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100917 NULL, /* SIOCSIWGENIE */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200918
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700919 r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
920 NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100921 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700922 NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100923 NULL, /* SIOCSIWPMKSA */
924 NULL, /*---hole---*/
Jerry Chuang8fc85982009-11-03 07:17:11 -0200925
926};
927
928
929static const struct iw_priv_args r8192_private_args[] = {
930
931 {
932 SIOCIWFIRSTPRIV + 0x0,
933 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
934 },
935
936 {
937 SIOCIWFIRSTPRIV + 0x1,
938 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
939
940 },
941 {
942 SIOCIWFIRSTPRIV + 0x2,
943 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
Xenia Ragiadakouaa0cb592013-10-10 10:43:47 +0300944 },
Jerry Chuang8fc85982009-11-03 07:17:11 -0200945 {
946 SIOCIWFIRSTPRIV + 0x3,
947 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
948
949 }
950
951};
952
953
954static iw_handler r8192_private_handler[] = {
Chaitanya Hazarey69eb9762014-06-02 09:11:45 -0700955 r8192_wx_set_crcmon,
Jerry Chuang8fc85982009-11-03 07:17:11 -0200956 r8192_wx_set_scan_type,
957 r8192_wx_set_rawtx,
Jerry Chuang8fc85982009-11-03 07:17:11 -0200958 r8192_wx_force_reset,
959};
960
Jerry Chuang8fc85982009-11-03 07:17:11 -0200961struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
962{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700963 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300964 struct ieee80211_device *ieee = priv->ieee80211;
965 struct iw_statistics *wstats = &priv->wstats;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200966 int tmp_level = 0;
967 int tmp_qual = 0;
968 int tmp_noise = 0;
Chaitanya Hazareya08d5412014-06-20 10:49:54 -0700969
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700970 if (ieee->state < IEEE80211_LINKED) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200971 wstats->qual.qual = 0;
972 wstats->qual.level = 0;
973 wstats->qual.noise = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200974 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200975 return wstats;
976 }
977
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700978 tmp_level = (&ieee->current_network)->stats.rssi;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200979 tmp_qual = (&ieee->current_network)->stats.signal;
980 tmp_noise = (&ieee->current_network)->stats.noise;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200981
982 wstats->qual.level = tmp_level;
983 wstats->qual.qual = tmp_qual;
984 wstats->qual.noise = tmp_noise;
Chaitanya Hazarey31c207f2014-05-29 13:45:20 -0700985 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200986 return wstats;
987}
Jerry Chuang8fc85982009-11-03 07:17:11 -0200988
989
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700990struct iw_handler_def r8192_wx_handlers_def = {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200991 .standard = r8192_wx_handlers,
Jim Cromieb330f602012-04-10 16:06:41 -0600992 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
Jerry Chuang8fc85982009-11-03 07:17:11 -0200993 .private = r8192_private_handler,
Jim Cromieb330f602012-04-10 16:06:41 -0600994 .num_private = ARRAY_SIZE(r8192_private_handler),
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200995 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
Jerry Chuang8fc85982009-11-03 07:17:11 -0200996 .get_wireless_stats = r8192_get_wireless_stats,
Jerry Chuang8fc85982009-11-03 07:17:11 -0200997 .private_args = (struct iw_priv_args *)r8192_private_args,
998};