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