• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 thanks the Authors of those projects and the Ndiswrapper
17 	project Authors.
18 */
19 
20 
21 #include "r8180.h"
22 #include "r8180_hw.h"
23 
24 #include "ieee80211/dot11d.h"
25 
26 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
27 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
28 
29 #define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
30 
31 static CHANNEL_LIST DefaultChannelPlan[] = {
32 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},		/* FCC */
33 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},						/* IC */
34 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* ETSI	*/
35 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* Spain. Change to ETSI. */
36 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* France. Change to ETSI. */
37 	{{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},						/* MKK */
38 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},	/* MKK1	*/
39 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* Israel */
40 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},			/* For 11a , TELEC */
41 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}					/* For Global Domain. 1-11:active scan, 12-14 passive scan.*/	/* +YJ, 080626 */
42 };
r8180_wx_get_freq(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)43 static int r8180_wx_get_freq(struct net_device *dev,
44 			     struct iw_request_info *a,
45 			     union iwreq_data *wrqu, char *b)
46 {
47 	struct r8180_priv *priv = ieee80211_priv(dev);
48 
49 	return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
50 }
51 
52 
r8180_wx_set_key(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * key)53 int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
54 		     union iwreq_data *wrqu, char *key)
55 {
56 	struct r8180_priv *priv = ieee80211_priv(dev);
57 	struct iw_point *erq = &(wrqu->encoding);
58 
59 	if (priv->ieee80211->bHwRadioOff)
60 		return 0;
61 
62 	if (erq->length > 0) {
63 		u32* tkey = (u32*) key;
64 		priv->key0[0] = tkey[0];
65 		priv->key0[1] = tkey[1];
66 		priv->key0[2] = tkey[2];
67 		priv->key0[3] = tkey[3] & 0xff;
68 		DMESG("Setting wep key to %x %x %x %x",
69 		      tkey[0], tkey[1], tkey[2], tkey[3]);
70 		rtl8180_set_hw_wep(dev);
71 	}
72 	return 0;
73 }
74 
75 
r8180_wx_set_beaconinterval(struct net_device * dev,struct iw_request_info * aa,union iwreq_data * wrqu,char * b)76 static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
77 			  union iwreq_data *wrqu, char *b)
78 {
79 	int *parms = (int *)b;
80 	int bi = parms[0];
81 
82 	struct r8180_priv *priv = ieee80211_priv(dev);
83 
84 	if (priv->ieee80211->bHwRadioOff)
85 		return 0;
86 
87 	down(&priv->wx_sem);
88 	DMESG("setting beacon interval to %x", bi);
89 
90 	priv->ieee80211->current_network.beacon_interval = bi;
91 	rtl8180_commit(dev);
92 	up(&priv->wx_sem);
93 
94 	return 0;
95 }
96 
97 
98 
r8180_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)99 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
100 			     union iwreq_data *wrqu, char *b)
101 {
102 	struct r8180_priv *priv = ieee80211_priv(dev);
103 	return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
104 }
105 
106 
107 
r8180_wx_get_rate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)108 static int r8180_wx_get_rate(struct net_device *dev,
109 			     struct iw_request_info *info,
110 			     union iwreq_data *wrqu, char *extra)
111 {
112 	struct r8180_priv *priv = ieee80211_priv(dev);
113 	return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
114 }
115 
116 
117 
r8180_wx_set_rate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)118 static int r8180_wx_set_rate(struct net_device *dev,
119 			     struct iw_request_info *info,
120 			     union iwreq_data *wrqu, char *extra)
121 {
122 	int ret;
123 	struct r8180_priv *priv = ieee80211_priv(dev);
124 
125 
126 	if (priv->ieee80211->bHwRadioOff)
127 		return 0;
128 
129 	down(&priv->wx_sem);
130 
131 	ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
132 
133 	up(&priv->wx_sem);
134 
135 	return ret;
136 }
137 
138 
r8180_wx_set_crcmon(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)139 static int r8180_wx_set_crcmon(struct net_device *dev,
140 			       struct iw_request_info *info,
141 			       union iwreq_data *wrqu, char *extra)
142 {
143 	struct r8180_priv *priv = ieee80211_priv(dev);
144 	int *parms = (int *)extra;
145 	int enable = (parms[0] > 0);
146 	short prev = priv->crcmon;
147 
148 
149 	if (priv->ieee80211->bHwRadioOff)
150 		return 0;
151 
152 	down(&priv->wx_sem);
153 
154 	if (enable)
155 		priv->crcmon = 1;
156 	else
157 		priv->crcmon = 0;
158 
159 	DMESG("bad CRC in monitor mode are %s",
160 	      priv->crcmon ? "accepted" : "rejected");
161 
162 	if (prev != priv->crcmon && priv->up)	{
163 		rtl8180_down(dev);
164 		rtl8180_up(dev);
165 	}
166 
167 	up(&priv->wx_sem);
168 
169 	return 0;
170 }
171 
172 
r8180_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)173 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
174 			     union iwreq_data *wrqu, char *b)
175 {
176 	struct r8180_priv *priv = ieee80211_priv(dev);
177 	int ret;
178 
179 
180 	if (priv->ieee80211->bHwRadioOff)
181 		return 0;
182 
183 	down(&priv->wx_sem);
184 	if (priv->bInactivePs)	{
185 		if (wrqu->mode == IW_MODE_ADHOC)
186 			IPSLeave(dev);
187 	}
188 	ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
189 
190 	up(&priv->wx_sem);
191 	return ret;
192 }
193 
194 /* YJ,add,080819,for hidden ap */
195 struct  iw_range_with_scan_capa	{
196 		/* Informative stuff (to choose between different interface) */
197 
198 		__u32		throughput; /* To give an idea... */
199 
200 		/* In theory this value should be the maximum benchmarked
201 		 * TCP/IP throughput, because with most of these devices the
202 		 * bit rate is meaningless (overhead an co) to estimate how
203 		 * fast the connection will go and pick the fastest one.
204 		 * I suggest people to play with Netperf or any benchmark...
205 		 */
206 
207 		/* NWID (or domain id)	*/
208 		__u32           min_nwid; /* Minimal NWID we are able to set */
209 		__u32			max_nwid; /* Maximal NWID we are able to set */
210 
211 		/* Old Frequency (backward compat - moved lower ) */
212 		__u16			old_num_channels;
213 		__u8			old_num_frequency;
214 
215 		/* Scan capabilities */
216 		__u8			scan_capa;
217 };
218 /* YJ,add,080819,for hidden ap */
219 
220 
rtl8180_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)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 r8180_priv *priv = ieee80211_priv(dev);
227 	u16 val;
228 	int i;
229 
230 	wrqu->data.length = sizeof(*range);
231 	memset(range, 0, sizeof(*range));
232 
233 	/* Let's try to keep this struct in the same order as in
234 	 * linux/include/wireless.h
235 	 */
236 
237 	/* TODO: See what values we can set, and remove the ones we can't
238 	 * set, or fill them with some default data.
239 	 */
240 
241 	/* ~5 Mb/s real (802.11b) */
242 	range->throughput = 5 * 1000 * 1000;
243 
244 	/* TODO: Not used in 802.11b?	*/
245 /*	range->min_nwid; */	/* Minimal NWID we are able to set */
246 	/* TODO: Not used in 802.11b?	*/
247 /*	range->max_nwid; */	/* Maximal NWID we are able to set */
248 
249 		/* Old Frequency (backward compat - moved lower ) */
250 /*	range->old_num_channels; */
251 /*	range->old_num_frequency; */
252 /*	range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
253 	if (priv->rf_set_sens != NULL)
254 		range->sensitivity = priv->max_sens;	/* signal level threshold range */
255 
256 	range->max_qual.qual = 100;
257 	/* TODO: Find real max RSSI and stick here */
258 	range->max_qual.level = 0;
259 	range->max_qual.noise = -98;
260 	range->max_qual.updated = 7; /* Updated all three */
261 
262 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
263 	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
264 	range->avg_qual.level = 20 + -98;
265 	range->avg_qual.noise = 0;
266 	range->avg_qual.updated = 7; /* Updated all three */
267 
268 	range->num_bitrates = RATE_COUNT;
269 
270 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
271 		range->bitrate[i] = rtl8180_rates[i];
272 
273 	range->min_frag = MIN_FRAG_THRESHOLD;
274 	range->max_frag = MAX_FRAG_THRESHOLD;
275 
276 	range->pm_capa = 0;
277 
278 	range->we_version_compiled = WIRELESS_EXT;
279 	range->we_version_source = 16;
280 
281 		range->num_channels = 14;
282 
283 	for (i = 0, val = 0; i < 14; i++) {
284 
285 		/* Include only legal frequencies for some countries */
286 		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
287 				range->freq[val].i = i + 1;
288 			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
289 			range->freq[val].e = 1;
290 			val++;
291 		} else {
292 			/* FIXME: do we need to set anything for channels */
293 			/* we don't use ? */
294 		}
295 
296 		if (val == IW_MAX_FREQUENCIES)
297 		break;
298 	}
299 
300 	range->num_frequency = val;
301 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
302 						IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
303 
304 	return 0;
305 }
306 
307 
r8180_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)308 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
309 			     union iwreq_data *wrqu, char *b)
310 {
311 	struct r8180_priv *priv = ieee80211_priv(dev);
312 	int ret;
313 	struct ieee80211_device* ieee = priv->ieee80211;
314 
315 
316 	if (priv->ieee80211->bHwRadioOff)
317 		return 0;
318 
319 	if (wrqu->data.flags & IW_SCAN_THIS_ESSID)	{
320 		struct iw_scan_req* req = (struct iw_scan_req*)b;
321 		if (req->essid_len)		{
322 			ieee->current_network.ssid_len = req->essid_len;
323 			memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
324 		}
325 	}
326 
327 	down(&priv->wx_sem);
328 	if (priv->up)	{
329 		priv->ieee80211->actscanning = true;
330 		if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED))	{
331 			IPSLeave(dev);
332 		ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
333 			ret = 0;
334 		}	else	{
335 			/* prevent scan in BusyTraffic */
336 			/* FIXME: Need to consider last scan time */
337 			if ((priv->link_detect.bBusyTraffic) && (true))	{
338 				ret = 0;
339 				printk("Now traffic is busy, please try later!\n");
340 			}	else
341 				/* prevent scan in BusyTraffic,end */
342 				ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
343 		}
344 	}	else
345 			ret = -1;
346 
347 	up(&priv->wx_sem);
348 
349 	return ret;
350 }
351 
352 
r8180_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)353 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
354 			     union iwreq_data *wrqu, char *b)
355 {
356 
357 	int ret;
358 	struct r8180_priv *priv = ieee80211_priv(dev);
359 
360 	down(&priv->wx_sem);
361 	if (priv->up)
362 		ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
363 	else
364 		ret = -1;
365 
366 	up(&priv->wx_sem);
367 	return ret;
368 }
369 
370 
r8180_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)371 static int r8180_wx_set_essid(struct net_device *dev,
372 			      struct iw_request_info *a,
373 			      union iwreq_data *wrqu, char *b)
374 {
375 	struct r8180_priv *priv = ieee80211_priv(dev);
376 
377 	int ret;
378 
379 	if (priv->ieee80211->bHwRadioOff)
380 		return 0;
381 
382 	down(&priv->wx_sem);
383 	if (priv->bInactivePs)
384 		IPSLeave(dev);
385 
386 	ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
387 
388 	up(&priv->wx_sem);
389 	return ret;
390 }
391 
392 
r8180_wx_get_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)393 static int r8180_wx_get_essid(struct net_device *dev,
394 			      struct iw_request_info *a,
395 			      union iwreq_data *wrqu, char *b)
396 {
397 	int ret;
398 	struct r8180_priv *priv = ieee80211_priv(dev);
399 
400 	down(&priv->wx_sem);
401 
402 	ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
403 
404 	up(&priv->wx_sem);
405 
406 	return ret;
407 }
408 
409 
r8180_wx_set_freq(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)410 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
411 			     union iwreq_data *wrqu, char *b)
412 {
413 	int ret;
414 	struct r8180_priv *priv = ieee80211_priv(dev);
415 
416 
417 	if (priv->ieee80211->bHwRadioOff)
418 		return 0;
419 
420 	down(&priv->wx_sem);
421 
422 	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
423 
424 	up(&priv->wx_sem);
425 	return ret;
426 }
427 
428 
r8180_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)429 static int r8180_wx_get_name(struct net_device *dev,
430 			     struct iw_request_info *info,
431 			     union iwreq_data *wrqu, char *extra)
432 {
433 	struct r8180_priv *priv = ieee80211_priv(dev);
434 	return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
435 }
436 
r8180_wx_set_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)437 static int r8180_wx_set_frag(struct net_device *dev,
438 			     struct iw_request_info *info,
439 			     union iwreq_data *wrqu, char *extra)
440 {
441 	struct r8180_priv *priv = ieee80211_priv(dev);
442 
443 	if (priv->ieee80211->bHwRadioOff)
444 		return 0;
445 
446 	if (wrqu->frag.disabled)
447 		priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
448 	else {
449 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
450 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
451 			return -EINVAL;
452 
453 		priv->ieee80211->fts = wrqu->frag.value & ~0x1;
454 	}
455 
456 	return 0;
457 }
458 
459 
r8180_wx_get_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)460 static int r8180_wx_get_frag(struct net_device *dev,
461 			     struct iw_request_info *info,
462 			     union iwreq_data *wrqu, char *extra)
463 {
464 	struct r8180_priv *priv = ieee80211_priv(dev);
465 
466 	wrqu->frag.value = priv->ieee80211->fts;
467 	wrqu->frag.fixed = 0;	/* no auto select */
468 	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
469 
470 	return 0;
471 }
472 
473 
r8180_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)474 static int r8180_wx_set_wap(struct net_device *dev,
475 			 struct iw_request_info *info,
476 			 union iwreq_data *awrq,
477 			 char *extra)
478 {
479 	int ret;
480 	struct r8180_priv *priv = ieee80211_priv(dev);
481 
482 	if (priv->ieee80211->bHwRadioOff)
483 		return 0;
484 
485 	down(&priv->wx_sem);
486 
487 	ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
488 
489 	up(&priv->wx_sem);
490 	return ret;
491 
492 }
493 
494 
r8180_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)495 static int r8180_wx_get_wap(struct net_device *dev,
496 			    struct iw_request_info *info,
497 			    union iwreq_data *wrqu, char *extra)
498 {
499 	struct r8180_priv *priv = ieee80211_priv(dev);
500 
501 	return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
502 }
503 
504 
r8180_wx_set_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * key)505 static int r8180_wx_set_enc(struct net_device *dev,
506 			    struct iw_request_info *info,
507 			    union iwreq_data *wrqu, char *key)
508 {
509 	struct r8180_priv *priv = ieee80211_priv(dev);
510 	int ret;
511 
512 	if (priv->ieee80211->bHwRadioOff)
513 		return 0;
514 
515 
516 	down(&priv->wx_sem);
517 
518 	if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key);
519 	else	{
520 		DMESG("Setting SW wep key");
521 		ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
522 	}
523 
524 	up(&priv->wx_sem);
525 	return ret;
526 }
527 
528 
r8180_wx_get_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * key)529 static int r8180_wx_get_enc(struct net_device *dev,
530 			    struct iw_request_info *info,
531 			    union iwreq_data *wrqu, char *key)
532 {
533 	struct r8180_priv *priv = ieee80211_priv(dev);
534 
535 	return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
536 }
537 
538 
r8180_wx_set_scan_type(struct net_device * dev,struct iw_request_info * aa,union iwreq_data * wrqu,char * p)539 static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
540 	iwreq_data *wrqu, char *p)	{
541 
542 	struct r8180_priv *priv = ieee80211_priv(dev);
543 	int *parms = (int*)p;
544 	int mode = parms[0];
545 
546 	if (priv->ieee80211->bHwRadioOff)
547 		return 0;
548 
549 	priv->ieee80211->active_scan = mode;
550 
551 	return 1;
552 }
553 
r8180_wx_set_retry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)554 static int r8180_wx_set_retry(struct net_device *dev,
555 				struct iw_request_info *info,
556 				union iwreq_data *wrqu, char *extra)
557 {
558 	struct r8180_priv *priv = ieee80211_priv(dev);
559 	int err = 0;
560 
561 	if (priv->ieee80211->bHwRadioOff)
562 		return 0;
563 
564 	down(&priv->wx_sem);
565 
566 	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
567 	    wrqu->retry.disabled)	{
568 		err = -EINVAL;
569 		goto exit;
570 	}
571 	if (!(wrqu->retry.flags & IW_RETRY_LIMIT))	{
572 		err = -EINVAL;
573 		goto exit;
574 	}
575 
576 	if (wrqu->retry.value > R8180_MAX_RETRY)	{
577 		err = -EINVAL;
578 		goto exit;
579 	}
580 	if (wrqu->retry.flags & IW_RETRY_MAX) {
581 		priv->retry_rts = wrqu->retry.value;
582 		DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
583 
584 	}	else {
585 		priv->retry_data = wrqu->retry.value;
586 		DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
587 	}
588 
589 	/* FIXME !
590 	 * We might try to write directly the TX config register
591 	 * or to restart just the (R)TX process.
592 	 * I'm unsure if whole reset is really needed
593 	 */
594 
595 	rtl8180_commit(dev);
596 exit:
597 	up(&priv->wx_sem);
598 
599 	return err;
600 }
601 
r8180_wx_get_retry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)602 static int r8180_wx_get_retry(struct net_device *dev,
603 				struct iw_request_info *info,
604 				union iwreq_data *wrqu, char *extra)
605 {
606 	struct r8180_priv *priv = ieee80211_priv(dev);
607 
608 
609 	wrqu->retry.disabled = 0; /* can't be disabled */
610 
611 	if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
612 	    IW_RETRY_LIFETIME)
613 		return -EINVAL;
614 
615 	if (wrqu->retry.flags & IW_RETRY_MAX) {
616 		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
617 		wrqu->retry.value = priv->retry_rts;
618 	} else {
619 		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
620 		wrqu->retry.value = priv->retry_data;
621 	}
622 
623 	return 0;
624 }
625 
r8180_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)626 static int r8180_wx_get_sens(struct net_device *dev,
627 				struct iw_request_info *info,
628 				union iwreq_data *wrqu, char *extra)
629 {
630 	struct r8180_priv *priv = ieee80211_priv(dev);
631 	if (priv->rf_set_sens == NULL)
632 		return -1; /* we have not this support for this radio */
633 	wrqu->sens.value = priv->sens;
634 	return 0;
635 }
636 
637 
r8180_wx_set_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)638 static int r8180_wx_set_sens(struct net_device *dev,
639 				struct iw_request_info *info,
640 				union iwreq_data *wrqu, char *extra)
641 {
642 
643 	struct r8180_priv *priv = ieee80211_priv(dev);
644 
645 	short err = 0;
646 
647 	if (priv->ieee80211->bHwRadioOff)
648 		return 0;
649 
650 	down(&priv->wx_sem);
651 	if (priv->rf_set_sens == NULL) {
652 		err = -1; /* we have not this support for this radio */
653 		goto exit;
654 	}
655 	if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
656 		priv->sens = wrqu->sens.value;
657 	else
658 		err = -EINVAL;
659 
660 exit:
661 	up(&priv->wx_sem);
662 
663 	return err;
664 }
665 
666 
r8180_wx_set_rawtx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)667 static int r8180_wx_set_rawtx(struct net_device *dev,
668 			       struct iw_request_info *info,
669 			       union iwreq_data *wrqu, char *extra)
670 {
671 	struct r8180_priv *priv = ieee80211_priv(dev);
672 	int ret;
673 
674 	if (priv->ieee80211->bHwRadioOff)
675 		return 0;
676 
677 	down(&priv->wx_sem);
678 
679 	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
680 
681 	up(&priv->wx_sem);
682 
683 	return ret;
684 
685 }
686 
r8180_wx_get_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)687 static int r8180_wx_get_power(struct net_device *dev,
688 			       struct iw_request_info *info,
689 			       union iwreq_data *wrqu, char *extra)
690 {
691 	int ret;
692 	struct r8180_priv *priv = ieee80211_priv(dev);
693 
694 	down(&priv->wx_sem);
695 
696 	ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
697 
698 	up(&priv->wx_sem);
699 
700 	return ret;
701 }
702 
r8180_wx_set_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)703 static int r8180_wx_set_power(struct net_device *dev,
704 			       struct iw_request_info *info,
705 			       union iwreq_data *wrqu, char *extra)
706 {
707 	int ret;
708 	struct r8180_priv *priv = ieee80211_priv(dev);
709 
710 
711 	if (priv->ieee80211->bHwRadioOff)
712 		return 0;
713 
714 	down(&priv->wx_sem);
715 	printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
716 	if (wrqu->power.disabled == 0) {
717 		wrqu->power.flags |= IW_POWER_ALL_R;
718 		wrqu->power.flags |= IW_POWER_TIMEOUT;
719 		wrqu->power.value = 1000;
720 	}
721 
722 	ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
723 
724 	up(&priv->wx_sem);
725 
726 	return ret;
727 }
728 
r8180_wx_set_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)729 static int r8180_wx_set_rts(struct net_device *dev,
730 			     struct iw_request_info *info,
731 			     union iwreq_data *wrqu, char *extra)
732 {
733 	struct r8180_priv *priv = ieee80211_priv(dev);
734 
735 
736 	if (priv->ieee80211->bHwRadioOff)
737 		return 0;
738 
739 	if (wrqu->rts.disabled)
740 		priv->rts = DEFAULT_RTS_THRESHOLD;
741 	else {
742 		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
743 		    wrqu->rts.value > MAX_RTS_THRESHOLD)
744 			return -EINVAL;
745 
746 		priv->rts = wrqu->rts.value;
747 	}
748 
749 	return 0;
750 }
r8180_wx_get_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)751 static int r8180_wx_get_rts(struct net_device *dev,
752 			     struct iw_request_info *info,
753 			     union iwreq_data *wrqu, char *extra)
754 {
755 	struct r8180_priv *priv = ieee80211_priv(dev);
756 
757 
758 
759 	wrqu->rts.value = priv->rts;
760 	wrqu->rts.fixed = 0;	/* no auto select */
761 	wrqu->rts.disabled = (wrqu->rts.value == 0);
762 
763 	return 0;
764 }
dummy(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)765 static int dummy(struct net_device *dev, struct iw_request_info *a,
766 		 union iwreq_data *wrqu, char *b)
767 {
768 	return -1;
769 }
770 
r8180_wx_get_iwmode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)771 static int r8180_wx_get_iwmode(struct net_device *dev,
772 			       struct iw_request_info *info,
773 			       union iwreq_data *wrqu, char *extra)
774 {
775 	struct r8180_priv *priv = ieee80211_priv(dev);
776 	struct ieee80211_device *ieee;
777 	int ret = 0;
778 
779 
780 
781 	down(&priv->wx_sem);
782 
783 	ieee = priv->ieee80211;
784 
785 	strcpy(extra, "802.11");
786 	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
787 		strcat(extra, "b");
788 		if (ieee->modulation & IEEE80211_OFDM_MODULATION)
789 			strcat(extra, "/g");
790 	} else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
791 		strcat(extra, "g");
792 
793 	up(&priv->wx_sem);
794 
795 	return ret;
796 }
r8180_wx_set_iwmode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)797 static int r8180_wx_set_iwmode(struct net_device *dev,
798 			       struct iw_request_info *info,
799 			       union iwreq_data *wrqu, char *extra)
800 {
801 	struct r8180_priv *priv = ieee80211_priv(dev);
802 	struct ieee80211_device *ieee = priv->ieee80211;
803 	int *param = (int *)extra;
804 	int ret = 0;
805 	int modulation = 0, mode = 0;
806 
807 
808 	if (priv->ieee80211->bHwRadioOff)
809 		return 0;
810 
811 	down(&priv->wx_sem);
812 
813 	if (*param == 1) {
814 		modulation |= IEEE80211_CCK_MODULATION;
815 		mode = IEEE_B;
816 	printk(KERN_INFO "B mode!\n");
817 	} else if (*param == 2) {
818 		modulation |= IEEE80211_OFDM_MODULATION;
819 		mode = IEEE_G;
820 	printk(KERN_INFO "G mode!\n");
821 	} else if (*param == 3) {
822 		modulation |= IEEE80211_CCK_MODULATION;
823 		modulation |= IEEE80211_OFDM_MODULATION;
824 		mode = IEEE_B|IEEE_G;
825 	printk(KERN_INFO "B/G mode!\n");
826 	}
827 
828 	if (ieee->proto_started) {
829 		ieee80211_stop_protocol(ieee);
830 		ieee->mode = mode;
831 		ieee->modulation = modulation;
832 		ieee80211_start_protocol(ieee);
833 	} else {
834 		ieee->mode = mode;
835 		ieee->modulation = modulation;
836 	}
837 
838 	up(&priv->wx_sem);
839 
840 	return ret;
841 }
r8180_wx_get_preamble(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)842 static int r8180_wx_get_preamble(struct net_device *dev,
843 			     struct iw_request_info *info,
844 			     union iwreq_data *wrqu, char *extra)
845 {
846 	struct r8180_priv *priv = ieee80211_priv(dev);
847 
848 
849 
850 	down(&priv->wx_sem);
851 
852 
853 
854 	*extra = (char) priv->plcp_preamble_mode;	/* 0:auto 1:short 2:long */
855 	up(&priv->wx_sem);
856 
857 	return 0;
858 }
r8180_wx_set_preamble(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)859 static int r8180_wx_set_preamble(struct net_device *dev,
860 			     struct iw_request_info *info,
861 			     union iwreq_data *wrqu, char *extra)
862 {
863 	struct r8180_priv *priv = ieee80211_priv(dev);
864 	int ret = 0;
865 
866 
867 	if (priv->ieee80211->bHwRadioOff)
868 		return 0;
869 
870 	down(&priv->wx_sem);
871 	if (*extra < 0 || *extra > 2)
872 		ret = -1;
873 	else
874 		priv->plcp_preamble_mode = *((short *)extra) ;
875 
876 
877 
878 	up(&priv->wx_sem);
879 
880 	return ret;
881 }
r8180_wx_get_siglevel(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)882 static int r8180_wx_get_siglevel(struct net_device *dev,
883 			       struct iw_request_info *info,
884 			       union iwreq_data *wrqu, char *extra)
885 {
886 	struct r8180_priv *priv = ieee80211_priv(dev);
887 	int ret = 0;
888 
889 
890 
891 	down(&priv->wx_sem);
892 	/* Modify by hikaru 6.5 */
893 	*((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
894 
895 
896 
897 	up(&priv->wx_sem);
898 
899 	return ret;
900 }
r8180_wx_get_sigqual(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)901 static int r8180_wx_get_sigqual(struct net_device *dev,
902 			       struct iw_request_info *info,
903 			       union iwreq_data *wrqu, char *extra)
904 {
905 	struct r8180_priv *priv = ieee80211_priv(dev);
906 	int ret = 0;
907 
908 
909 
910 	down(&priv->wx_sem);
911 	/* Modify by hikaru 6.5	*/
912 	*((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
913 
914 
915 
916 	up(&priv->wx_sem);
917 
918 	return ret;
919 }
r8180_wx_reset_stats(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)920 static int r8180_wx_reset_stats(struct net_device *dev,
921 				struct iw_request_info *info,
922 				union iwreq_data *wrqu, char *extra)
923 {
924 	struct r8180_priv *priv = ieee80211_priv(dev);
925 	down(&priv->wx_sem);
926 
927 	priv->stats.txrdu = 0;
928 	priv->stats.rxrdu = 0;
929 	priv->stats.rxnolast = 0;
930 	priv->stats.rxnodata = 0;
931 	priv->stats.rxnopointer = 0;
932 	priv->stats.txnperr = 0;
933 	priv->stats.txresumed = 0;
934 	priv->stats.rxerr = 0;
935 	priv->stats.rxoverflow = 0;
936 	priv->stats.rxint = 0;
937 
938 	priv->stats.txnpokint = 0;
939 	priv->stats.txhpokint = 0;
940 	priv->stats.txhperr = 0;
941 	priv->stats.ints = 0;
942 	priv->stats.shints = 0;
943 	priv->stats.txoverflow = 0;
944 	priv->stats.rxdmafail = 0;
945 	priv->stats.txbeacon = 0;
946 	priv->stats.txbeaconerr = 0;
947 	priv->stats.txlpokint = 0;
948 	priv->stats.txlperr = 0;
949 	priv->stats.txretry = 0;/* 20060601 */
950 	priv->stats.rxcrcerrmin = 0 ;
951 	priv->stats.rxcrcerrmid = 0;
952 	priv->stats.rxcrcerrmax = 0;
953 	priv->stats.rxicverr = 0;
954 
955 	up(&priv->wx_sem);
956 
957 	return 0;
958 
959 }
r8180_wx_radio_on(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)960 static int r8180_wx_radio_on(struct net_device *dev,
961 				struct iw_request_info *info,
962 				union iwreq_data *wrqu, char *extra)
963 {
964 	struct r8180_priv *priv = ieee80211_priv(dev);
965 
966 	if (priv->ieee80211->bHwRadioOff)
967 		return 0;
968 
969 
970 	down(&priv->wx_sem);
971 	priv->rf_wakeup(dev);
972 
973 	up(&priv->wx_sem);
974 
975 	return 0;
976 
977 }
978 
r8180_wx_radio_off(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)979 static int r8180_wx_radio_off(struct net_device *dev,
980 				struct iw_request_info *info,
981 				union iwreq_data *wrqu, char *extra)
982 {
983 	struct r8180_priv *priv = ieee80211_priv(dev);
984 
985 	if (priv->ieee80211->bHwRadioOff)
986 		return 0;
987 
988 
989 	down(&priv->wx_sem);
990 	priv->rf_sleep(dev);
991 
992 	up(&priv->wx_sem);
993 
994 	return 0;
995 
996 }
r8180_wx_get_channelplan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)997 static int r8180_wx_get_channelplan(struct net_device *dev,
998 			     struct iw_request_info *info,
999 			     union iwreq_data *wrqu, char *extra)
1000 {
1001 	struct r8180_priv *priv = ieee80211_priv(dev);
1002 
1003 
1004 
1005 	down(&priv->wx_sem);
1006 	*extra = priv->channel_plan;
1007 
1008 
1009 
1010 	up(&priv->wx_sem);
1011 
1012 	return 0;
1013 }
r8180_wx_set_channelplan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1014 static int r8180_wx_set_channelplan(struct net_device *dev,
1015 			     struct iw_request_info *info,
1016 			     union iwreq_data *wrqu, char *extra)
1017 {
1018 	struct r8180_priv *priv = ieee80211_priv(dev);
1019 	int *val = (int *)extra;
1020 	int i;
1021 	printk("-----in fun %s\n", __func__);
1022 
1023 	if (priv->ieee80211->bHwRadioOff)
1024 		return 0;
1025 
1026 	/* unsigned long flags; */
1027 	down(&priv->wx_sem);
1028 	if (DefaultChannelPlan[*val].Len != 0)	{
1029 		priv->channel_plan = *val;
1030 		/* Clear old channel map 8 */
1031 		for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1032 			GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1033 
1034 		/* Set new channel map */
1035 		for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1036 			GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1037 
1038 	}
1039 	up(&priv->wx_sem);
1040 
1041 	return 0;
1042 }
1043 
r8180_wx_get_version(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1044 static int r8180_wx_get_version(struct net_device *dev,
1045 			       struct iw_request_info *info,
1046 			       union iwreq_data *wrqu, char *extra)
1047 {
1048 	struct r8180_priv *priv = ieee80211_priv(dev);
1049 	/* struct ieee80211_device *ieee; */
1050 
1051 	down(&priv->wx_sem);
1052 	strcpy(extra, "1020.0808");
1053 	up(&priv->wx_sem);
1054 
1055 	return 0;
1056 }
1057 
1058 /* added by amy 080818 */
1059 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
r8180_wx_set_forcerate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1060 static int r8180_wx_set_forcerate(struct net_device *dev,
1061 			     struct iw_request_info *info,
1062 			     union iwreq_data *wrqu, char *extra)
1063 {
1064 	struct r8180_priv *priv = ieee80211_priv(dev);
1065 	u8 forcerate = *extra;
1066 
1067 	down(&priv->wx_sem);
1068 
1069 	printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1070 	if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1071 		(forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1072 		(forcerate == 96) || (forcerate == 108))
1073 	{
1074 		priv->ForcedDataRate = 1;
1075 		priv->ieee80211->rate = forcerate * 5;
1076 	}	else if (forcerate == 0)	{
1077 		priv->ForcedDataRate = 0;
1078 		printk("OK! return rate adaptive\n");
1079 	}	else
1080 			printk("ERR: wrong rate\n");
1081 	up(&priv->wx_sem);
1082 	return 0;
1083 }
1084 
r8180_wx_set_enc_ext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1085 static int r8180_wx_set_enc_ext(struct net_device *dev,
1086 										struct iw_request_info *info,
1087 										union iwreq_data *wrqu, char *extra)
1088 {
1089 
1090 	struct r8180_priv *priv = ieee80211_priv(dev);
1091 
1092 	int ret = 0;
1093 
1094 	if (priv->ieee80211->bHwRadioOff)
1095 		return 0;
1096 
1097 	down(&priv->wx_sem);
1098 	ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1099 	up(&priv->wx_sem);
1100 	return ret;
1101 
1102 }
r8180_wx_set_auth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1103 static int r8180_wx_set_auth(struct net_device *dev,
1104 			     struct iw_request_info *info,
1105 			     union iwreq_data *wrqu, char *extra)
1106 {
1107 	struct r8180_priv *priv = ieee80211_priv(dev);
1108 	int ret = 0;
1109 
1110 	if (priv->ieee80211->bHwRadioOff)
1111 		return 0;
1112 
1113 	down(&priv->wx_sem);
1114 	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1115 	up(&priv->wx_sem);
1116 	return ret;
1117 }
1118 
r8180_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1119 static int r8180_wx_set_mlme(struct net_device *dev,
1120 										struct iw_request_info *info,
1121 										union iwreq_data *wrqu, char *extra)
1122 {
1123 	int ret = 0;
1124 	struct r8180_priv *priv = ieee80211_priv(dev);
1125 
1126 
1127 	if (priv->ieee80211->bHwRadioOff)
1128 		return 0;
1129 
1130 
1131 	down(&priv->wx_sem);
1132 #if 1
1133 	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1134 #endif
1135 	up(&priv->wx_sem);
1136 	return ret;
1137 }
r8180_wx_set_gen_ie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1138 static int r8180_wx_set_gen_ie(struct net_device *dev,
1139 			       struct iw_request_info *info,
1140 			       union iwreq_data *wrqu, char *extra)
1141 {
1142 	int ret = 0;
1143 		struct r8180_priv *priv = ieee80211_priv(dev);
1144 
1145 
1146 	if (priv->ieee80211->bHwRadioOff)
1147 		return 0;
1148 
1149 		down(&priv->wx_sem);
1150 #if 1
1151 		ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1152 #endif
1153 		up(&priv->wx_sem);
1154 		return ret;
1155 
1156 
1157 }
1158 static iw_handler r8180_wx_handlers[] =	{
1159 		NULL,					/* SIOCSIWCOMMIT */
1160 		r8180_wx_get_name,			/* SIOCGIWNAME */
1161 		dummy,					/* SIOCSIWNWID */
1162 		dummy,					/* SIOCGIWNWID */
1163 		r8180_wx_set_freq,			/* SIOCSIWFREQ */
1164 		r8180_wx_get_freq,			/* SIOCGIWFREQ */
1165 		r8180_wx_set_mode,			/* SIOCSIWMODE */
1166 		r8180_wx_get_mode,			/* SIOCGIWMODE */
1167 		r8180_wx_set_sens,			/* SIOCSIWSENS */
1168 		r8180_wx_get_sens,			/* SIOCGIWSENS */
1169 		NULL,					/* SIOCSIWRANGE */
1170 		rtl8180_wx_get_range,			/* SIOCGIWRANGE */
1171 		NULL,					/* SIOCSIWPRIV */
1172 		NULL,					/* SIOCGIWPRIV */
1173 		NULL,					/* SIOCSIWSTATS */
1174 		NULL,					/* SIOCGIWSTATS */
1175 		dummy,					/* SIOCSIWSPY */
1176 		dummy,					/* SIOCGIWSPY */
1177 		NULL,					/* SIOCGIWTHRSPY */
1178 		NULL,					/* SIOCWIWTHRSPY */
1179 		r8180_wx_set_wap,			/* SIOCSIWAP */
1180 		r8180_wx_get_wap,			/* SIOCGIWAP */
1181 		r8180_wx_set_mlme,			/* SIOCSIWMLME*/
1182 		dummy,					/* SIOCGIWAPLIST -- deprecated */
1183 		r8180_wx_set_scan,			/* SIOCSIWSCAN */
1184 		r8180_wx_get_scan,			/* SIOCGIWSCAN */
1185 		r8180_wx_set_essid,			/* SIOCSIWESSID */
1186 		r8180_wx_get_essid,			/* SIOCGIWESSID */
1187 		dummy,					/* SIOCSIWNICKN */
1188 		dummy,					/* SIOCGIWNICKN */
1189 		NULL,					/* -- hole -- */
1190 		NULL,					/* -- hole -- */
1191 		r8180_wx_set_rate,			/* SIOCSIWRATE */
1192 		r8180_wx_get_rate,			/* SIOCGIWRATE */
1193 		r8180_wx_set_rts,			/* SIOCSIWRTS */
1194 		r8180_wx_get_rts,			/* SIOCGIWRTS */
1195 		r8180_wx_set_frag,			/* SIOCSIWFRAG */
1196 		r8180_wx_get_frag,			/* SIOCGIWFRAG */
1197 		dummy,					/* SIOCSIWTXPOW */
1198 		dummy,					/* SIOCGIWTXPOW */
1199 		r8180_wx_set_retry,			/* SIOCSIWRETRY */
1200 		r8180_wx_get_retry,			/* SIOCGIWRETRY */
1201 		r8180_wx_set_enc,			/* SIOCSIWENCODE */
1202 		r8180_wx_get_enc,			/* SIOCGIWENCODE */
1203 		r8180_wx_set_power,			/* SIOCSIWPOWER */
1204 		r8180_wx_get_power,			/* SIOCGIWPOWER */
1205 		NULL,					/*---hole---*/
1206 		NULL,					/*---hole---*/
1207 		r8180_wx_set_gen_ie,			/* SIOCSIWGENIE */
1208 		NULL,					/* SIOCSIWGENIE */
1209 		r8180_wx_set_auth,			/* SIOCSIWAUTH */
1210 		NULL,					/* SIOCSIWAUTH */
1211 		r8180_wx_set_enc_ext,			/* SIOCSIWENCODEEXT */
1212 		NULL,					/* SIOCSIWENCODEEXT */
1213 		NULL,					/* SIOCSIWPMKSA */
1214 		NULL,					/*---hole---*/
1215 };
1216 
1217 
1218 static const struct iw_priv_args r8180_private_args[] = {
1219 	{
1220 		SIOCIWFIRSTPRIV + 0x0,
1221 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1222 	},
1223 	{	SIOCIWFIRSTPRIV + 0x1,
1224 		0, 0, "dummy"
1225 
1226 	},
1227 	{
1228 		SIOCIWFIRSTPRIV + 0x2,
1229 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1230 	},
1231 	{	SIOCIWFIRSTPRIV + 0x3,
1232 		0, 0, "dummy"
1233 
1234 	},
1235 	{
1236 		SIOCIWFIRSTPRIV + 0x4,
1237 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1238 
1239 	},
1240 	{	SIOCIWFIRSTPRIV + 0x5,
1241 		0, 0, "dummy"
1242 
1243 	},
1244 	{
1245 		SIOCIWFIRSTPRIV + 0x6,
1246 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1247 
1248 	},
1249 	{	SIOCIWFIRSTPRIV + 0x7,
1250 		0, 0, "dummy"
1251 
1252 	},
1253 	{
1254 		SIOCIWFIRSTPRIV + 0x8,
1255 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1256 	},
1257 	{
1258 		SIOCIWFIRSTPRIV + 0x9,
1259 		0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1260 	},
1261 	{
1262 		SIOCIWFIRSTPRIV + 0xA,
1263 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1264 	},
1265 	{
1266 		SIOCIWFIRSTPRIV + 0xB,
1267 		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1268 	},
1269 	{	SIOCIWFIRSTPRIV + 0xC,
1270 		0, 0, "dummy"
1271 	},
1272 	{
1273 		SIOCIWFIRSTPRIV + 0xD,
1274 		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1275 	},
1276 	{	SIOCIWFIRSTPRIV + 0xE,
1277 		0, 0, "dummy"
1278 	},
1279 	{
1280 		SIOCIWFIRSTPRIV + 0xF,
1281 		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1282 	},
1283 	{
1284 		SIOCIWFIRSTPRIV + 0x10,
1285 		0, 0, "resetstats"
1286 	},
1287 	{
1288 		SIOCIWFIRSTPRIV + 0x11,
1289 		0, 0, "dummy"
1290 	},
1291 	{
1292 		SIOCIWFIRSTPRIV + 0x12,
1293 		0, 0, "radioon"
1294 	},
1295 	{
1296 		SIOCIWFIRSTPRIV + 0x13,
1297 		0, 0, "radiooff"
1298 	},
1299 	{
1300 		SIOCIWFIRSTPRIV + 0x14,
1301 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1302 	},
1303 	{
1304 		SIOCIWFIRSTPRIV + 0x15,
1305 		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1306 	},
1307 	{
1308 		SIOCIWFIRSTPRIV + 0x16,
1309 		0, 0, "dummy"
1310 	},
1311 	{
1312 		SIOCIWFIRSTPRIV + 0x17,
1313 		0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1314 	},
1315 	{
1316 		SIOCIWFIRSTPRIV + 0x18,
1317 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1318 	},
1319 };
1320 
1321 
1322 static iw_handler r8180_private_handler[] = {
1323 	r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1324 	dummy,
1325 	r8180_wx_set_beaconinterval,
1326 	dummy,
1327 	/* r8180_wx_set_monitor_type, */
1328 	r8180_wx_set_scan_type,
1329 	dummy,
1330 	r8180_wx_set_rawtx,
1331 	dummy,
1332 	r8180_wx_set_iwmode,
1333 	r8180_wx_get_iwmode,
1334 	r8180_wx_set_preamble,
1335 	r8180_wx_get_preamble,
1336 	dummy,
1337 	r8180_wx_get_siglevel,
1338 	dummy,
1339 	r8180_wx_get_sigqual,
1340 	r8180_wx_reset_stats,
1341 	dummy,/* r8180_wx_get_stats */
1342 	r8180_wx_radio_on,
1343 	r8180_wx_radio_off,
1344 	r8180_wx_set_channelplan,
1345 	r8180_wx_get_channelplan,
1346 	dummy,
1347 	r8180_wx_get_version,
1348 	r8180_wx_set_forcerate,
1349 };
1350 
is_same_network(struct ieee80211_network * src,struct ieee80211_network * dst,struct ieee80211_device * ieee)1351 static inline int is_same_network(struct ieee80211_network *src,
1352 									struct ieee80211_network *dst,
1353 				  struct ieee80211_device *ieee)
1354 {
1355 		/* A network is only a duplicate if the channel, BSSID, ESSID
1356 		 * and the capability field (in particular IBSS and BSS) all match.
1357 		 * We treat all <hidden> with the same BSSID and channel
1358 		 * as one network
1359 		 */
1360 		return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1361 			(src->channel == dst->channel) &&
1362 			!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1363 			(!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&  /* YJ,mod, 080819,for hidden ap */
1364 			((src->capability & WLAN_CAPABILITY_IBSS) ==
1365 			(dst->capability & WLAN_CAPABILITY_IBSS)) &&
1366 			((src->capability & WLAN_CAPABILITY_BSS) ==
1367 			(dst->capability & WLAN_CAPABILITY_BSS)));
1368 }
1369 
1370 /* WB modified to show signal to GUI on 18-01-2008 */
r8180_get_wireless_stats(struct net_device * dev)1371 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1372 {
1373 	struct r8180_priv *priv = ieee80211_priv(dev);
1374 	struct ieee80211_device* ieee = priv->ieee80211;
1375 	struct iw_statistics* wstats = &priv->wstats;
1376 	int tmp_level = 0;
1377 	int tmp_qual = 0;
1378 	int tmp_noise = 0;
1379 
1380 	if (ieee->state < IEEE80211_LINKED)	{
1381 		wstats->qual.qual = 0;
1382 		wstats->qual.level = 0;
1383 		wstats->qual.noise = 0;
1384 		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1385 		return wstats;
1386 	}
1387 
1388 	tmp_level = (&ieee->current_network)->stats.signal;
1389 	tmp_qual = (&ieee->current_network)->stats.signalstrength;
1390 	tmp_noise = (&ieee->current_network)->stats.noise;
1391 
1392 	wstats->qual.level = tmp_level;
1393 	wstats->qual.qual = tmp_qual;
1394 	wstats->qual.noise = tmp_noise;
1395 	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1396 	return wstats;
1397 }
1398 
1399 struct iw_handler_def  r8180_wx_handlers_def = {
1400 	.standard = r8180_wx_handlers,
1401 	.num_standard = ARRAY_SIZE(r8180_wx_handlers),
1402 	.private = r8180_private_handler,
1403 	.num_private = ARRAY_SIZE(r8180_private_handler),
1404 	.num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1405 	.get_wireless_stats = r8180_get_wireless_stats,
1406 	.private_args = (struct iw_priv_args *)r8180_private_args,
1407 };
1408 
1409 
1410