1 /******************************************************************************
2  *
3  * This file contains wireless extension handlers.
4  *
5  * This is part of rtl8180 OpenSource driver.
6  * Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
7  * Released under the terms of GPL (General Public Licence)
8  *
9  * Parts of this driver are based on the GPL part
10  * of the official realtek driver.
11  *
12  * Parts of this driver are based on the rtl8180 driver skeleton
13  * from Patric Schenke & Andres Salomon.
14  *
15  * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16  *
17  * We want to thank the Authors of those projects and the Ndiswrapper
18  * project Authors.
19  *
20  *****************************************************************************/
21 
22 #include <linux/string.h>
23 #include "r8192U.h"
24 #include "r8192U_hw.h"
25 
26 #include "dot11d.h"
27 #include "r8192U_wx.h"
28 
29 #define RATE_COUNT 12
30 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
31 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
32 
33 #ifndef ENETDOWN
34 #define ENETDOWN 1
35 #endif
36 
37 static int r8192_wx_get_freq(struct net_device *dev,
38 			     struct iw_request_info *a,
39 			     union iwreq_data *wrqu, char *b)
40 {
41 	struct r8192_priv *priv = ieee80211_priv(dev);
42 
43 	return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
44 }
45 
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 			     union iwreq_data *wrqu, char *b)
48 {
49 	struct r8192_priv *priv = ieee80211_priv(dev);
50 
51 	return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
52 }
53 
54 static int r8192_wx_get_rate(struct net_device *dev,
55 			     struct iw_request_info *info,
56 			     union iwreq_data *wrqu, char *extra)
57 {
58 	struct r8192_priv *priv = ieee80211_priv(dev);
59 
60 	return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
61 }
62 
63 static int r8192_wx_set_rate(struct net_device *dev,
64 			     struct iw_request_info *info,
65 			     union iwreq_data *wrqu, char *extra)
66 {
67 	int ret;
68 	struct r8192_priv *priv = ieee80211_priv(dev);
69 
70 	mutex_lock(&priv->wx_mutex);
71 
72 	ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
73 
74 	mutex_unlock(&priv->wx_mutex);
75 
76 	return ret;
77 }
78 
79 static int r8192_wx_set_rts(struct net_device *dev,
80 			     struct iw_request_info *info,
81 			     union iwreq_data *wrqu, char *extra)
82 {
83 	int ret;
84 	struct r8192_priv *priv = ieee80211_priv(dev);
85 
86 	mutex_lock(&priv->wx_mutex);
87 
88 	ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
89 
90 	mutex_unlock(&priv->wx_mutex);
91 
92 	return ret;
93 }
94 
95 static int r8192_wx_get_rts(struct net_device *dev,
96 			     struct iw_request_info *info,
97 			     union iwreq_data *wrqu, char *extra)
98 {
99 	struct r8192_priv *priv = ieee80211_priv(dev);
100 
101 	return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
102 }
103 
104 static int r8192_wx_set_power(struct net_device *dev,
105 			     struct iw_request_info *info,
106 			     union iwreq_data *wrqu, char *extra)
107 {
108 	int ret;
109 	struct r8192_priv *priv = ieee80211_priv(dev);
110 
111 	mutex_lock(&priv->wx_mutex);
112 
113 	ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
114 
115 	mutex_unlock(&priv->wx_mutex);
116 
117 	return ret;
118 }
119 
120 static int r8192_wx_get_power(struct net_device *dev,
121 			     struct iw_request_info *info,
122 			     union iwreq_data *wrqu, char *extra)
123 {
124 	struct r8192_priv *priv = ieee80211_priv(dev);
125 
126 	return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
127 }
128 
129 static int r8192_wx_force_reset(struct net_device *dev,
130 		struct iw_request_info *info,
131 		union iwreq_data *wrqu, char *extra)
132 {
133 	struct r8192_priv *priv = ieee80211_priv(dev);
134 
135 	mutex_lock(&priv->wx_mutex);
136 
137 	netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra);
138 	priv->force_reset = *extra;
139 	mutex_unlock(&priv->wx_mutex);
140 	return 0;
141 
142 }
143 
144 static int r8192_wx_set_rawtx(struct net_device *dev,
145 			       struct iw_request_info *info,
146 			       union iwreq_data *wrqu, char *extra)
147 {
148 	struct r8192_priv *priv = ieee80211_priv(dev);
149 	int ret;
150 
151 	mutex_lock(&priv->wx_mutex);
152 
153 	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
154 
155 	mutex_unlock(&priv->wx_mutex);
156 
157 	return ret;
158 
159 }
160 
161 static int r8192_wx_set_crcmon(struct net_device *dev,
162 			       struct iw_request_info *info,
163 			       union iwreq_data *wrqu, char *extra)
164 {
165 	struct r8192_priv *priv = ieee80211_priv(dev);
166 	int *parms = (int *)extra;
167 	int enable = (parms[0] > 0);
168 
169 	mutex_lock(&priv->wx_mutex);
170 
171 	if (enable)
172 		priv->crcmon = 1;
173 	else
174 		priv->crcmon = 0;
175 
176 	DMESG("bad CRC in monitor mode are %s",
177 	      priv->crcmon ? "accepted" : "rejected");
178 
179 	mutex_unlock(&priv->wx_mutex);
180 
181 	return 0;
182 }
183 
184 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
185 			     union iwreq_data *wrqu, char *b)
186 {
187 	struct r8192_priv *priv = ieee80211_priv(dev);
188 	int ret;
189 
190 	mutex_lock(&priv->wx_mutex);
191 
192 	ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
193 
194 	rtl8192_set_rxconf(dev);
195 
196 	mutex_unlock(&priv->wx_mutex);
197 	return ret;
198 }
199 
200 struct  iw_range_with_scan_capa {
201 	/* Informative stuff (to choose between different interface) */
202 	__u32           throughput;     /* To give an idea... */
203 	/* In theory this value should be the maximum benchmarked
204 	 * TCP/IP throughput, because with most of these devices the
205 	 * bit rate is meaningless (overhead an co) to estimate how
206 	 * fast the connection will go and pick the fastest one.
207 	 * I suggest people to play with Netperf or any benchmark...
208 	 */
209 
210 	/* NWID (or domain id) */
211 	__u32           min_nwid;       /* Minimal NWID we are able to set */
212 	__u32           max_nwid;       /* Maximal NWID we are able to set */
213 
214 	/* Old Frequency (backward compat - moved lower ) */
215 	__u16           old_num_channels;
216 	__u8            old_num_frequency;
217 
218 	/* Scan capabilities */
219 	__u8            scan_capa;
220 };
221 static int rtl8180_wx_get_range(struct net_device *dev,
222 				struct iw_request_info *info,
223 				union iwreq_data *wrqu, char *extra)
224 {
225 	struct iw_range *range = (struct iw_range *)extra;
226 	struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
227 	struct r8192_priv *priv = ieee80211_priv(dev);
228 	u16 val;
229 	int i;
230 
231 	wrqu->data.length = sizeof(*range);
232 	memset(range, 0, sizeof(*range));
233 
234 	/* Let's try to keep this struct in the same order as in
235 	 * linux/include/wireless.h
236 	 */
237 
238 	/* TODO: See what values we can set, and remove the ones we can't
239 	 * set, or fill them with some default data.
240 	 */
241 
242 	/* ~5 Mb/s real (802.11b) */
243 	range->throughput = 5 * 1000 * 1000;
244 
245 	/* TODO: Not used in 802.11b? */
246 	/* range->min_nwid; */	/* Minimal NWID we are able to set */
247 	/* TODO: Not used in 802.11b? */
248 	/* range->max_nwid; */	/* Maximal NWID we are able to set */
249 
250 	/* Old Frequency (backward compat - moved lower ) */
251 	/* range->old_num_channels; */
252 	/* range->old_num_frequency; */
253 	/* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
254 	if (priv->rf_set_sens != NULL)
255 		range->sensitivity = priv->max_sens;	/* signal level threshold range */
256 
257 	range->max_qual.qual = 100;
258 	/* TODO: Find real max RSSI and stick here */
259 	range->max_qual.level = 0;
260 	range->max_qual.noise = 0x100 - 98;
261 	range->max_qual.updated = 7; /* Updated all three */
262 
263 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
264 	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
265 	range->avg_qual.level = 0x100 - 78;
266 	range->avg_qual.noise = 0;
267 	range->avg_qual.updated = 7; /* Updated all three */
268 
269 	range->num_bitrates = RATE_COUNT;
270 
271 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
272 		range->bitrate[i] = rtl8180_rates[i];
273 
274 	range->min_frag = MIN_FRAG_THRESHOLD;
275 	range->max_frag = MAX_FRAG_THRESHOLD;
276 
277 	range->min_pmp = 0;
278 	range->max_pmp = 5000000;
279 	range->min_pmt = 0;
280 	range->max_pmt = 65535*1000;
281 	range->pmp_flags = IW_POWER_PERIOD;
282 	range->pmt_flags = IW_POWER_TIMEOUT;
283 	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
284 
285 	range->we_version_compiled = WIRELESS_EXT;
286 	range->we_version_source = 16;
287 
288 	/* range->retry_capa; */	/* What retry options are supported */
289 	/* range->retry_flags; */	/* How to decode max/min retry limit */
290 	/* range->r_time_flags; */	/* How to decode max/min retry life */
291 	/* range->min_retry; */		/* Minimal number of retries */
292 	/* range->max_retry; */		/* Maximal number of retries */
293 	/* range->min_r_time; */	/* Minimal retry lifetime */
294 	/* range->max_r_time; */	/* Maximal retry lifetime */
295 
296 	for (i = 0, val = 0; i < 14; i++) {
297 
298 		/* Include only legal frequencies for some countries */
299 		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
300 			range->freq[val].i = i + 1;
301 			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
302 			range->freq[val].e = 1;
303 			val++;
304 		} else {
305 			/* FIXME: do we need to set anything for channels */
306 			/* we don't use ? */
307 		}
308 
309 		if (val == IW_MAX_FREQUENCIES)
310 			break;
311 	}
312 	range->num_frequency = val;
313 	range->num_channels = val;
314 	range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
315 			  IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
316 	tmp->scan_capa = 0x01;
317 	return 0;
318 }
319 
320 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
321 			     union iwreq_data *wrqu, char *b)
322 {
323 	struct r8192_priv *priv = ieee80211_priv(dev);
324 	struct ieee80211_device *ieee = priv->ieee80211;
325 	int ret = 0;
326 
327 	if (!priv->up)
328 		return -ENETDOWN;
329 
330 	if (priv->ieee80211->LinkDetectInfo.bBusyTraffic)
331 		return -EAGAIN;
332 	if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
333 		struct iw_scan_req *req = (struct iw_scan_req *)b;
334 
335 		if (req->essid_len) {
336 			ieee->current_network.ssid_len = req->essid_len;
337 			memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
338 		}
339 	}
340 
341 	mutex_lock(&priv->wx_mutex);
342 	if (priv->ieee80211->state != IEEE80211_LINKED) {
343 		priv->ieee80211->scanning = 0;
344 		ieee80211_softmac_scan_syncro(priv->ieee80211);
345 		ret = 0;
346 	} else {
347 		ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
348 	}
349 	mutex_unlock(&priv->wx_mutex);
350 	return ret;
351 }
352 
353 
354 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
355 			     union iwreq_data *wrqu, char *b)
356 {
357 
358 	int ret;
359 	struct r8192_priv *priv = ieee80211_priv(dev);
360 
361 	if (!priv->up)
362 		return -ENETDOWN;
363 
364 	mutex_lock(&priv->wx_mutex);
365 
366 	ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
367 
368 	mutex_unlock(&priv->wx_mutex);
369 
370 	return ret;
371 }
372 
373 static int r8192_wx_set_essid(struct net_device *dev,
374 			      struct iw_request_info *a,
375 			      union iwreq_data *wrqu, char *b)
376 {
377 	struct r8192_priv *priv = ieee80211_priv(dev);
378 	int ret;
379 
380 	mutex_lock(&priv->wx_mutex);
381 
382 	ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
383 
384 	mutex_unlock(&priv->wx_mutex);
385 
386 	return ret;
387 }
388 
389 static int r8192_wx_get_essid(struct net_device *dev,
390 			      struct iw_request_info *a,
391 			      union iwreq_data *wrqu, char *b)
392 {
393 	int ret;
394 	struct r8192_priv *priv = ieee80211_priv(dev);
395 
396 	mutex_lock(&priv->wx_mutex);
397 
398 	ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
399 
400 	mutex_unlock(&priv->wx_mutex);
401 
402 	return ret;
403 }
404 
405 static int r8192_wx_set_freq(struct net_device *dev, 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 	mutex_lock(&priv->wx_mutex);
412 
413 	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
414 
415 	mutex_unlock(&priv->wx_mutex);
416 	return ret;
417 }
418 
419 static int r8192_wx_get_name(struct net_device *dev,
420 			     struct iw_request_info *info,
421 			     union iwreq_data *wrqu, char *extra)
422 {
423 	struct r8192_priv *priv = ieee80211_priv(dev);
424 
425 	return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
426 }
427 
428 static int r8192_wx_set_frag(struct net_device *dev,
429 			     struct iw_request_info *info,
430 			     union iwreq_data *wrqu, char *extra)
431 {
432 	struct r8192_priv *priv = ieee80211_priv(dev);
433 
434 	if (wrqu->frag.disabled)
435 		priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
436 	else {
437 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
438 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
439 			return -EINVAL;
440 
441 		priv->ieee80211->fts = wrqu->frag.value & ~0x1;
442 	}
443 
444 	return 0;
445 }
446 
447 
448 static int r8192_wx_get_frag(struct net_device *dev,
449 			     struct iw_request_info *info,
450 			     union iwreq_data *wrqu, char *extra)
451 {
452 	struct r8192_priv *priv = ieee80211_priv(dev);
453 
454 	wrqu->frag.value = priv->ieee80211->fts;
455 	wrqu->frag.fixed = 0;	/* no auto select */
456 	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
457 
458 	return 0;
459 }
460 
461 
462 static int r8192_wx_set_wap(struct net_device *dev,
463 			 struct iw_request_info *info,
464 			 union iwreq_data *awrq,
465 			 char *extra)
466 {
467 
468 	int ret;
469 	struct r8192_priv *priv = ieee80211_priv(dev);
470 	/* struct sockaddr *temp = (struct sockaddr *)awrq; */
471 	mutex_lock(&priv->wx_mutex);
472 
473 	ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
474 
475 	mutex_unlock(&priv->wx_mutex);
476 
477 	return ret;
478 
479 }
480 
481 static int r8192_wx_get_wap(struct net_device *dev,
482 			    struct iw_request_info *info,
483 			    union iwreq_data *wrqu, char *extra)
484 {
485 	struct r8192_priv *priv = ieee80211_priv(dev);
486 
487 	return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
488 }
489 
490 static int r8192_wx_get_enc(struct net_device *dev,
491 			    struct iw_request_info *info,
492 			    union iwreq_data *wrqu, char *key)
493 {
494 	struct r8192_priv *priv = ieee80211_priv(dev);
495 
496 	return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
497 }
498 
499 static int r8192_wx_set_enc(struct net_device *dev,
500 			    struct iw_request_info *info,
501 			    union iwreq_data *wrqu, char *key)
502 {
503 	struct r8192_priv *priv = ieee80211_priv(dev);
504 	struct ieee80211_device *ieee = priv->ieee80211;
505 	int ret;
506 	u32 hwkey[4] = {0, 0, 0, 0};
507 	u8 mask = 0xff;
508 	u32 key_idx = 0;
509 	u8 zero_addr[4][6] = {	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
510 				{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
511 				{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
512 				{0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
513 	int i;
514 
515 	if (!priv->up)
516 		return -ENETDOWN;
517 
518 	mutex_lock(&priv->wx_mutex);
519 
520 	RT_TRACE(COMP_SEC, "Setting SW wep key");
521 	ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
522 
523 	mutex_unlock(&priv->wx_mutex);
524 
525 
526 
527 	/* sometimes, the length is zero while we do not type key value */
528 	if (wrqu->encoding.length != 0) {
529 
530 		for (i = 0; i < 4; i++) {
531 			hwkey[i] |=  key[4*i+0]&mask;
532 			if (i == 1 && (4*i+1) == wrqu->encoding.length)
533 				mask = 0x00;
534 			if (i == 3 && (4*i+1) == wrqu->encoding.length)
535 				mask = 0x00;
536 			hwkey[i] |= (key[4*i+1]&mask)<<8;
537 			hwkey[i] |= (key[4*i+2]&mask)<<16;
538 			hwkey[i] |= (key[4*i+3]&mask)<<24;
539 		}
540 
541 		#define CONF_WEP40  0x4
542 		#define CONF_WEP104 0x14
543 
544 		switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
545 		case 0:
546 			key_idx = ieee->tx_keyidx;
547 			break;
548 		case 1:
549 			key_idx = 0;
550 			break;
551 		case 2:
552 			key_idx = 1;
553 			break;
554 		case 3:
555 			key_idx = 2;
556 			break;
557 		case 4:
558 			key_idx	= 3;
559 			break;
560 		default:
561 			break;
562 		}
563 
564 		if (wrqu->encoding.length == 0x5) {
565 			ieee->pairwise_key_type = KEY_TYPE_WEP40;
566 			EnableHWSecurityConfig8192(dev);
567 
568 			setKey(dev,
569 				key_idx,                /* EntryNo */
570 				key_idx,                /* KeyIndex */
571 				KEY_TYPE_WEP40,         /* KeyType */
572 				zero_addr[key_idx],
573 				0,                      /* DefaultKey */
574 				hwkey);                 /* KeyContent */
575 
576 		}
577 
578 		else if (wrqu->encoding.length == 0xd) {
579 			ieee->pairwise_key_type = KEY_TYPE_WEP104;
580 			EnableHWSecurityConfig8192(dev);
581 
582 			setKey(dev,
583 				key_idx,                /* EntryNo */
584 				key_idx,                /* KeyIndex */
585 				KEY_TYPE_WEP104,        /* KeyType */
586 				zero_addr[key_idx],
587 				0,                      /* DefaultKey */
588 				hwkey);                 /* KeyContent */
589 
590 		} else {
591 			printk("wrong type in WEP, not WEP40 and WEP104\n");
592 		}
593 
594 	}
595 
596 	return ret;
597 }
598 
599 
600 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
601 					union iwreq_data *wrqu, char *p)
602 {
603 
604 	struct r8192_priv *priv = ieee80211_priv(dev);
605 	int *parms = (int *)p;
606 	int mode = parms[0];
607 
608 	priv->ieee80211->active_scan = mode;
609 
610 	return 1;
611 }
612 
613 
614 
615 static int r8192_wx_set_retry(struct net_device *dev,
616 				struct iw_request_info *info,
617 				union iwreq_data *wrqu, char *extra)
618 {
619 	struct r8192_priv *priv = ieee80211_priv(dev);
620 	int err = 0;
621 
622 	mutex_lock(&priv->wx_mutex);
623 
624 	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
625 	    wrqu->retry.disabled){
626 		err = -EINVAL;
627 		goto exit;
628 	}
629 	if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
630 		err = -EINVAL;
631 		goto exit;
632 	}
633 
634 	if (wrqu->retry.value > R8180_MAX_RETRY) {
635 		err = -EINVAL;
636 		goto exit;
637 	}
638 	if (wrqu->retry.flags & IW_RETRY_MAX) {
639 		priv->retry_rts = wrqu->retry.value;
640 		DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
641 
642 	} else {
643 		priv->retry_data = wrqu->retry.value;
644 		DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
645 	}
646 
647 	/* FIXME !
648 	 * We might try to write directly the TX config register
649 	 * or to restart just the (R)TX process.
650 	 * I'm unsure if whole reset is really needed
651 	 */
652 
653 	rtl8192_commit(dev);
654 exit:
655 	mutex_unlock(&priv->wx_mutex);
656 
657 	return err;
658 }
659 
660 static int r8192_wx_get_retry(struct net_device *dev,
661 				struct iw_request_info *info,
662 				union iwreq_data *wrqu, char *extra)
663 {
664 	struct r8192_priv *priv = ieee80211_priv(dev);
665 
666 
667 	wrqu->retry.disabled = 0; /* can't be disabled */
668 
669 	if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
670 	    IW_RETRY_LIFETIME)
671 		return -EINVAL;
672 
673 	if (wrqu->retry.flags & IW_RETRY_MAX) {
674 		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
675 		wrqu->retry.value = priv->retry_rts;
676 	} else {
677 		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
678 		wrqu->retry.value = priv->retry_data;
679 	}
680 
681 	return 0;
682 }
683 
684 static int r8192_wx_get_sens(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 	if (priv->rf_set_sens == NULL)
691 		return -1; /* we have not this support for this radio */
692 	wrqu->sens.value = priv->sens;
693 	return 0;
694 }
695 
696 static int r8192_wx_set_sens(struct net_device *dev,
697 				struct iw_request_info *info,
698 				union iwreq_data *wrqu, char *extra)
699 {
700 
701 	struct r8192_priv *priv = ieee80211_priv(dev);
702 	short err = 0;
703 
704 	mutex_lock(&priv->wx_mutex);
705 	if (priv->rf_set_sens == NULL) {
706 		err = -1; /* we have not this support for this radio */
707 		goto exit;
708 	}
709 	if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
710 		priv->sens = wrqu->sens.value;
711 	else
712 		err = -EINVAL;
713 
714 exit:
715 	mutex_unlock(&priv->wx_mutex);
716 
717 	return err;
718 }
719 
720 /* hw security need to reorganized. */
721 static int r8192_wx_set_enc_ext(struct net_device *dev,
722 					struct iw_request_info *info,
723 					union iwreq_data *wrqu, char *extra)
724 {
725 	int ret = 0;
726 	struct r8192_priv *priv = ieee80211_priv(dev);
727 	struct ieee80211_device *ieee = priv->ieee80211;
728 
729 
730 	mutex_lock(&priv->wx_mutex);
731 	ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
732 
733 	{
734 		u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
735 		u8 zero[6] = {0};
736 		u32 key[4] = {0};
737 		struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
738 		struct iw_point *encoding = &wrqu->encoding;
739 		u8 idx = 0, alg = 0, group = 0;
740 
741 		if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
742 			/* none is not allowed to use hwsec WB 2008.07.01 */
743 			goto end_hw_sec;
744 
745 		/* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
746 		alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
747 		idx = encoding->flags & IW_ENCODE_INDEX;
748 		if (idx)
749 			idx--;
750 		group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
751 
752 		if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40)) {
753 			if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
754 				alg = KEY_TYPE_WEP104;
755 			ieee->pairwise_key_type = alg;
756 			EnableHWSecurityConfig8192(dev);
757 		}
758 		memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
759 
760 		if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
761 
762 			setKey(dev,
763 					idx,	/* EntryNao */
764 					idx,	/* KeyIndex */
765 					alg,	/* KeyType */
766 					zero,	/* MacAddr */
767 					0,	/* DefaultKey */
768 					key);	/* KeyContent */
769 		} else if (group) {
770 			ieee->group_key_type = alg;
771 			setKey(dev,
772 					idx,	/* EntryNo */
773 					idx,	/* KeyIndex */
774 					alg,	/* KeyType */
775 					broadcast_addr,	/* MacAddr */
776 					0,		/* DefaultKey */
777 					key);		/* KeyContent */
778 		} else {	/* pairwise key */
779 			setKey(dev,
780 					4,	/* EntryNo */
781 					idx,	/* KeyIndex */
782 					alg,	/* KeyType */
783 					(u8 *)ieee->ap_mac_addr,/* MacAddr */
784 					0,			/* DefaultKey */
785 					key);			/* KeyContent */
786 		}
787 
788 
789 	}
790 
791 end_hw_sec:
792 
793 	mutex_unlock(&priv->wx_mutex);
794 	return ret;
795 
796 }
797 static int r8192_wx_set_auth(struct net_device *dev,
798 					struct iw_request_info *info,
799 					union iwreq_data *data, char *extra)
800 {
801 	int ret = 0;
802 	struct r8192_priv *priv = ieee80211_priv(dev);
803 
804 	mutex_lock(&priv->wx_mutex);
805 	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
806 	mutex_unlock(&priv->wx_mutex);
807 	return ret;
808 }
809 
810 static int r8192_wx_set_mlme(struct net_device *dev,
811 					struct iw_request_info *info,
812 					union iwreq_data *wrqu, char *extra)
813 {
814 
815 	int ret = 0;
816 	struct r8192_priv *priv = ieee80211_priv(dev);
817 
818 	mutex_lock(&priv->wx_mutex);
819 	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
820 
821 	mutex_unlock(&priv->wx_mutex);
822 	return ret;
823 }
824 
825 static int r8192_wx_set_gen_ie(struct net_device *dev,
826 					struct iw_request_info *info,
827 					union iwreq_data *data, char *extra)
828 {
829 	int ret = 0;
830 	struct r8192_priv *priv = ieee80211_priv(dev);
831 
832 	mutex_lock(&priv->wx_mutex);
833 	ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
834 	mutex_unlock(&priv->wx_mutex);
835 	return ret;
836 
837 
838 }
839 
840 static int dummy(struct net_device *dev, struct iw_request_info *a,
841 		 union iwreq_data *wrqu, char *b)
842 {
843 	return -1;
844 }
845 
846 static iw_handler r8192_wx_handlers[] = {
847 	NULL,                     /* SIOCSIWCOMMIT */
848 	r8192_wx_get_name,	  /* SIOCGIWNAME */
849 	dummy,                    /* SIOCSIWNWID */
850 	dummy,                    /* SIOCGIWNWID */
851 	r8192_wx_set_freq,        /* SIOCSIWFREQ */
852 	r8192_wx_get_freq,        /* SIOCGIWFREQ */
853 	r8192_wx_set_mode,        /* SIOCSIWMODE */
854 	r8192_wx_get_mode,        /* SIOCGIWMODE */
855 	r8192_wx_set_sens,        /* SIOCSIWSENS */
856 	r8192_wx_get_sens,        /* SIOCGIWSENS */
857 	NULL,                     /* SIOCSIWRANGE */
858 	rtl8180_wx_get_range,	  /* SIOCGIWRANGE */
859 	NULL,                     /* SIOCSIWPRIV */
860 	NULL,                     /* SIOCGIWPRIV */
861 	NULL,                     /* SIOCSIWSTATS */
862 	NULL,                     /* SIOCGIWSTATS */
863 	dummy,                    /* SIOCSIWSPY */
864 	dummy,                    /* SIOCGIWSPY */
865 	NULL,                     /* SIOCGIWTHRSPY */
866 	NULL,                     /* SIOCWIWTHRSPY */
867 	r8192_wx_set_wap,	  /* SIOCSIWAP */
868 	r8192_wx_get_wap,         /* SIOCGIWAP */
869 	r8192_wx_set_mlme,                     /* MLME-- */
870 	dummy,                     /* SIOCGIWAPLIST -- deprecated */
871 	r8192_wx_set_scan,        /* SIOCSIWSCAN */
872 	r8192_wx_get_scan,        /* SIOCGIWSCAN */
873 	r8192_wx_set_essid,       /* SIOCSIWESSID */
874 	r8192_wx_get_essid,       /* SIOCGIWESSID */
875 	dummy,                    /* SIOCSIWNICKN */
876 	dummy,                    /* SIOCGIWNICKN */
877 	NULL,                     /* -- hole -- */
878 	NULL,                     /* -- hole -- */
879 	r8192_wx_set_rate,        /* SIOCSIWRATE */
880 	r8192_wx_get_rate,        /* SIOCGIWRATE */
881 	r8192_wx_set_rts,                    /* SIOCSIWRTS */
882 	r8192_wx_get_rts,                    /* SIOCGIWRTS */
883 	r8192_wx_set_frag,        /* SIOCSIWFRAG */
884 	r8192_wx_get_frag,        /* SIOCGIWFRAG */
885 	dummy,                    /* SIOCSIWTXPOW */
886 	dummy,                    /* SIOCGIWTXPOW */
887 	r8192_wx_set_retry,       /* SIOCSIWRETRY */
888 	r8192_wx_get_retry,       /* SIOCGIWRETRY */
889 	r8192_wx_set_enc,         /* SIOCSIWENCODE */
890 	r8192_wx_get_enc,         /* SIOCGIWENCODE */
891 	r8192_wx_set_power,                    /* SIOCSIWPOWER */
892 	r8192_wx_get_power,                    /* SIOCGIWPOWER */
893 	NULL,			/*---hole---*/
894 	NULL,			/*---hole---*/
895 	r8192_wx_set_gen_ie, /* NULL, */		/* SIOCSIWGENIE */
896 	NULL,			/* SIOCSIWGENIE */
897 
898 	r8192_wx_set_auth,/* NULL, */			/* SIOCSIWAUTH */
899 	NULL,/* r8192_wx_get_auth, */ /* NULL, */	/* SIOCSIWAUTH */
900 	r8192_wx_set_enc_ext,			/* SIOCSIWENCODEEXT */
901 	NULL,/* r8192_wx_get_enc_ext, *//* NULL, */			/* SIOCSIWENCODEEXT */
902 	NULL,			/* SIOCSIWPMKSA */
903 	NULL,			 /*---hole---*/
904 
905 };
906 
907 
908 static const struct iw_priv_args r8192_private_args[] = {
909 
910 	{
911 		SIOCIWFIRSTPRIV + 0x0,
912 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
913 	},
914 
915 	{
916 		SIOCIWFIRSTPRIV + 0x1,
917 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
918 
919 	},
920 	{
921 		SIOCIWFIRSTPRIV + 0x2,
922 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
923 	},
924 	{
925 		SIOCIWFIRSTPRIV + 0x3,
926 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
927 
928 	}
929 
930 };
931 
932 static iw_handler r8192_private_handler[] = {
933 	r8192_wx_set_crcmon,
934 	r8192_wx_set_scan_type,
935 	r8192_wx_set_rawtx,
936 	r8192_wx_force_reset,
937 };
938 
939 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
940 {
941 	struct r8192_priv *priv = ieee80211_priv(dev);
942 	struct ieee80211_device *ieee = priv->ieee80211;
943 	struct iw_statistics *wstats = &priv->wstats;
944 	int tmp_level = 0;
945 	int tmp_qual = 0;
946 	int tmp_noise = 0;
947 
948 	if (ieee->state < IEEE80211_LINKED) {
949 		wstats->qual.qual = 0;
950 		wstats->qual.level = 0;
951 		wstats->qual.noise = 0;
952 		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
953 		return wstats;
954 	}
955 
956 	tmp_level = (&ieee->current_network)->stats.rssi;
957 	tmp_qual = (&ieee->current_network)->stats.signal;
958 	tmp_noise = (&ieee->current_network)->stats.noise;
959 
960 	wstats->qual.level = tmp_level;
961 	wstats->qual.qual = tmp_qual;
962 	wstats->qual.noise = tmp_noise;
963 	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
964 	return wstats;
965 }
966 
967 struct iw_handler_def  r8192_wx_handlers_def = {
968 	.standard = r8192_wx_handlers,
969 	.num_standard = ARRAY_SIZE(r8192_wx_handlers),
970 	.private = r8192_private_handler,
971 	.num_private = ARRAY_SIZE(r8192_private_handler),
972 	.num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
973 	.get_wireless_stats = r8192_get_wireless_stats,
974 	.private_args = (struct iw_priv_args *)r8192_private_args,
975 };
976