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