blob: b533784eac8f6348442e392e4724d81d586389b2 [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 Hazarey654d1ce2014-05-28 07:32:38 -070060 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020061}
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
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070074 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020075
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
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -070091 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -020092
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);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700103 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200104}
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
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700115 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200116
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);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700127 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200128}
129
Jerry Chuang8fc85982009-11-03 07:17:11 -0200130static int r8192_wx_force_reset(struct net_device *dev,
131 struct iw_request_info *info,
132 union iwreq_data *wrqu, char *extra)
133{
134 struct r8192_priv *priv = ieee80211_priv(dev);
135
136 down(&priv->wx_sem);
137
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700138 printk("%s(): force reset ! extra is %d\n", __func__, *extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200139 priv->force_reset = *extra;
140 up(&priv->wx_sem);
141 return 0;
142
143}
144
145
146static int r8192_wx_set_rawtx(struct net_device *dev,
147 struct iw_request_info *info,
148 union iwreq_data *wrqu, char *extra)
149{
150 struct r8192_priv *priv = ieee80211_priv(dev);
151 int ret;
152
153 down(&priv->wx_sem);
154
155 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
156
157 up(&priv->wx_sem);
158
159 return ret;
160
161}
162
163static int r8192_wx_set_crcmon(struct net_device *dev,
164 struct iw_request_info *info,
165 union iwreq_data *wrqu, char *extra)
166{
167 struct r8192_priv *priv = ieee80211_priv(dev);
168 int *parms = (int *)extra;
169 int enable = (parms[0] > 0);
170 short prev = priv->crcmon;
171
172 down(&priv->wx_sem);
173
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700174 if (enable)
175 priv->crcmon = 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200176 else
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700177 priv->crcmon = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200178
179 DMESG("bad CRC in monitor mode are %s",
180 priv->crcmon ? "accepted" : "rejected");
181
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700182 if (prev != priv->crcmon && priv->up) {
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700183 /* rtl8180_down(dev); */
184 /* rtl8180_up(dev); */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200185 }
186
187 up(&priv->wx_sem);
188
189 return 0;
190}
191
192static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
193 union iwreq_data *wrqu, char *b)
194{
195 struct r8192_priv *priv = ieee80211_priv(dev);
196 int ret;
197 down(&priv->wx_sem);
198
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700199 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200200
201 rtl8192_set_rxconf(dev);
202
203 up(&priv->wx_sem);
204 return ret;
205}
206
Jennifer Naumann0db7a342012-12-05 21:40:19 +0100207struct iw_range_with_scan_capa {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200208 /* Informative stuff (to choose between different interface) */
209 __u32 throughput; /* To give an idea... */
210 /* In theory this value should be the maximum benchmarked
211 * TCP/IP throughput, because with most of these devices the
212 * bit rate is meaningless (overhead an co) to estimate how
213 * fast the connection will go and pick the fastest one.
214 * I suggest people to play with Netperf or any benchmark...
215 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200216
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200217 /* NWID (or domain id) */
218 __u32 min_nwid; /* Minimal NWID we are able to set */
219 __u32 max_nwid; /* Maximal NWID we are able to set */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200220
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200221 /* Old Frequency (backward compat - moved lower ) */
222 __u16 old_num_channels;
223 __u8 old_num_frequency;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200224
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200225 /* Scan capabilities */
226 __u8 scan_capa;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200227};
228static int rtl8180_wx_get_range(struct net_device *dev,
229 struct iw_request_info *info,
230 union iwreq_data *wrqu, char *extra)
231{
232 struct iw_range *range = (struct iw_range *)extra;
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300233 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200234 struct r8192_priv *priv = ieee80211_priv(dev);
235 u16 val;
236 int i;
237
238 wrqu->data.length = sizeof(*range);
239 memset(range, 0, sizeof(*range));
240
241 /* Let's try to keep this struct in the same order as in
242 * linux/include/wireless.h
243 */
244
245 /* TODO: See what values we can set, and remove the ones we can't
246 * set, or fill them with some default data.
247 */
248
249 /* ~5 Mb/s real (802.11b) */
250 range->throughput = 5 * 1000 * 1000;
251
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700252 /* TODO: Not used in 802.11b? */
253 /* range->min_nwid; */ /* Minimal NWID we are able to set */
254 /* TODO: Not used in 802.11b? */
255 /* range->max_nwid; */ /* Maximal NWID we are able to set */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200256
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200257 /* Old Frequency (backward compat - moved lower ) */
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700258 /* range->old_num_channels; */
259 /* range->old_num_frequency; */
260 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700261 if (priv->rf_set_sens != NULL)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200262 range->sensitivity = priv->max_sens; /* signal level threshold range */
263
264 range->max_qual.qual = 100;
265 /* TODO: Find real max RSSI and stick here */
266 range->max_qual.level = 0;
267 range->max_qual.noise = -98;
268 range->max_qual.updated = 7; /* Updated all three */
269
270 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700271 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200272 range->avg_qual.level = 20 + -98;
273 range->avg_qual.noise = 0;
274 range->avg_qual.updated = 7; /* Updated all three */
275
276 range->num_bitrates = RATE_COUNT;
277
Rui Miguel Silva2930d0b92014-04-28 12:12:54 +0100278 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200279 range->bitrate[i] = rtl8180_rates[i];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200280
281 range->min_frag = MIN_FRAG_THRESHOLD;
282 range->max_frag = MAX_FRAG_THRESHOLD;
283
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700284 range->min_pmp = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200285 range->max_pmp = 5000000;
286 range->min_pmt = 0;
287 range->max_pmt = 65535*1000;
288 range->pmp_flags = IW_POWER_PERIOD;
289 range->pmt_flags = IW_POWER_TIMEOUT;
290 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
291
292 range->we_version_compiled = WIRELESS_EXT;
293 range->we_version_source = 16;
294
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700295 /* range->retry_capa; */ /* What retry options are supported */
296 /* range->retry_flags; */ /* How to decode max/min retry limit */
297 /* range->r_time_flags; */ /* How to decode max/min retry life */
298 /* range->min_retry; */ /* Minimal number of retries */
299 /* range->max_retry; */ /* Maximal number of retries */
300 /* range->min_r_time; */ /* Minimal retry lifetime */
301 /* range->max_r_time; */ /* Maximal retry lifetime */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200302
303
304 for (i = 0, val = 0; i < 14; i++) {
305
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700306 /* Include only legal frequencies for some countries */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200307 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200308 range->freq[val].i = i + 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200309 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
310 range->freq[val].e = 1;
311 val++;
312 } else {
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700313 /* FIXME: do we need to set anything for channels */
314 /* we don't use ? */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200315 }
316
317 if (val == IW_MAX_FREQUENCIES)
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700318 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200319 }
320 range->num_frequency = val;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200321 range->num_channels = val;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200322 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
323 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200324 tmp->scan_capa = 0x01;
325 return 0;
326}
327
328
329static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
330 union iwreq_data *wrqu, char *b)
331{
332 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300333 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200334 int ret = 0;
335
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700336 if (!priv->up)
337 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200338
339 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
340 return -EAGAIN;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700341 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300342 struct iw_scan_req *req = (struct iw_scan_req *)b;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700343 if (req->essid_len) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200344 ieee->current_network.ssid_len = req->essid_len;
345 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200346 }
347 }
348
349 down(&priv->wx_sem);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700350 if (priv->ieee80211->state != IEEE80211_LINKED) {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200351 priv->ieee80211->scanning = 0;
352 ieee80211_softmac_scan_syncro(priv->ieee80211);
353 ret = 0;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700354 } else {
355 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200356 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200357 up(&priv->wx_sem);
358 return ret;
359}
360
361
362static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
363 union iwreq_data *wrqu, char *b)
364{
365
366 int ret;
367 struct r8192_priv *priv = ieee80211_priv(dev);
368
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700369 if (!priv->up)
370 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200371
372 down(&priv->wx_sem);
373
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700374 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200375
376 up(&priv->wx_sem);
377
378 return ret;
379}
380
381static int r8192_wx_set_essid(struct net_device *dev,
382 struct iw_request_info *a,
383 union iwreq_data *wrqu, char *b)
384{
385 struct r8192_priv *priv = ieee80211_priv(dev);
386 int ret;
387 down(&priv->wx_sem);
388
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700389 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200390
391 up(&priv->wx_sem);
392
393 return ret;
394}
395
396
397
398
399static int r8192_wx_get_essid(struct net_device *dev,
400 struct iw_request_info *a,
401 union iwreq_data *wrqu, char *b)
402{
403 int ret;
404 struct r8192_priv *priv = ieee80211_priv(dev);
405
406 down(&priv->wx_sem);
407
408 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
409
410 up(&priv->wx_sem);
411
412 return ret;
413}
414
415
416static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
417 union iwreq_data *wrqu, char *b)
418{
419 int ret;
420 struct r8192_priv *priv = ieee80211_priv(dev);
421
422 down(&priv->wx_sem);
423
424 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
425
426 up(&priv->wx_sem);
427 return ret;
428}
429
430static int r8192_wx_get_name(struct net_device *dev,
431 struct iw_request_info *info,
432 union iwreq_data *wrqu, char *extra)
433{
434 struct r8192_priv *priv = ieee80211_priv(dev);
435 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
436}
437
438
439static int r8192_wx_set_frag(struct net_device *dev,
440 struct iw_request_info *info,
441 union iwreq_data *wrqu, char *extra)
442{
443 struct r8192_priv *priv = ieee80211_priv(dev);
444
445 if (wrqu->frag.disabled)
446 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
447 else {
448 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
449 wrqu->frag.value > MAX_FRAG_THRESHOLD)
450 return -EINVAL;
451
452 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
453 }
454
455 return 0;
456}
457
458
459static int r8192_wx_get_frag(struct net_device *dev,
460 struct iw_request_info *info,
461 union iwreq_data *wrqu, char *extra)
462{
463 struct r8192_priv *priv = ieee80211_priv(dev);
464
465 wrqu->frag.value = priv->ieee80211->fts;
466 wrqu->frag.fixed = 0; /* no auto select */
467 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
468
469 return 0;
470}
471
472
473static int r8192_wx_set_wap(struct net_device *dev,
474 struct iw_request_info *info,
475 union iwreq_data *awrq,
476 char *extra)
477{
478
479 int ret;
480 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700481 /* struct sockaddr *temp = (struct sockaddr *)awrq; */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200482 down(&priv->wx_sem);
483
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700484 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200485
486 up(&priv->wx_sem);
487
488 return ret;
489
490}
491
492
493static int r8192_wx_get_wap(struct net_device *dev,
494 struct iw_request_info *info,
495 union iwreq_data *wrqu, char *extra)
496{
497 struct r8192_priv *priv = ieee80211_priv(dev);
498
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700499 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200500}
501
502
503static int r8192_wx_get_enc(struct net_device *dev,
504 struct iw_request_info *info,
505 union iwreq_data *wrqu, char *key)
506{
507 struct r8192_priv *priv = ieee80211_priv(dev);
508
509 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
510}
511
512static int r8192_wx_set_enc(struct net_device *dev,
513 struct iw_request_info *info,
514 union iwreq_data *wrqu, char *key)
515{
516 struct r8192_priv *priv = ieee80211_priv(dev);
517 struct ieee80211_device *ieee = priv->ieee80211;
518 int ret;
519
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700520 /* u32 TargetContent; */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700521 u32 hwkey[4] = {0, 0, 0, 0};
522 u8 mask = 0xff;
523 u32 key_idx = 0;
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700524 /* u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff}; */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700525 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
526 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
527 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
528 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
Jerry Chuang8fc85982009-11-03 07:17:11 -0200529 int i;
530
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700531 if (!priv->up)
532 return -ENETDOWN;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200533
534 down(&priv->wx_sem);
535
536 RT_TRACE(COMP_SEC, "Setting SW wep key");
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700537 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200538
539 up(&priv->wx_sem);
540
541
542
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700543 /* sometimes, the length is zero while we do not type key value */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700544 if (wrqu->encoding.length != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200545
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700546 for (i = 0; i < 4; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200547 hwkey[i] |= key[4*i+0]&mask;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700548 if (i == 1 && (4*i+1) == wrqu->encoding.length)
549 mask = 0x00;
550 if (i == 3 && (4*i+1) == wrqu->encoding.length)
551 mask = 0x00;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200552 hwkey[i] |= (key[4*i+1]&mask)<<8;
553 hwkey[i] |= (key[4*i+2]&mask)<<16;
554 hwkey[i] |= (key[4*i+3]&mask)<<24;
555 }
556
557 #define CONF_WEP40 0x4
558 #define CONF_WEP104 0x14
559
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700560 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700561 case 0:
562 key_idx = ieee->tx_keyidx;
563 break;
564 case 1:
565 key_idx = 0;
566 break;
567 case 2:
568 key_idx = 1;
569 break;
570 case 3:
571 key_idx = 2;
572 break;
573 case 4:
574 key_idx = 3;
575 break;
576 default:
577 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200578 }
579
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700580 if (wrqu->encoding.length == 0x5) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200581 ieee->pairwise_key_type = KEY_TYPE_WEP40;
582 EnableHWSecurityConfig8192(dev);
583
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700584 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700585 key_idx, /* EntryNo */
586 key_idx, /* KeyIndex */
587 KEY_TYPE_WEP40, /* KeyType */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200588 zero_addr[key_idx],
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700589 0, /* DefaultKey */
590 hwkey); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200591
592 }
593
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700594 else if (wrqu->encoding.length == 0xd) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200595 ieee->pairwise_key_type = KEY_TYPE_WEP104;
596 EnableHWSecurityConfig8192(dev);
597
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700598 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700599 key_idx, /* EntryNo */
600 key_idx, /* KeyIndex */
601 KEY_TYPE_WEP104, /* KeyType */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200602 zero_addr[key_idx],
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700603 0, /* DefaultKey */
604 hwkey); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200605
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700606 } else {
607 printk("wrong type in WEP, not WEP40 and WEP104\n");
Jerry Chuang8fc85982009-11-03 07:17:11 -0200608 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200609
610 }
611
612 return ret;
613}
614
615
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700616static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
Chaitanya Hazareye00b8fd2014-05-28 16:23:47 -0700617 union iwreq_data *wrqu, char *p)
618{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200619
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200620 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700621 int *parms = (int *)p;
622 int mode = parms[0];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200623
624 priv->ieee80211->active_scan = mode;
625
626 return 1;
627}
628
629
630
631static int r8192_wx_set_retry(struct net_device *dev,
632 struct iw_request_info *info,
633 union iwreq_data *wrqu, char *extra)
634{
635 struct r8192_priv *priv = ieee80211_priv(dev);
636 int err = 0;
637
638 down(&priv->wx_sem);
639
640 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
641 wrqu->retry.disabled){
642 err = -EINVAL;
643 goto exit;
644 }
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700645 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200646 err = -EINVAL;
647 goto exit;
648 }
649
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700650 if (wrqu->retry.value > R8180_MAX_RETRY) {
651 err = -EINVAL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200652 goto exit;
653 }
654 if (wrqu->retry.flags & IW_RETRY_MAX) {
655 priv->retry_rts = wrqu->retry.value;
656 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
657
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700658 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200659 priv->retry_data = wrqu->retry.value;
660 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
661 }
662
663 /* FIXME !
664 * We might try to write directly the TX config register
665 * or to restart just the (R)TX process.
666 * I'm unsure if whole reset is really needed
667 */
668
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200669 rtl8192_commit(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200670 /*
671 if(priv->up){
672 rtl8180_rtx_disable(dev);
673 rtl8180_rx_enable(dev);
674 rtl8180_tx_enable(dev);
675
676 }
677 */
678exit:
679 up(&priv->wx_sem);
680
681 return err;
682}
683
684static int r8192_wx_get_retry(struct net_device *dev,
685 struct iw_request_info *info,
686 union iwreq_data *wrqu, char *extra)
687{
688 struct r8192_priv *priv = ieee80211_priv(dev);
689
690
691 wrqu->retry.disabled = 0; /* can't be disabled */
692
693 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
694 IW_RETRY_LIFETIME)
695 return -EINVAL;
696
697 if (wrqu->retry.flags & IW_RETRY_MAX) {
698 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
699 wrqu->retry.value = priv->retry_rts;
700 } else {
701 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
702 wrqu->retry.value = priv->retry_data;
703 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200704
705
706 return 0;
707}
708
709static int r8192_wx_get_sens(struct net_device *dev,
710 struct iw_request_info *info,
711 union iwreq_data *wrqu, char *extra)
712{
713 struct r8192_priv *priv = ieee80211_priv(dev);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700714 if (priv->rf_set_sens == NULL)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200715 return -1; /* we have not this support for this radio */
716 wrqu->sens.value = priv->sens;
717 return 0;
718}
719
720
721static int r8192_wx_set_sens(struct net_device *dev,
722 struct iw_request_info *info,
723 union iwreq_data *wrqu, char *extra)
724{
725
726 struct r8192_priv *priv = ieee80211_priv(dev);
727
728 short err = 0;
729 down(&priv->wx_sem);
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700730 if (priv->rf_set_sens == NULL) {
731 err = -1; /* we have not this support for this radio */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200732 goto exit;
733 }
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700734 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200735 priv->sens = wrqu->sens.value;
736 else
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700737 err = -EINVAL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200738
739exit:
740 up(&priv->wx_sem);
741
742 return err;
743}
744
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700745/* hw security need to reorganized. */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200746static int r8192_wx_set_enc_ext(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200747 struct iw_request_info *info,
748 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200749{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700750 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200751 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300752 struct ieee80211_device *ieee = priv->ieee80211;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200753
754
755 down(&priv->wx_sem);
756 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
757
758 {
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700759 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
Jerry Chuang8fc85982009-11-03 07:17:11 -0200760 u8 zero[6] = {0};
761 u32 key[4] = {0};
762 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
763 struct iw_point *encoding = &wrqu->encoding;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200764 u8 idx = 0, alg = 0, group = 0;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700765 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700766 /* none is not allowed to use hwsec WB 2008.07.01 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200767 goto end_hw_sec;
768
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700769 /* 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 -0700770 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200771 idx = encoding->flags & IW_ENCODE_INDEX;
772 if (idx)
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700773 idx--;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200774 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
775
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700776 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) {
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700777 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
Jerry Chuang8fc85982009-11-03 07:17:11 -0200778 alg = KEY_TYPE_WEP104;
779 ieee->pairwise_key_type = alg;
780 EnableHWSecurityConfig8192(dev);
781 }
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700782 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200783
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700784 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200785
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700786 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700787 idx, /* EntryNao */
788 idx, /* KeyIndex */
789 alg, /* KeyType */
790 zero, /* MacAddr */
791 0, /* DefaultKey */
792 key); /* KeyContent */
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700793 } else if (group) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200794 ieee->group_key_type = alg;
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700795 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700796 idx, /* EntryNo */
797 idx, /* KeyIndex */
798 alg, /* KeyType */
799 broadcast_addr, /* MacAddr */
800 0, /* DefaultKey */
801 key); /* KeyContent */
802 } else { /* pairwise key */
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700803 setKey(dev,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700804 4, /* EntryNo */
805 idx, /* KeyIndex */
806 alg, /* KeyType */
807 (u8 *)ieee->ap_mac_addr,/* MacAddr */
808 0, /* DefaultKey */
809 key); /* KeyContent */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200810 }
811
812
813 }
814
815end_hw_sec:
816
817 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200818 return ret;
819
820}
821static int r8192_wx_set_auth(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200822 struct iw_request_info *info,
823 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200824{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700825 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200826 struct r8192_priv *priv = ieee80211_priv(dev);
827 down(&priv->wx_sem);
828 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
829 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200830 return ret;
831}
832
833static int r8192_wx_set_mlme(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200834 struct iw_request_info *info,
835 union iwreq_data *wrqu, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200836{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200837
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700838 int ret = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200839 struct r8192_priv *priv = ieee80211_priv(dev);
840 down(&priv->wx_sem);
841 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
842
843 up(&priv->wx_sem);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200844 return ret;
845}
Joel Pelaez Jorgee6c1ef62014-05-23 14:27:43 -0500846
Jerry Chuang8fc85982009-11-03 07:17:11 -0200847static int r8192_wx_set_gen_ie(struct net_device *dev,
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200848 struct iw_request_info *info,
849 union iwreq_data *data, char *extra)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200850{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700851 int ret = 0;
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200852 struct r8192_priv *priv = ieee80211_priv(dev);
853 down(&priv->wx_sem);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200854 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200855 up(&priv->wx_sem);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200856 return ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200857
858
859}
860
861static int dummy(struct net_device *dev, struct iw_request_info *a,
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700862 union iwreq_data *wrqu, char *b)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200863{
864 return -1;
865}
866
867
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700868static iw_handler r8192_wx_handlers[] = {
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200869 NULL, /* SIOCSIWCOMMIT */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100870 r8192_wx_get_name, /* SIOCGIWNAME */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200871 dummy, /* SIOCSIWNWID */
872 dummy, /* SIOCGIWNWID */
873 r8192_wx_set_freq, /* SIOCSIWFREQ */
874 r8192_wx_get_freq, /* SIOCGIWFREQ */
875 r8192_wx_set_mode, /* SIOCSIWMODE */
876 r8192_wx_get_mode, /* SIOCGIWMODE */
877 r8192_wx_set_sens, /* SIOCSIWSENS */
878 r8192_wx_get_sens, /* SIOCGIWSENS */
879 NULL, /* SIOCSIWRANGE */
880 rtl8180_wx_get_range, /* SIOCGIWRANGE */
881 NULL, /* SIOCSIWPRIV */
882 NULL, /* SIOCGIWPRIV */
883 NULL, /* SIOCSIWSTATS */
884 NULL, /* SIOCGIWSTATS */
885 dummy, /* SIOCSIWSPY */
886 dummy, /* SIOCGIWSPY */
887 NULL, /* SIOCGIWTHRSPY */
888 NULL, /* SIOCWIWTHRSPY */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100889 r8192_wx_set_wap, /* SIOCSIWAP */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200890 r8192_wx_get_wap, /* SIOCGIWAP */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200891 r8192_wx_set_mlme, /* MLME-- */
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700892 dummy, /* SIOCGIWAPLIST -- deprecated */
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200893 r8192_wx_set_scan, /* SIOCSIWSCAN */
894 r8192_wx_get_scan, /* SIOCGIWSCAN */
895 r8192_wx_set_essid, /* SIOCSIWESSID */
896 r8192_wx_get_essid, /* SIOCGIWESSID */
897 dummy, /* SIOCSIWNICKN */
898 dummy, /* SIOCGIWNICKN */
899 NULL, /* -- hole -- */
900 NULL, /* -- hole -- */
901 r8192_wx_set_rate, /* SIOCSIWRATE */
902 r8192_wx_get_rate, /* SIOCGIWRATE */
903 r8192_wx_set_rts, /* SIOCSIWRTS */
904 r8192_wx_get_rts, /* SIOCGIWRTS */
905 r8192_wx_set_frag, /* SIOCSIWFRAG */
906 r8192_wx_get_frag, /* SIOCGIWFRAG */
907 dummy, /* SIOCSIWTXPOW */
908 dummy, /* SIOCGIWTXPOW */
909 r8192_wx_set_retry, /* SIOCSIWRETRY */
910 r8192_wx_get_retry, /* SIOCGIWRETRY */
911 r8192_wx_set_enc, /* SIOCSIWENCODE */
912 r8192_wx_get_enc, /* SIOCGIWENCODE */
913 r8192_wx_set_power, /* SIOCSIWPOWER */
914 r8192_wx_get_power, /* SIOCGIWPOWER */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200915 NULL, /*---hole---*/
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100916 NULL, /*---hole---*/
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700917 r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100918 NULL, /* SIOCSIWGENIE */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200919
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700920 r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
921 NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100922 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700923 NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100924 NULL, /* SIOCSIWPMKSA */
925 NULL, /*---hole---*/
Jerry Chuang8fc85982009-11-03 07:17:11 -0200926
927};
928
929
930static const struct iw_priv_args r8192_private_args[] = {
931
932 {
933 SIOCIWFIRSTPRIV + 0x0,
934 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
935 },
936
937 {
938 SIOCIWFIRSTPRIV + 0x1,
939 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
940
941 },
942 {
943 SIOCIWFIRSTPRIV + 0x2,
944 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
Xenia Ragiadakouaa0cb592013-10-10 10:43:47 +0300945 },
Jerry Chuang8fc85982009-11-03 07:17:11 -0200946 {
947 SIOCIWFIRSTPRIV + 0x3,
948 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
949
950 }
951
952};
953
954
955static iw_handler r8192_private_handler[] = {
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700956 /* r8192_wx_set_monitor, */ /* SIOCIWFIRSTPRIV */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200957 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700958 /* r8192_wx_set_forceassociate, */
959 /* r8192_wx_set_beaconinterval, */
960 /* r8192_wx_set_monitor_type, */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200961 r8192_wx_set_scan_type,
962 r8192_wx_set_rawtx,
Chaitanya Hazarey0bb927c2014-05-29 13:45:19 -0700963 /* r8192_wx_null, */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200964 r8192_wx_force_reset,
965};
966
Jerry Chuang8fc85982009-11-03 07:17:11 -0200967struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
968{
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700969 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub81c2b02013-05-11 17:22:24 +0300970 struct ieee80211_device *ieee = priv->ieee80211;
971 struct iw_statistics *wstats = &priv->wstats;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200972 int tmp_level = 0;
973 int tmp_qual = 0;
974 int tmp_noise = 0;
Chaitanya Hazarey28cda5a2014-05-28 07:32:39 -0700975 if (ieee->state < IEEE80211_LINKED) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200976 wstats->qual.qual = 0;
977 wstats->qual.level = 0;
978 wstats->qual.noise = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200979 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200980 return wstats;
981 }
982
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700983 tmp_level = (&ieee->current_network)->stats.rssi;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200984 tmp_qual = (&ieee->current_network)->stats.signal;
985 tmp_noise = (&ieee->current_network)->stats.noise;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200986
987 wstats->qual.level = tmp_level;
988 wstats->qual.qual = tmp_qual;
989 wstats->qual.noise = tmp_noise;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200990 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200991 return wstats;
992}
Jerry Chuang8fc85982009-11-03 07:17:11 -0200993
994
Chaitanya Hazarey654d1ce2014-05-28 07:32:38 -0700995struct iw_handler_def r8192_wx_handlers_def = {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200996 .standard = r8192_wx_handlers,
Jim Cromieb330f602012-04-10 16:06:41 -0600997 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
Jerry Chuang8fc85982009-11-03 07:17:11 -0200998 .private = r8192_private_handler,
Jim Cromieb330f602012-04-10 16:06:41 -0600999 .num_private = ARRAY_SIZE(r8192_private_handler),
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001000 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
Jerry Chuang8fc85982009-11-03 07:17:11 -02001001 .get_wireless_stats = r8192_get_wireless_stats,
Jerry Chuang8fc85982009-11-03 07:17:11 -02001002 .private_args = (struct iw_priv_args *)r8192_private_args,
1003};