• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
3 
4 #include <linux/slab.h>
5 #include <linux/types.h>
6 #include <linux/sched/signal.h>
7 #include <linux/ethtool.h>
8 #include <linux/if_arp.h>
9 #include <linux/module.h>
10 #include <linux/etherdevice.h>
11 #include <net/lib80211.h>
12 
13 #include "hostap_wlan.h"
14 #include "hostap.h"
15 #include "hostap_ap.h"
16 
hostap_get_wireless_stats(struct net_device * dev)17 static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
18 {
19 	struct hostap_interface *iface;
20 	local_info_t *local;
21 	struct iw_statistics *wstats;
22 
23 	iface = netdev_priv(dev);
24 	local = iface->local;
25 
26 	/* Why are we doing that ? Jean II */
27 	if (iface->type != HOSTAP_INTERFACE_MAIN)
28 		return NULL;
29 
30 	wstats = &local->wstats;
31 
32 	wstats->status = 0;
33 	wstats->discard.code =
34 		local->comm_tallies.rx_discards_wep_undecryptable;
35 	wstats->discard.misc =
36 		local->comm_tallies.rx_fcs_errors +
37 		local->comm_tallies.rx_discards_no_buffer +
38 		local->comm_tallies.tx_discards_wrong_sa;
39 
40 	wstats->discard.retries =
41 		local->comm_tallies.tx_retry_limit_exceeded;
42 	wstats->discard.fragment =
43 		local->comm_tallies.rx_message_in_bad_msg_fragments;
44 
45 	if (local->iw_mode != IW_MODE_MASTER &&
46 	    local->iw_mode != IW_MODE_REPEAT) {
47 
48 		if (prism2_update_comms_qual(dev) == 0)
49 			wstats->qual.updated = IW_QUAL_ALL_UPDATED |
50 				IW_QUAL_DBM;
51 
52 		wstats->qual.qual = local->comms_qual;
53 		wstats->qual.level = local->avg_signal;
54 		wstats->qual.noise = local->avg_noise;
55 	} else {
56 		wstats->qual.qual = 0;
57 		wstats->qual.level = 0;
58 		wstats->qual.noise = 0;
59 		wstats->qual.updated = IW_QUAL_ALL_INVALID;
60 	}
61 
62 	return wstats;
63 }
64 
65 
prism2_get_datarates(struct net_device * dev,u8 * rates)66 static int prism2_get_datarates(struct net_device *dev, u8 *rates)
67 {
68 	struct hostap_interface *iface;
69 	local_info_t *local;
70 	u8 buf[12];
71 	int len;
72 	u16 val;
73 
74 	iface = netdev_priv(dev);
75 	local = iface->local;
76 
77 	len = local->func->get_rid(dev, HFA384X_RID_SUPPORTEDDATARATES, buf,
78 				   sizeof(buf), 0);
79 	if (len < 2)
80 		return 0;
81 
82 	val = le16_to_cpu(*(__le16 *) buf); /* string length */
83 
84 	if (len - 2 < val || val > 10)
85 		return 0;
86 
87 	memcpy(rates, buf + 2, val);
88 	return val;
89 }
90 
91 
prism2_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)92 static int prism2_get_name(struct net_device *dev,
93 			   struct iw_request_info *info,
94 			   union iwreq_data *wrqu, char *extra)
95 {
96 	u8 rates[10];
97 	int len, i, over2 = 0;
98 
99 	len = prism2_get_datarates(dev, rates);
100 
101 	for (i = 0; i < len; i++) {
102 		if (rates[i] == 0x0b || rates[i] == 0x16) {
103 			over2 = 1;
104 			break;
105 		}
106 	}
107 
108 	strcpy(wrqu->name, over2 ? "IEEE 802.11b" : "IEEE 802.11-DS");
109 
110 	return 0;
111 }
112 
113 
prism2_ioctl_siwencode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)114 static int prism2_ioctl_siwencode(struct net_device *dev,
115 				  struct iw_request_info *info,
116 				  union iwreq_data *wrqu, char *keybuf)
117 {
118 	struct iw_point *erq = &wrqu->encoding;
119 	struct hostap_interface *iface;
120 	local_info_t *local;
121 	int i;
122 	struct lib80211_crypt_data **crypt;
123 
124 	iface = netdev_priv(dev);
125 	local = iface->local;
126 
127 	i = erq->flags & IW_ENCODE_INDEX;
128 	if (i < 1 || i > 4)
129 		i = local->crypt_info.tx_keyidx;
130 	else
131 		i--;
132 	if (i < 0 || i >= WEP_KEYS)
133 		return -EINVAL;
134 
135 	crypt = &local->crypt_info.crypt[i];
136 
137 	if (erq->flags & IW_ENCODE_DISABLED) {
138 		if (*crypt)
139 			lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
140 		goto done;
141 	}
142 
143 	if (*crypt != NULL && (*crypt)->ops != NULL &&
144 	    strcmp((*crypt)->ops->name, "WEP") != 0) {
145 		/* changing to use WEP; deinit previously used algorithm */
146 		lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
147 	}
148 
149 	if (*crypt == NULL) {
150 		struct lib80211_crypt_data *new_crypt;
151 
152 		/* take WEP into use */
153 		new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
154 				GFP_KERNEL);
155 		if (new_crypt == NULL)
156 			return -ENOMEM;
157 		new_crypt->ops = lib80211_get_crypto_ops("WEP");
158 		if (!new_crypt->ops) {
159 			request_module("lib80211_crypt_wep");
160 			new_crypt->ops = lib80211_get_crypto_ops("WEP");
161 		}
162 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
163 			new_crypt->priv = new_crypt->ops->init(i);
164 		if (!new_crypt->ops || !new_crypt->priv) {
165 			kfree(new_crypt);
166 			new_crypt = NULL;
167 
168 			printk(KERN_WARNING "%s: could not initialize WEP: "
169 			       "load module hostap_crypt_wep.o\n",
170 			       dev->name);
171 			return -EOPNOTSUPP;
172 		}
173 		*crypt = new_crypt;
174 	}
175 
176 	if (erq->length > 0) {
177 		int len = erq->length <= 5 ? 5 : 13;
178 		int first = 1, j;
179 		if (len > erq->length)
180 			memset(keybuf + erq->length, 0, len - erq->length);
181 		(*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
182 		for (j = 0; j < WEP_KEYS; j++) {
183 			if (j != i && local->crypt_info.crypt[j]) {
184 				first = 0;
185 				break;
186 			}
187 		}
188 		if (first)
189 			local->crypt_info.tx_keyidx = i;
190 	} else {
191 		/* No key data - just set the default TX key index */
192 		local->crypt_info.tx_keyidx = i;
193 	}
194 
195  done:
196 	local->open_wep = erq->flags & IW_ENCODE_OPEN;
197 
198 	if (hostap_set_encryption(local)) {
199 		printk(KERN_DEBUG "%s: set_encryption failed\n", dev->name);
200 		return -EINVAL;
201 	}
202 
203 	/* Do not reset port0 if card is in Managed mode since resetting will
204 	 * generate new IEEE 802.11 authentication which may end up in looping
205 	 * with IEEE 802.1X. Prism2 documentation seem to require port reset
206 	 * after WEP configuration. However, keys are apparently changed at
207 	 * least in Managed mode. */
208 	if (local->iw_mode != IW_MODE_INFRA && local->func->reset_port(dev)) {
209 		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
210 		return -EINVAL;
211 	}
212 
213 	return 0;
214 }
215 
216 
prism2_ioctl_giwencode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * key)217 static int prism2_ioctl_giwencode(struct net_device *dev,
218 				  struct iw_request_info *info,
219 				  union iwreq_data *wrqu, char *key)
220 {
221 	struct iw_point *erq = &wrqu->encoding;
222 	struct hostap_interface *iface;
223 	local_info_t *local;
224 	int i, len;
225 	u16 val;
226 	struct lib80211_crypt_data *crypt;
227 
228 	iface = netdev_priv(dev);
229 	local = iface->local;
230 
231 	i = erq->flags & IW_ENCODE_INDEX;
232 	if (i < 1 || i > 4)
233 		i = local->crypt_info.tx_keyidx;
234 	else
235 		i--;
236 	if (i < 0 || i >= WEP_KEYS)
237 		return -EINVAL;
238 
239 	crypt = local->crypt_info.crypt[i];
240 	erq->flags = i + 1;
241 
242 	if (crypt == NULL || crypt->ops == NULL) {
243 		erq->length = 0;
244 		erq->flags |= IW_ENCODE_DISABLED;
245 		return 0;
246 	}
247 
248 	if (strcmp(crypt->ops->name, "WEP") != 0) {
249 		/* only WEP is supported with wireless extensions, so just
250 		 * report that encryption is used */
251 		erq->length = 0;
252 		erq->flags |= IW_ENCODE_ENABLED;
253 		return 0;
254 	}
255 
256 	/* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show
257 	 * the keys from driver buffer */
258 	len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv);
259 	erq->length = (len >= 0 ? len : 0);
260 
261 	if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0)
262 	{
263 		printk("CNFWEPFLAGS reading failed\n");
264 		return -EOPNOTSUPP;
265 	}
266 	le16_to_cpus(&val);
267 	if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED)
268 		erq->flags |= IW_ENCODE_ENABLED;
269 	else
270 		erq->flags |= IW_ENCODE_DISABLED;
271 	if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED)
272 		erq->flags |= IW_ENCODE_RESTRICTED;
273 	else
274 		erq->flags |= IW_ENCODE_OPEN;
275 
276 	return 0;
277 }
278 
279 
hostap_set_rate(struct net_device * dev)280 static int hostap_set_rate(struct net_device *dev)
281 {
282 	struct hostap_interface *iface;
283 	local_info_t *local;
284 	int ret, basic_rates;
285 
286 	iface = netdev_priv(dev);
287 	local = iface->local;
288 
289 	basic_rates = local->basic_rates & local->tx_rate_control;
290 	if (!basic_rates || basic_rates != local->basic_rates) {
291 		printk(KERN_INFO "%s: updating basic rate set automatically "
292 		       "to match with the new supported rate set\n",
293 		       dev->name);
294 		if (!basic_rates)
295 			basic_rates = local->tx_rate_control;
296 
297 		local->basic_rates = basic_rates;
298 		if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
299 				    basic_rates))
300 			printk(KERN_WARNING "%s: failed to set "
301 			       "cnfBasicRates\n", dev->name);
302 	}
303 
304 	ret = (hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
305 			       local->tx_rate_control) ||
306 	       hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
307 			       local->tx_rate_control) ||
308 	       local->func->reset_port(dev));
309 
310 	if (ret) {
311 		printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates "
312 		       "setting to 0x%x failed\n",
313 		       dev->name, local->tx_rate_control);
314 	}
315 
316 	/* Update TX rate configuration for all STAs based on new operational
317 	 * rate set. */
318 	hostap_update_rates(local);
319 
320 	return ret;
321 }
322 
323 
prism2_ioctl_siwrate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)324 static int prism2_ioctl_siwrate(struct net_device *dev,
325 				struct iw_request_info *info,
326 				union iwreq_data *wrqu, char *extra)
327 {
328 	struct iw_param *rrq = &wrqu->bitrate;
329 	struct hostap_interface *iface;
330 	local_info_t *local;
331 
332 	iface = netdev_priv(dev);
333 	local = iface->local;
334 
335 	if (rrq->fixed) {
336 		switch (rrq->value) {
337 		case 11000000:
338 			local->tx_rate_control = HFA384X_RATES_11MBPS;
339 			break;
340 		case 5500000:
341 			local->tx_rate_control = HFA384X_RATES_5MBPS;
342 			break;
343 		case 2000000:
344 			local->tx_rate_control = HFA384X_RATES_2MBPS;
345 			break;
346 		case 1000000:
347 			local->tx_rate_control = HFA384X_RATES_1MBPS;
348 			break;
349 		default:
350 			local->tx_rate_control = HFA384X_RATES_1MBPS |
351 				HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
352 				HFA384X_RATES_11MBPS;
353 			break;
354 		}
355 	} else {
356 		switch (rrq->value) {
357 		case 11000000:
358 			local->tx_rate_control = HFA384X_RATES_1MBPS |
359 				HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
360 				HFA384X_RATES_11MBPS;
361 			break;
362 		case 5500000:
363 			local->tx_rate_control = HFA384X_RATES_1MBPS |
364 				HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS;
365 			break;
366 		case 2000000:
367 			local->tx_rate_control = HFA384X_RATES_1MBPS |
368 				HFA384X_RATES_2MBPS;
369 			break;
370 		case 1000000:
371 			local->tx_rate_control = HFA384X_RATES_1MBPS;
372 			break;
373 		default:
374 			local->tx_rate_control = HFA384X_RATES_1MBPS |
375 				HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
376 				HFA384X_RATES_11MBPS;
377 			break;
378 		}
379 	}
380 
381 	return hostap_set_rate(dev);
382 }
383 
384 
prism2_ioctl_giwrate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)385 static int prism2_ioctl_giwrate(struct net_device *dev,
386 				struct iw_request_info *info,
387 				union iwreq_data *wrqu, char *extra)
388 {
389 	struct iw_param *rrq = &wrqu->bitrate;
390 	u16 val;
391 	struct hostap_interface *iface;
392 	local_info_t *local;
393 	int ret = 0;
394 
395 	iface = netdev_priv(dev);
396 	local = iface->local;
397 
398 	if (local->func->get_rid(dev, HFA384X_RID_TXRATECONTROL, &val, 2, 1) <
399 	    0)
400 		return -EINVAL;
401 
402 	if ((val & 0x1) && (val > 1))
403 		rrq->fixed = 0;
404 	else
405 		rrq->fixed = 1;
406 
407 	if (local->iw_mode == IW_MODE_MASTER && local->ap != NULL &&
408 	    !local->fw_tx_rate_control) {
409 		/* HFA384X_RID_CURRENTTXRATE seems to always be 2 Mbps in
410 		 * Host AP mode, so use the recorded TX rate of the last sent
411 		 * frame */
412 		rrq->value = local->ap->last_tx_rate > 0 ?
413 			local->ap->last_tx_rate * 100000 : 11000000;
414 		return 0;
415 	}
416 
417 	if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) <
418 	    0)
419 		return -EINVAL;
420 
421 	switch (val) {
422 	case HFA384X_RATES_1MBPS:
423 		rrq->value = 1000000;
424 		break;
425 	case HFA384X_RATES_2MBPS:
426 		rrq->value = 2000000;
427 		break;
428 	case HFA384X_RATES_5MBPS:
429 		rrq->value = 5500000;
430 		break;
431 	case HFA384X_RATES_11MBPS:
432 		rrq->value = 11000000;
433 		break;
434 	default:
435 		/* should not happen */
436 		rrq->value = 11000000;
437 		ret = -EINVAL;
438 		break;
439 	}
440 
441 	return ret;
442 }
443 
444 
prism2_ioctl_siwsens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)445 static int prism2_ioctl_siwsens(struct net_device *dev,
446 				struct iw_request_info *info,
447 				union iwreq_data *wrqu, char *extra)
448 {
449 	struct iw_param *sens = &wrqu->sens;
450 	struct hostap_interface *iface;
451 	local_info_t *local;
452 
453 	iface = netdev_priv(dev);
454 	local = iface->local;
455 
456 	/* Set the desired AP density */
457 	if (sens->value < 1 || sens->value > 3)
458 		return -EINVAL;
459 
460 	if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) ||
461 	    local->func->reset_port(dev))
462 		return -EINVAL;
463 
464 	return 0;
465 }
466 
prism2_ioctl_giwsens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)467 static int prism2_ioctl_giwsens(struct net_device *dev,
468 				struct iw_request_info *info,
469 				union iwreq_data *wrqu, char *extra)
470 {
471 	struct iw_param *sens = &wrqu->sens;
472 	struct hostap_interface *iface;
473 	local_info_t *local;
474 	__le16 val;
475 
476 	iface = netdev_priv(dev);
477 	local = iface->local;
478 
479 	/* Get the current AP density */
480 	if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) <
481 	    0)
482 		return -EINVAL;
483 
484 	sens->value = le16_to_cpu(val);
485 	sens->fixed = 1;
486 
487 	return 0;
488 }
489 
490 
491 /* Deprecated in new wireless extension API */
prism2_ioctl_giwaplist(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)492 static int prism2_ioctl_giwaplist(struct net_device *dev,
493 				  struct iw_request_info *info,
494 				  union iwreq_data *wrqu, char *extra)
495 {
496 	struct iw_point *data = &wrqu->data;
497 	struct hostap_interface *iface;
498 	local_info_t *local;
499 	struct sockaddr *addr;
500 	struct iw_quality *qual;
501 
502 	iface = netdev_priv(dev);
503 	local = iface->local;
504 
505 	if (local->iw_mode != IW_MODE_MASTER) {
506 		printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported "
507 		       "in Host AP mode\n");
508 		data->length = 0;
509 		return -EOPNOTSUPP;
510 	}
511 
512 	addr = kmalloc_array(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL);
513 	qual = kmalloc_array(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL);
514 	if (addr == NULL || qual == NULL) {
515 		kfree(addr);
516 		kfree(qual);
517 		data->length = 0;
518 		return -ENOMEM;
519 	}
520 
521 	data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1);
522 
523 	memcpy(extra, addr, sizeof(struct sockaddr) * data->length);
524 	data->flags = 1; /* has quality information */
525 	memcpy(extra + sizeof(struct sockaddr) * data->length, qual,
526 	       sizeof(struct iw_quality) * data->length);
527 
528 	kfree(addr);
529 	kfree(qual);
530 	return 0;
531 }
532 
533 
prism2_ioctl_siwrts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)534 static int prism2_ioctl_siwrts(struct net_device *dev,
535 			       struct iw_request_info *info,
536 			       union iwreq_data *wrqu, char *extra)
537 {
538 	struct iw_param *rts = &wrqu->rts;
539 	struct hostap_interface *iface;
540 	local_info_t *local;
541 	__le16 val;
542 
543 	iface = netdev_priv(dev);
544 	local = iface->local;
545 
546 	if (rts->disabled)
547 		val = cpu_to_le16(2347);
548 	else if (rts->value < 0 || rts->value > 2347)
549 		return -EINVAL;
550 	else
551 		val = cpu_to_le16(rts->value);
552 
553 	if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) ||
554 	    local->func->reset_port(dev))
555 		return -EINVAL;
556 
557 	local->rts_threshold = rts->value;
558 
559 	return 0;
560 }
561 
prism2_ioctl_giwrts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)562 static int prism2_ioctl_giwrts(struct net_device *dev,
563 			       struct iw_request_info *info,
564 			       union iwreq_data *wrqu, char *extra)
565 {
566 	struct iw_param *rts = &wrqu->rts;
567 	struct hostap_interface *iface;
568 	local_info_t *local;
569 	__le16 val;
570 
571 	iface = netdev_priv(dev);
572 	local = iface->local;
573 
574 	if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) <
575 	    0)
576 		return -EINVAL;
577 
578 	rts->value = le16_to_cpu(val);
579 	rts->disabled = (rts->value == 2347);
580 	rts->fixed = 1;
581 
582 	return 0;
583 }
584 
585 
prism2_ioctl_siwfrag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)586 static int prism2_ioctl_siwfrag(struct net_device *dev,
587 				struct iw_request_info *info,
588 				union iwreq_data *wrqu, char *extra)
589 {
590 	struct iw_param *rts = &wrqu->rts;
591 	struct hostap_interface *iface;
592 	local_info_t *local;
593 	__le16 val;
594 
595 	iface = netdev_priv(dev);
596 	local = iface->local;
597 
598 	if (rts->disabled)
599 		val = cpu_to_le16(2346);
600 	else if (rts->value < 256 || rts->value > 2346)
601 		return -EINVAL;
602 	else
603 		val = cpu_to_le16(rts->value & ~0x1); /* even numbers only */
604 
605 	local->fragm_threshold = rts->value & ~0x1;
606 	if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val,
607 				 2)
608 	    || local->func->reset_port(dev))
609 		return -EINVAL;
610 
611 	return 0;
612 }
613 
prism2_ioctl_giwfrag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)614 static int prism2_ioctl_giwfrag(struct net_device *dev,
615 				struct iw_request_info *info,
616 				union iwreq_data *wrqu, char *extra)
617 {
618 	struct iw_param *rts = &wrqu->rts;
619 	struct hostap_interface *iface;
620 	local_info_t *local;
621 	__le16 val;
622 
623 	iface = netdev_priv(dev);
624 	local = iface->local;
625 
626 	if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
627 				 &val, 2, 1) < 0)
628 		return -EINVAL;
629 
630 	rts->value = le16_to_cpu(val);
631 	rts->disabled = (rts->value == 2346);
632 	rts->fixed = 1;
633 
634 	return 0;
635 }
636 
637 
638 #ifndef PRISM2_NO_STATION_MODES
hostap_join_ap(struct net_device * dev)639 static int hostap_join_ap(struct net_device *dev)
640 {
641 	struct hostap_interface *iface;
642 	local_info_t *local;
643 	struct hfa384x_join_request req;
644 	unsigned long flags;
645 	int i;
646 	struct hfa384x_hostscan_result *entry;
647 
648 	iface = netdev_priv(dev);
649 	local = iface->local;
650 
651 	memcpy(req.bssid, local->preferred_ap, ETH_ALEN);
652 	req.channel = 0;
653 
654 	spin_lock_irqsave(&local->lock, flags);
655 	for (i = 0; i < local->last_scan_results_count; i++) {
656 		if (!local->last_scan_results)
657 			break;
658 		entry = &local->last_scan_results[i];
659 		if (ether_addr_equal(local->preferred_ap, entry->bssid)) {
660 			req.channel = entry->chid;
661 			break;
662 		}
663 	}
664 	spin_unlock_irqrestore(&local->lock, flags);
665 
666 	if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
667 				 sizeof(req))) {
668 		printk(KERN_DEBUG "%s: JoinRequest %pM failed\n",
669 		       dev->name, local->preferred_ap);
670 		return -1;
671 	}
672 
673 	printk(KERN_DEBUG "%s: Trying to join BSSID %pM\n",
674 	       dev->name, local->preferred_ap);
675 
676 	return 0;
677 }
678 #endif /* PRISM2_NO_STATION_MODES */
679 
680 
prism2_ioctl_siwap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)681 static int prism2_ioctl_siwap(struct net_device *dev,
682 			      struct iw_request_info *info,
683 			      union iwreq_data *wrqu, char *extra)
684 {
685 	struct sockaddr *ap_addr = &wrqu->ap_addr;
686 #ifdef PRISM2_NO_STATION_MODES
687 	return -EOPNOTSUPP;
688 #else /* PRISM2_NO_STATION_MODES */
689 	struct hostap_interface *iface;
690 	local_info_t *local;
691 
692 	iface = netdev_priv(dev);
693 	local = iface->local;
694 
695 	memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN);
696 
697 	if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) {
698 		struct hfa384x_scan_request scan_req;
699 		memset(&scan_req, 0, sizeof(scan_req));
700 		scan_req.channel_list = cpu_to_le16(0x3fff);
701 		scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
702 		if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST,
703 					 &scan_req, sizeof(scan_req))) {
704 			printk(KERN_DEBUG "%s: ScanResults request failed - "
705 			       "preferred AP delayed to next unsolicited "
706 			       "scan\n", dev->name);
707 		}
708 	} else if (local->host_roaming == 2 &&
709 		   local->iw_mode == IW_MODE_INFRA) {
710 		if (hostap_join_ap(dev))
711 			return -EINVAL;
712 	} else {
713 		printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only "
714 		       "in Managed mode when host_roaming is enabled\n",
715 		       dev->name);
716 	}
717 
718 	return 0;
719 #endif /* PRISM2_NO_STATION_MODES */
720 }
721 
prism2_ioctl_giwap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)722 static int prism2_ioctl_giwap(struct net_device *dev,
723 			      struct iw_request_info *info,
724 			      union iwreq_data *wrqu, char *extra)
725 {
726 	struct sockaddr *ap_addr = &wrqu->ap_addr;
727 	struct hostap_interface *iface;
728 	local_info_t *local;
729 
730 	iface = netdev_priv(dev);
731 	local = iface->local;
732 
733 	ap_addr->sa_family = ARPHRD_ETHER;
734 	switch (iface->type) {
735 	case HOSTAP_INTERFACE_AP:
736 		memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN);
737 		break;
738 	case HOSTAP_INTERFACE_STA:
739 		memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN);
740 		break;
741 	case HOSTAP_INTERFACE_WDS:
742 		memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN);
743 		break;
744 	default:
745 		if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID,
746 					 &ap_addr->sa_data, ETH_ALEN, 1) < 0)
747 			return -EOPNOTSUPP;
748 
749 		/* local->bssid is also updated in LinkStatus handler when in
750 		 * station mode */
751 		memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN);
752 		break;
753 	}
754 
755 	return 0;
756 }
757 
758 
prism2_ioctl_siwnickn(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * nickname)759 static int prism2_ioctl_siwnickn(struct net_device *dev,
760 				 struct iw_request_info *info,
761 				 union iwreq_data *wrqu, char *nickname)
762 {
763 	struct iw_point *data = &wrqu->data;
764 	struct hostap_interface *iface;
765 	local_info_t *local;
766 
767 	iface = netdev_priv(dev);
768 	local = iface->local;
769 
770 	memset(local->name, 0, sizeof(local->name));
771 	memcpy(local->name, nickname, data->length);
772 	local->name_set = 1;
773 
774 	if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) ||
775 	    local->func->reset_port(dev))
776 		return -EINVAL;
777 
778 	return 0;
779 }
780 
prism2_ioctl_giwnickn(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * nickname)781 static int prism2_ioctl_giwnickn(struct net_device *dev,
782 				 struct iw_request_info *info,
783 				 union iwreq_data *wrqu, char *nickname)
784 {
785 	struct iw_point *data = &wrqu->data;
786 	struct hostap_interface *iface;
787 	local_info_t *local;
788 	int len;
789 	char name[MAX_NAME_LEN + 3];
790 	u16 val;
791 
792 	iface = netdev_priv(dev);
793 	local = iface->local;
794 
795 	len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME,
796 				   &name, MAX_NAME_LEN + 2, 0);
797 	val = le16_to_cpu(*(__le16 *) name);
798 	if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN)
799 		return -EOPNOTSUPP;
800 
801 	name[val + 2] = '\0';
802 	data->length = val + 1;
803 	memcpy(nickname, name + 2, val + 1);
804 
805 	return 0;
806 }
807 
808 
prism2_ioctl_siwfreq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)809 static int prism2_ioctl_siwfreq(struct net_device *dev,
810 				struct iw_request_info *info,
811 				union iwreq_data *wrqu, char *extra)
812 {
813 	struct iw_freq *freq = &wrqu->freq;
814 	struct hostap_interface *iface;
815 	local_info_t *local;
816 
817 	iface = netdev_priv(dev);
818 	local = iface->local;
819 
820 	/* freq => chan. */
821 	if (freq->e == 1 &&
822 	    freq->m / 100000 >= freq_list[0] &&
823 	    freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) {
824 		int ch;
825 		int fr = freq->m / 100000;
826 		for (ch = 0; ch < FREQ_COUNT; ch++) {
827 			if (fr == freq_list[ch]) {
828 				freq->e = 0;
829 				freq->m = ch + 1;
830 				break;
831 			}
832 		}
833 	}
834 
835 	if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT ||
836 	    !(local->channel_mask & (1 << (freq->m - 1))))
837 		return -EINVAL;
838 
839 	local->channel = freq->m; /* channel is used in prism2_setup_rids() */
840 	if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) ||
841 	    local->func->reset_port(dev))
842 		return -EINVAL;
843 
844 	return 0;
845 }
846 
prism2_ioctl_giwfreq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)847 static int prism2_ioctl_giwfreq(struct net_device *dev,
848 				struct iw_request_info *info,
849 				union iwreq_data *wrqu, char *extra)
850 {
851 	struct iw_freq *freq = &wrqu->freq;
852 	struct hostap_interface *iface;
853 	local_info_t *local;
854 	u16 val;
855 
856 	iface = netdev_priv(dev);
857 	local = iface->local;
858 
859 	if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) <
860 	    0)
861 		return -EINVAL;
862 
863 	le16_to_cpus(&val);
864 	if (val < 1 || val > FREQ_COUNT)
865 		return -EINVAL;
866 
867 	freq->m = freq_list[val - 1] * 100000;
868 	freq->e = 1;
869 
870 	return 0;
871 }
872 
873 
hostap_monitor_set_type(local_info_t * local)874 static void hostap_monitor_set_type(local_info_t *local)
875 {
876 	struct net_device *dev = local->ddev;
877 
878 	if (dev == NULL)
879 		return;
880 
881 	if (local->monitor_type == PRISM2_MONITOR_PRISM ||
882 	    local->monitor_type == PRISM2_MONITOR_CAPHDR) {
883 		dev->type = ARPHRD_IEEE80211_PRISM;
884 	} else if (local->monitor_type == PRISM2_MONITOR_RADIOTAP) {
885 		dev->type = ARPHRD_IEEE80211_RADIOTAP;
886 	} else {
887 		dev->type = ARPHRD_IEEE80211;
888 	}
889 }
890 
891 
prism2_ioctl_siwessid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * ssid)892 static int prism2_ioctl_siwessid(struct net_device *dev,
893 				 struct iw_request_info *info,
894 				 union iwreq_data *wrqu, char *ssid)
895 {
896 	struct iw_point *data = &wrqu->data;
897 	struct hostap_interface *iface;
898 	local_info_t *local;
899 
900 	iface = netdev_priv(dev);
901 	local = iface->local;
902 
903 	if (iface->type == HOSTAP_INTERFACE_WDS)
904 		return -EOPNOTSUPP;
905 
906 	if (data->flags == 0)
907 		ssid[0] = '\0'; /* ANY */
908 
909 	if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') {
910 		/* Setting SSID to empty string seems to kill the card in
911 		 * Host AP mode */
912 		printk(KERN_DEBUG "%s: Host AP mode does not support "
913 		       "'Any' essid\n", dev->name);
914 		return -EINVAL;
915 	}
916 
917 	memcpy(local->essid, ssid, data->length);
918 	local->essid[data->length] = '\0';
919 
920 	if ((!local->fw_ap &&
921 	     hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid))
922 	    || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) ||
923 	    local->func->reset_port(dev))
924 		return -EINVAL;
925 
926 	return 0;
927 }
928 
prism2_ioctl_giwessid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * essid)929 static int prism2_ioctl_giwessid(struct net_device *dev,
930 				 struct iw_request_info *info,
931 				 union iwreq_data *wrqu, char *essid)
932 {
933 	struct iw_point *data = &wrqu->data;
934 	struct hostap_interface *iface;
935 	local_info_t *local;
936 	u16 val;
937 
938 	iface = netdev_priv(dev);
939 	local = iface->local;
940 
941 	if (iface->type == HOSTAP_INTERFACE_WDS)
942 		return -EOPNOTSUPP;
943 
944 	data->flags = 1; /* active */
945 	if (local->iw_mode == IW_MODE_MASTER) {
946 		data->length = strlen(local->essid);
947 		memcpy(essid, local->essid, IW_ESSID_MAX_SIZE);
948 	} else {
949 		int len;
950 		char ssid[MAX_SSID_LEN + 2];
951 		memset(ssid, 0, sizeof(ssid));
952 		len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID,
953 					   &ssid, MAX_SSID_LEN + 2, 0);
954 		val = le16_to_cpu(*(__le16 *) ssid);
955 		if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) {
956 			return -EOPNOTSUPP;
957 		}
958 		data->length = val;
959 		memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE);
960 	}
961 
962 	return 0;
963 }
964 
965 
prism2_ioctl_giwrange(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)966 static int prism2_ioctl_giwrange(struct net_device *dev,
967 				 struct iw_request_info *info,
968 				 union iwreq_data *wrqu, char *extra)
969 {
970 	struct iw_point *data = &wrqu->data;
971 	struct hostap_interface *iface;
972 	local_info_t *local;
973 	struct iw_range *range = (struct iw_range *) extra;
974 	u8 rates[10];
975 	u16 val;
976 	int i, len, over2;
977 
978 	iface = netdev_priv(dev);
979 	local = iface->local;
980 
981 	data->length = sizeof(struct iw_range);
982 	memset(range, 0, sizeof(struct iw_range));
983 
984 	/* TODO: could fill num_txpower and txpower array with
985 	 * something; however, there are 128 different values.. */
986 
987 	range->txpower_capa = IW_TXPOW_DBM;
988 
989 	if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC)
990 	{
991 		range->min_pmp = 1 * 1024;
992 		range->max_pmp = 65535 * 1024;
993 		range->min_pmt = 1 * 1024;
994 		range->max_pmt = 1000 * 1024;
995 		range->pmp_flags = IW_POWER_PERIOD;
996 		range->pmt_flags = IW_POWER_TIMEOUT;
997 		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
998 			IW_POWER_UNICAST_R | IW_POWER_ALL_R;
999 	}
1000 
1001 	range->we_version_compiled = WIRELESS_EXT;
1002 	range->we_version_source = 18;
1003 
1004 	range->retry_capa = IW_RETRY_LIMIT;
1005 	range->retry_flags = IW_RETRY_LIMIT;
1006 	range->min_retry = 0;
1007 	range->max_retry = 255;
1008 
1009 	range->num_channels = FREQ_COUNT;
1010 
1011 	val = 0;
1012 	for (i = 0; i < FREQ_COUNT; i++) {
1013 		if (local->channel_mask & (1 << i)) {
1014 			range->freq[val].i = i + 1;
1015 			range->freq[val].m = freq_list[i] * 100000;
1016 			range->freq[val].e = 1;
1017 			val++;
1018 		}
1019 		if (val == IW_MAX_FREQUENCIES)
1020 			break;
1021 	}
1022 	range->num_frequency = val;
1023 
1024 	if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1025 		range->max_qual.qual = 70; /* what is correct max? This was not
1026 					    * documented exactly. At least
1027 					    * 69 has been observed. */
1028 		range->max_qual.level = 0; /* dB */
1029 		range->max_qual.noise = 0; /* dB */
1030 
1031 		/* What would be suitable values for "average/typical" qual? */
1032 		range->avg_qual.qual = 20;
1033 		range->avg_qual.level = -60;
1034 		range->avg_qual.noise = -95;
1035 	} else {
1036 		range->max_qual.qual = 92; /* 0 .. 92 */
1037 		range->max_qual.level = 154; /* 27 .. 154 */
1038 		range->max_qual.noise = 154; /* 27 .. 154 */
1039 	}
1040 	range->sensitivity = 3;
1041 
1042 	range->max_encoding_tokens = WEP_KEYS;
1043 	range->num_encoding_sizes = 2;
1044 	range->encoding_size[0] = 5;
1045 	range->encoding_size[1] = 13;
1046 
1047 	over2 = 0;
1048 	len = prism2_get_datarates(dev, rates);
1049 	range->num_bitrates = 0;
1050 	for (i = 0; i < len; i++) {
1051 		if (range->num_bitrates < IW_MAX_BITRATES) {
1052 			range->bitrate[range->num_bitrates] =
1053 				rates[i] * 500000;
1054 			range->num_bitrates++;
1055 		}
1056 		if (rates[i] == 0x0b || rates[i] == 0x16)
1057 			over2 = 1;
1058 	}
1059 	/* estimated maximum TCP throughput values (bps) */
1060 	range->throughput = over2 ? 5500000 : 1500000;
1061 
1062 	range->min_rts = 0;
1063 	range->max_rts = 2347;
1064 	range->min_frag = 256;
1065 	range->max_frag = 2346;
1066 
1067 	/* Event capability (kernel + driver) */
1068 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1069 				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
1070 				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
1071 				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
1072 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
1073 	range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
1074 				IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
1075 				IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
1076 				IW_EVENT_CAPA_MASK(IWEVEXPIRED));
1077 
1078 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1079 		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1080 
1081 	if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
1082 		range->scan_capa = IW_SCAN_CAPA_ESSID;
1083 
1084 	return 0;
1085 }
1086 
1087 
hostap_monitor_mode_enable(local_info_t * local)1088 static int hostap_monitor_mode_enable(local_info_t *local)
1089 {
1090 	struct net_device *dev = local->dev;
1091 
1092 	printk(KERN_DEBUG "Enabling monitor mode\n");
1093 	hostap_monitor_set_type(local);
1094 
1095 	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1096 			    HFA384X_PORTTYPE_PSEUDO_IBSS)) {
1097 		printk(KERN_DEBUG "Port type setting for monitor mode "
1098 		       "failed\n");
1099 		return -EOPNOTSUPP;
1100 	}
1101 
1102 	/* Host decrypt is needed to get the IV and ICV fields;
1103 	 * however, monitor mode seems to remove WEP flag from frame
1104 	 * control field */
1105 	if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
1106 			    HFA384X_WEPFLAGS_HOSTENCRYPT |
1107 			    HFA384X_WEPFLAGS_HOSTDECRYPT)) {
1108 		printk(KERN_DEBUG "WEP flags setting failed\n");
1109 		return -EOPNOTSUPP;
1110 	}
1111 
1112 	if (local->func->reset_port(dev) ||
1113 	    local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1114 			     (HFA384X_TEST_MONITOR << 8),
1115 			     0, NULL, NULL)) {
1116 		printk(KERN_DEBUG "Setting monitor mode failed\n");
1117 		return -EOPNOTSUPP;
1118 	}
1119 
1120 	return 0;
1121 }
1122 
1123 
hostap_monitor_mode_disable(local_info_t * local)1124 static int hostap_monitor_mode_disable(local_info_t *local)
1125 {
1126 	struct net_device *dev = local->ddev;
1127 
1128 	if (dev == NULL)
1129 		return -1;
1130 
1131 	printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
1132 	dev->type = ARPHRD_ETHER;
1133 
1134 	if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1135 			     (HFA384X_TEST_STOP << 8),
1136 			     0, NULL, NULL))
1137 		return -1;
1138 	return hostap_set_encryption(local);
1139 }
1140 
1141 
prism2_ioctl_siwmode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1142 static int prism2_ioctl_siwmode(struct net_device *dev,
1143 				struct iw_request_info *info,
1144 				union iwreq_data *wrqu, char *extra)
1145 {
1146 	__u32 *mode = &wrqu->mode;
1147 	struct hostap_interface *iface;
1148 	local_info_t *local;
1149 	int double_reset = 0;
1150 
1151 	iface = netdev_priv(dev);
1152 	local = iface->local;
1153 
1154 	if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
1155 	    *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
1156 	    *mode != IW_MODE_MONITOR)
1157 		return -EOPNOTSUPP;
1158 
1159 #ifdef PRISM2_NO_STATION_MODES
1160 	if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA)
1161 		return -EOPNOTSUPP;
1162 #endif /* PRISM2_NO_STATION_MODES */
1163 
1164 	if (*mode == local->iw_mode)
1165 		return 0;
1166 
1167 	if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') {
1168 		printk(KERN_WARNING "%s: empty SSID not allowed in Master "
1169 		       "mode\n", dev->name);
1170 		return -EINVAL;
1171 	}
1172 
1173 	if (local->iw_mode == IW_MODE_MONITOR)
1174 		hostap_monitor_mode_disable(local);
1175 
1176 	if ((local->iw_mode == IW_MODE_ADHOC ||
1177 	     local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {
1178 		/* There seems to be a firmware bug in at least STA f/w v1.5.6
1179 		 * that leaves beacon frames to use IBSS type when moving from
1180 		 * IBSS to Host AP mode. Doing double Port0 reset seems to be
1181 		 * enough to workaround this. */
1182 		double_reset = 1;
1183 	}
1184 
1185 	printk(KERN_DEBUG "prism2: %s: operating mode changed "
1186 	       "%d -> %d\n", dev->name, local->iw_mode, *mode);
1187 	local->iw_mode = *mode;
1188 
1189 	if (local->iw_mode == IW_MODE_MONITOR)
1190 		hostap_monitor_mode_enable(local);
1191 	else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
1192 		 !local->fw_encrypt_ok) {
1193 		printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
1194 		       "a workaround for firmware bug in Host AP mode WEP\n",
1195 		       dev->name);
1196 		local->host_encrypt = 1;
1197 	}
1198 
1199 	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1200 			    hostap_get_porttype(local)))
1201 		return -EOPNOTSUPP;
1202 
1203 	if (local->func->reset_port(dev))
1204 		return -EINVAL;
1205 	if (double_reset && local->func->reset_port(dev))
1206 		return -EINVAL;
1207 
1208 	if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC)
1209 	{
1210 		/* netif_carrier is used only in client modes for now, so make
1211 		 * sure carrier is on when moving to non-client modes. */
1212 		netif_carrier_on(local->dev);
1213 		netif_carrier_on(local->ddev);
1214 	}
1215 	return 0;
1216 }
1217 
1218 
prism2_ioctl_giwmode(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1219 static int prism2_ioctl_giwmode(struct net_device *dev,
1220 				struct iw_request_info *info,
1221 				union iwreq_data *wrqu, char *extra)
1222 {
1223 	__u32 *mode = &wrqu->mode;
1224 	struct hostap_interface *iface;
1225 	local_info_t *local;
1226 
1227 	iface = netdev_priv(dev);
1228 	local = iface->local;
1229 
1230 	switch (iface->type) {
1231 	case HOSTAP_INTERFACE_STA:
1232 		*mode = IW_MODE_INFRA;
1233 		break;
1234 	case HOSTAP_INTERFACE_WDS:
1235 		*mode = IW_MODE_REPEAT;
1236 		break;
1237 	default:
1238 		*mode = local->iw_mode;
1239 		break;
1240 	}
1241 	return 0;
1242 }
1243 
1244 
prism2_ioctl_siwpower(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1245 static int prism2_ioctl_siwpower(struct net_device *dev,
1246 				 struct iw_request_info *info,
1247 				 union iwreq_data *wrqu, char *extra)
1248 {
1249 	struct iw_param *wrq = &wrqu->power;
1250 #ifdef PRISM2_NO_STATION_MODES
1251 	return -EOPNOTSUPP;
1252 #else /* PRISM2_NO_STATION_MODES */
1253 	int ret = 0;
1254 
1255 	if (wrq->disabled)
1256 		return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0);
1257 
1258 	switch (wrq->flags & IW_POWER_MODE) {
1259 	case IW_POWER_UNICAST_R:
1260 		ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0);
1261 		if (ret)
1262 			return ret;
1263 		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1264 		if (ret)
1265 			return ret;
1266 		break;
1267 	case IW_POWER_ALL_R:
1268 		ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1);
1269 		if (ret)
1270 			return ret;
1271 		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1272 		if (ret)
1273 			return ret;
1274 		break;
1275 	case IW_POWER_ON:
1276 		break;
1277 	default:
1278 		return -EINVAL;
1279 	}
1280 
1281 	if (wrq->flags & IW_POWER_TIMEOUT) {
1282 		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1283 		if (ret)
1284 			return ret;
1285 		ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION,
1286 				      wrq->value / 1024);
1287 		if (ret)
1288 			return ret;
1289 	}
1290 	if (wrq->flags & IW_POWER_PERIOD) {
1291 		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1292 		if (ret)
1293 			return ret;
1294 		ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1295 				      wrq->value / 1024);
1296 		if (ret)
1297 			return ret;
1298 	}
1299 
1300 	return ret;
1301 #endif /* PRISM2_NO_STATION_MODES */
1302 }
1303 
1304 
prism2_ioctl_giwpower(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1305 static int prism2_ioctl_giwpower(struct net_device *dev,
1306 				 struct iw_request_info *info,
1307 				 union iwreq_data *wrqu, char *extra)
1308 {
1309 	struct iw_param *rrq = &wrqu->power;
1310 #ifdef PRISM2_NO_STATION_MODES
1311 	return -EOPNOTSUPP;
1312 #else /* PRISM2_NO_STATION_MODES */
1313 	struct hostap_interface *iface;
1314 	local_info_t *local;
1315 	__le16 enable, mcast;
1316 
1317 	iface = netdev_priv(dev);
1318 	local = iface->local;
1319 
1320 	if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1)
1321 	    < 0)
1322 		return -EINVAL;
1323 
1324 	if (!le16_to_cpu(enable)) {
1325 		rrq->disabled = 1;
1326 		return 0;
1327 	}
1328 
1329 	rrq->disabled = 0;
1330 
1331 	if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1332 		__le16 timeout;
1333 		if (local->func->get_rid(dev,
1334 					 HFA384X_RID_CNFPMHOLDOVERDURATION,
1335 					 &timeout, 2, 1) < 0)
1336 			return -EINVAL;
1337 
1338 		rrq->flags = IW_POWER_TIMEOUT;
1339 		rrq->value = le16_to_cpu(timeout) * 1024;
1340 	} else {
1341 		__le16 period;
1342 		if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1343 					 &period, 2, 1) < 0)
1344 			return -EINVAL;
1345 
1346 		rrq->flags = IW_POWER_PERIOD;
1347 		rrq->value = le16_to_cpu(period) * 1024;
1348 	}
1349 
1350 	if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,
1351 				 2, 1) < 0)
1352 		return -EINVAL;
1353 
1354 	if (le16_to_cpu(mcast))
1355 		rrq->flags |= IW_POWER_ALL_R;
1356 	else
1357 		rrq->flags |= IW_POWER_UNICAST_R;
1358 
1359 	return 0;
1360 #endif /* PRISM2_NO_STATION_MODES */
1361 }
1362 
1363 
prism2_ioctl_siwretry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1364 static int prism2_ioctl_siwretry(struct net_device *dev,
1365 				 struct iw_request_info *info,
1366 				 union iwreq_data *wrqu, char *extra)
1367 {
1368 	struct iw_param *rrq = &wrqu->retry;
1369 	struct hostap_interface *iface;
1370 	local_info_t *local;
1371 
1372 	iface = netdev_priv(dev);
1373 	local = iface->local;
1374 
1375 	if (rrq->disabled)
1376 		return -EINVAL;
1377 
1378 	/* setting retry limits is not supported with the current station
1379 	 * firmware code; simulate this with alternative retry count for now */
1380 	if (rrq->flags == IW_RETRY_LIMIT) {
1381 		if (rrq->value < 0) {
1382 			/* disable manual retry count setting and use firmware
1383 			 * defaults */
1384 			local->manual_retry_count = -1;
1385 			local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;
1386 		} else {
1387 			if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1388 					    rrq->value)) {
1389 				printk(KERN_DEBUG "%s: Alternate retry count "
1390 				       "setting to %d failed\n",
1391 				       dev->name, rrq->value);
1392 				return -EOPNOTSUPP;
1393 			}
1394 
1395 			local->manual_retry_count = rrq->value;
1396 			local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
1397 		}
1398 		return 0;
1399 	}
1400 
1401 	return -EOPNOTSUPP;
1402 
1403 #if 0
1404 	/* what could be done, if firmware would support this.. */
1405 
1406 	if (rrq->flags & IW_RETRY_LIMIT) {
1407 		if (rrq->flags & IW_RETRY_LONG)
1408 			HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1409 		else if (rrq->flags & IW_RETRY_SHORT)
1410 			HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1411 		else {
1412 			HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1413 			HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1414 		}
1415 
1416 	}
1417 
1418 	if (rrq->flags & IW_RETRY_LIFETIME) {
1419 		HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024;
1420 	}
1421 
1422 	return 0;
1423 #endif /* 0 */
1424 }
1425 
prism2_ioctl_giwretry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1426 static int prism2_ioctl_giwretry(struct net_device *dev,
1427 				 struct iw_request_info *info,
1428 				 union iwreq_data *wrqu, char *extra)
1429 {
1430 	struct iw_param *rrq = &wrqu->retry;
1431 	struct hostap_interface *iface;
1432 	local_info_t *local;
1433 	__le16 shortretry, longretry, lifetime, altretry;
1434 
1435 	iface = netdev_priv(dev);
1436 	local = iface->local;
1437 
1438 	if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry,
1439 				 2, 1) < 0 ||
1440 	    local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry,
1441 				 2, 1) < 0 ||
1442 	    local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME,
1443 				 &lifetime, 2, 1) < 0)
1444 		return -EINVAL;
1445 
1446 	rrq->disabled = 0;
1447 
1448 	if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1449 		rrq->flags = IW_RETRY_LIFETIME;
1450 		rrq->value = le16_to_cpu(lifetime) * 1024;
1451 	} else {
1452 		if (local->manual_retry_count >= 0) {
1453 			rrq->flags = IW_RETRY_LIMIT;
1454 			if (local->func->get_rid(dev,
1455 						 HFA384X_RID_CNFALTRETRYCOUNT,
1456 						 &altretry, 2, 1) >= 0)
1457 				rrq->value = le16_to_cpu(altretry);
1458 			else
1459 				rrq->value = local->manual_retry_count;
1460 		} else if ((rrq->flags & IW_RETRY_LONG)) {
1461 			rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1462 			rrq->value = le16_to_cpu(longretry);
1463 		} else {
1464 			rrq->flags = IW_RETRY_LIMIT;
1465 			rrq->value = le16_to_cpu(shortretry);
1466 			if (shortretry != longretry)
1467 				rrq->flags |= IW_RETRY_SHORT;
1468 		}
1469 	}
1470 	return 0;
1471 }
1472 
1473 
1474 /* Note! This TX power controlling is experimental and should not be used in
1475  * production use. It just sets raw power register and does not use any kind of
1476  * feedback information from the measured TX power (CR58). This is now
1477  * commented out to make sure that it is not used by accident. TX power
1478  * configuration will be enabled again after proper algorithm using feedback
1479  * has been implemented. */
1480 
1481 #ifdef RAW_TXPOWER_SETTING
1482 /* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping..
1483  * This version assumes following mapping:
1484  * CR31 is 7-bit value with -64 to +63 range.
1485  * -64 is mapped into +20dBm and +63 into -43dBm.
1486  * This is certainly not an exact mapping for every card, but at least
1487  * increasing dBm value should correspond to increasing TX power.
1488  */
1489 
prism2_txpower_hfa386x_to_dBm(u16 val)1490 static int prism2_txpower_hfa386x_to_dBm(u16 val)
1491 {
1492 	signed char tmp;
1493 
1494 	if (val > 255)
1495 		val = 255;
1496 
1497 	tmp = val;
1498 	tmp >>= 2;
1499 
1500 	return -12 - tmp;
1501 }
1502 
prism2_txpower_dBm_to_hfa386x(int val)1503 static u16 prism2_txpower_dBm_to_hfa386x(int val)
1504 {
1505 	signed char tmp;
1506 
1507 	if (val > 20)
1508 		return 128;
1509 	else if (val < -43)
1510 		return 127;
1511 
1512 	tmp = val;
1513 	tmp = -12 - tmp;
1514 	tmp <<= 2;
1515 
1516 	return (unsigned char) tmp;
1517 }
1518 #endif /* RAW_TXPOWER_SETTING */
1519 
1520 
prism2_ioctl_siwtxpow(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1521 static int prism2_ioctl_siwtxpow(struct net_device *dev,
1522 				 struct iw_request_info *info,
1523 				 union iwreq_data *wrqu, char *extra)
1524 {
1525 	struct iw_param *rrq = &wrqu->txpower;
1526 	struct hostap_interface *iface;
1527 	local_info_t *local;
1528 #ifdef RAW_TXPOWER_SETTING
1529 	char *tmp;
1530 #endif
1531 	u16 val;
1532 	int ret = 0;
1533 
1534 	iface = netdev_priv(dev);
1535 	local = iface->local;
1536 
1537 	if (rrq->disabled) {
1538 		if (local->txpower_type != PRISM2_TXPOWER_OFF) {
1539 			val = 0xff; /* use all standby and sleep modes */
1540 			ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1541 					       HFA386X_CR_A_D_TEST_MODES2,
1542 					       &val, NULL);
1543 			printk(KERN_DEBUG "%s: Turning radio off: %s\n",
1544 			       dev->name, ret ? "failed" : "OK");
1545 			local->txpower_type = PRISM2_TXPOWER_OFF;
1546 		}
1547 		return (ret ? -EOPNOTSUPP : 0);
1548 	}
1549 
1550 	if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1551 		val = 0; /* disable all standby and sleep modes */
1552 		ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1553 				       HFA386X_CR_A_D_TEST_MODES2, &val, NULL);
1554 		printk(KERN_DEBUG "%s: Turning radio on: %s\n",
1555 		       dev->name, ret ? "failed" : "OK");
1556 		local->txpower_type = PRISM2_TXPOWER_UNKNOWN;
1557 	}
1558 
1559 #ifdef RAW_TXPOWER_SETTING
1560 	if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {
1561 		printk(KERN_DEBUG "Setting ALC on\n");
1562 		val = HFA384X_TEST_CFG_BIT_ALC;
1563 		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1564 				 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);
1565 		local->txpower_type = PRISM2_TXPOWER_AUTO;
1566 		return 0;
1567 	}
1568 
1569 	if (local->txpower_type != PRISM2_TXPOWER_FIXED) {
1570 		printk(KERN_DEBUG "Setting ALC off\n");
1571 		val = HFA384X_TEST_CFG_BIT_ALC;
1572 		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1573 				 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
1574 			local->txpower_type = PRISM2_TXPOWER_FIXED;
1575 	}
1576 
1577 	if (rrq->flags == IW_TXPOW_DBM)
1578 		tmp = "dBm";
1579 	else if (rrq->flags == IW_TXPOW_MWATT)
1580 		tmp = "mW";
1581 	else
1582 		tmp = "UNKNOWN";
1583 	printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);
1584 
1585 	if (rrq->flags != IW_TXPOW_DBM) {
1586 		printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");
1587 		return -EOPNOTSUPP;
1588 	}
1589 
1590 	local->txpower = rrq->value;
1591 	val = prism2_txpower_dBm_to_hfa386x(local->txpower);
1592 	if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1593 			     HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
1594 		ret = -EOPNOTSUPP;
1595 #else /* RAW_TXPOWER_SETTING */
1596 	if (rrq->fixed)
1597 		ret = -EOPNOTSUPP;
1598 #endif /* RAW_TXPOWER_SETTING */
1599 
1600 	return ret;
1601 }
1602 
prism2_ioctl_giwtxpow(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1603 static int prism2_ioctl_giwtxpow(struct net_device *dev,
1604 				 struct iw_request_info *info,
1605 				 union iwreq_data *wrqu, char *extra)
1606 {
1607 #ifdef RAW_TXPOWER_SETTING
1608 	struct iw_param *rrq = &wrqu->txpower;
1609 	struct hostap_interface *iface;
1610 	local_info_t *local;
1611 	u16 resp0;
1612 
1613 	iface = netdev_priv(dev);
1614 	local = iface->local;
1615 
1616 	rrq->flags = IW_TXPOW_DBM;
1617 	rrq->disabled = 0;
1618 	rrq->fixed = 0;
1619 
1620 	if (local->txpower_type == PRISM2_TXPOWER_AUTO) {
1621 		if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
1622 				     HFA386X_CR_MANUAL_TX_POWER,
1623 				     NULL, &resp0) == 0) {
1624 			rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
1625 		} else {
1626 			/* Could not get real txpower; guess 15 dBm */
1627 			rrq->value = 15;
1628 		}
1629 	} else if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1630 		rrq->value = 0;
1631 		rrq->disabled = 1;
1632 	} else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
1633 		rrq->value = local->txpower;
1634 		rrq->fixed = 1;
1635 	} else {
1636 		printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",
1637 		       local->txpower_type);
1638 	}
1639 	return 0;
1640 #else /* RAW_TXPOWER_SETTING */
1641 	return -EOPNOTSUPP;
1642 #endif /* RAW_TXPOWER_SETTING */
1643 }
1644 
1645 
1646 #ifndef PRISM2_NO_STATION_MODES
1647 
1648 /* HostScan request works with and without host_roaming mode. In addition, it
1649  * does not break current association. However, it requires newer station
1650  * firmware version (>= 1.3.1) than scan request. */
prism2_request_hostscan(struct net_device * dev,u8 * ssid,u8 ssid_len)1651 static int prism2_request_hostscan(struct net_device *dev,
1652 				   u8 *ssid, u8 ssid_len)
1653 {
1654 	struct hostap_interface *iface;
1655 	local_info_t *local;
1656 	struct hfa384x_hostscan_request scan_req;
1657 
1658 	iface = netdev_priv(dev);
1659 	local = iface->local;
1660 
1661 	memset(&scan_req, 0, sizeof(scan_req));
1662 	scan_req.channel_list = cpu_to_le16(local->channel_mask &
1663 					    local->scan_channel_mask);
1664 	scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
1665 	if (ssid) {
1666 		if (ssid_len > 32)
1667 			return -EINVAL;
1668 		scan_req.target_ssid_len = cpu_to_le16(ssid_len);
1669 		memcpy(scan_req.target_ssid, ssid, ssid_len);
1670 	}
1671 
1672 	if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
1673 				 sizeof(scan_req))) {
1674 		printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name);
1675 		return -EINVAL;
1676 	}
1677 	return 0;
1678 }
1679 
1680 
prism2_request_scan(struct net_device * dev)1681 static int prism2_request_scan(struct net_device *dev)
1682 {
1683 	struct hostap_interface *iface;
1684 	local_info_t *local;
1685 	struct hfa384x_scan_request scan_req;
1686 	int ret = 0;
1687 
1688 	iface = netdev_priv(dev);
1689 	local = iface->local;
1690 
1691 	memset(&scan_req, 0, sizeof(scan_req));
1692 	scan_req.channel_list = cpu_to_le16(local->channel_mask &
1693 					    local->scan_channel_mask);
1694 	scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
1695 
1696 	/* FIX:
1697 	 * It seems to be enough to set roaming mode for a short moment to
1698 	 * host-based and then setup scanrequest data and return the mode to
1699 	 * firmware-based.
1700 	 *
1701 	 * Master mode would need to drop to Managed mode for a short while
1702 	 * to make scanning work.. Or sweep through the different channels and
1703 	 * use passive scan based on beacons. */
1704 
1705 	if (!local->host_roaming)
1706 		hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1707 				HFA384X_ROAMING_HOST);
1708 
1709 	if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req,
1710 				 sizeof(scan_req))) {
1711 		printk(KERN_DEBUG "SCANREQUEST failed\n");
1712 		ret = -EINVAL;
1713 	}
1714 
1715 	if (!local->host_roaming)
1716 		hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1717 				HFA384X_ROAMING_FIRMWARE);
1718 
1719 	return ret;
1720 }
1721 
1722 #else /* !PRISM2_NO_STATION_MODES */
1723 
prism2_request_hostscan(struct net_device * dev,u8 * ssid,u8 ssid_len)1724 static inline int prism2_request_hostscan(struct net_device *dev,
1725 					  u8 *ssid, u8 ssid_len)
1726 {
1727 	return -EOPNOTSUPP;
1728 }
1729 
1730 
prism2_request_scan(struct net_device * dev)1731 static inline int prism2_request_scan(struct net_device *dev)
1732 {
1733 	return -EOPNOTSUPP;
1734 }
1735 
1736 #endif /* !PRISM2_NO_STATION_MODES */
1737 
1738 
prism2_ioctl_siwscan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1739 static int prism2_ioctl_siwscan(struct net_device *dev,
1740 				struct iw_request_info *info,
1741 				union iwreq_data *wrqu, char *extra)
1742 {
1743 	struct iw_point *data = &wrqu->data;
1744 	struct hostap_interface *iface;
1745 	local_info_t *local;
1746 	int ret;
1747 	u8 *ssid = NULL, ssid_len = 0;
1748 	struct iw_scan_req *req = (struct iw_scan_req *) extra;
1749 
1750 	iface = netdev_priv(dev);
1751 	local = iface->local;
1752 
1753 	if (data->length < sizeof(struct iw_scan_req))
1754 		req = NULL;
1755 
1756 	if (local->iw_mode == IW_MODE_MASTER) {
1757 		/* In master mode, we just return the results of our local
1758 		 * tables, so we don't need to start anything...
1759 		 * Jean II */
1760 		data->length = 0;
1761 		return 0;
1762 	}
1763 
1764 	if (!local->dev_enabled)
1765 		return -ENETDOWN;
1766 
1767 	if (req && data->flags & IW_SCAN_THIS_ESSID) {
1768 		ssid = req->essid;
1769 		ssid_len = req->essid_len;
1770 
1771 		if (ssid_len &&
1772 		    ((local->iw_mode != IW_MODE_INFRA &&
1773 		      local->iw_mode != IW_MODE_ADHOC) ||
1774 		     (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))))
1775 			return -EOPNOTSUPP;
1776 	}
1777 
1778 	if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
1779 		ret = prism2_request_hostscan(dev, ssid, ssid_len);
1780 	else
1781 		ret = prism2_request_scan(dev);
1782 
1783 	if (ret == 0)
1784 		local->scan_timestamp = jiffies;
1785 
1786 	/* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */
1787 
1788 	return ret;
1789 }
1790 
1791 
1792 #ifndef PRISM2_NO_STATION_MODES
__prism2_translate_scan(local_info_t * local,struct iw_request_info * info,struct hfa384x_hostscan_result * scan,struct hostap_bss_info * bss,char * current_ev,char * end_buf)1793 static char * __prism2_translate_scan(local_info_t *local,
1794 				      struct iw_request_info *info,
1795 				      struct hfa384x_hostscan_result *scan,
1796 				      struct hostap_bss_info *bss,
1797 				      char *current_ev, char *end_buf)
1798 {
1799 	int i, chan;
1800 	struct iw_event iwe;
1801 	char *current_val;
1802 	u16 capabilities;
1803 	u8 *pos;
1804 	u8 *ssid, *bssid;
1805 	size_t ssid_len;
1806 	char *buf;
1807 
1808 	if (bss) {
1809 		ssid = bss->ssid;
1810 		ssid_len = bss->ssid_len;
1811 		bssid = bss->bssid;
1812 	} else {
1813 		ssid = scan->ssid;
1814 		ssid_len = le16_to_cpu(scan->ssid_len);
1815 		bssid = scan->bssid;
1816 	}
1817 	if (ssid_len > 32)
1818 		ssid_len = 32;
1819 
1820 	/* First entry *MUST* be the AP MAC address */
1821 	memset(&iwe, 0, sizeof(iwe));
1822 	iwe.cmd = SIOCGIWAP;
1823 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1824 	memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1825 	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1826 					  IW_EV_ADDR_LEN);
1827 
1828 	/* Other entries will be displayed in the order we give them */
1829 
1830 	memset(&iwe, 0, sizeof(iwe));
1831 	iwe.cmd = SIOCGIWESSID;
1832 	iwe.u.data.length = ssid_len;
1833 	iwe.u.data.flags = 1;
1834 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1835 					  &iwe, ssid);
1836 
1837 	memset(&iwe, 0, sizeof(iwe));
1838 	iwe.cmd = SIOCGIWMODE;
1839 	if (bss) {
1840 		capabilities = bss->capab_info;
1841 	} else {
1842 		capabilities = le16_to_cpu(scan->capability);
1843 	}
1844 	if (capabilities & (WLAN_CAPABILITY_ESS |
1845 			    WLAN_CAPABILITY_IBSS)) {
1846 		if (capabilities & WLAN_CAPABILITY_ESS)
1847 			iwe.u.mode = IW_MODE_MASTER;
1848 		else
1849 			iwe.u.mode = IW_MODE_ADHOC;
1850 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1851 						  &iwe, IW_EV_UINT_LEN);
1852 	}
1853 
1854 	memset(&iwe, 0, sizeof(iwe));
1855 	iwe.cmd = SIOCGIWFREQ;
1856 	if (scan) {
1857 		chan = le16_to_cpu(scan->chid);
1858 	} else if (bss) {
1859 		chan = bss->chan;
1860 	} else {
1861 		chan = 0;
1862 	}
1863 
1864 	if (chan > 0) {
1865 		iwe.u.freq.m = freq_list[chan - 1] * 100000;
1866 		iwe.u.freq.e = 1;
1867 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1868 						  &iwe, IW_EV_FREQ_LEN);
1869 	}
1870 
1871 	if (scan) {
1872 		memset(&iwe, 0, sizeof(iwe));
1873 		iwe.cmd = IWEVQUAL;
1874 		if (local->last_scan_type == PRISM2_HOSTSCAN) {
1875 			iwe.u.qual.level = le16_to_cpu(scan->sl);
1876 			iwe.u.qual.noise = le16_to_cpu(scan->anl);
1877 		} else {
1878 			iwe.u.qual.level =
1879 				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));
1880 			iwe.u.qual.noise =
1881 				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
1882 		}
1883 		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
1884 			| IW_QUAL_NOISE_UPDATED
1885 			| IW_QUAL_QUAL_INVALID
1886 			| IW_QUAL_DBM;
1887 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1888 						  &iwe, IW_EV_QUAL_LEN);
1889 	}
1890 
1891 	memset(&iwe, 0, sizeof(iwe));
1892 	iwe.cmd = SIOCGIWENCODE;
1893 	if (capabilities & WLAN_CAPABILITY_PRIVACY)
1894 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1895 	else
1896 		iwe.u.data.flags = IW_ENCODE_DISABLED;
1897 	iwe.u.data.length = 0;
1898 	current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
1899 
1900 	/* TODO: add SuppRates into BSS table */
1901 	if (scan) {
1902 		memset(&iwe, 0, sizeof(iwe));
1903 		iwe.cmd = SIOCGIWRATE;
1904 		current_val = current_ev + iwe_stream_lcp_len(info);
1905 		pos = scan->sup_rates;
1906 		for (i = 0; i < sizeof(scan->sup_rates); i++) {
1907 			if (pos[i] == 0)
1908 				break;
1909 			/* Bit rate given in 500 kb/s units (+ 0x80) */
1910 			iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1911 			current_val = iwe_stream_add_value(
1912 				info, current_ev, current_val, end_buf, &iwe,
1913 				IW_EV_PARAM_LEN);
1914 		}
1915 		/* Check if we added any event */
1916 		if ((current_val - current_ev) > iwe_stream_lcp_len(info))
1917 			current_ev = current_val;
1918 	}
1919 
1920 	/* TODO: add BeaconInt,resp_rate,atim into BSS table */
1921 	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
1922 	if (buf && scan) {
1923 		memset(&iwe, 0, sizeof(iwe));
1924 		iwe.cmd = IWEVCUSTOM;
1925 		sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
1926 		iwe.u.data.length = strlen(buf);
1927 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1928 						  &iwe, buf);
1929 
1930 		memset(&iwe, 0, sizeof(iwe));
1931 		iwe.cmd = IWEVCUSTOM;
1932 		sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
1933 		iwe.u.data.length = strlen(buf);
1934 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1935 						  &iwe, buf);
1936 
1937 		if (local->last_scan_type == PRISM2_HOSTSCAN &&
1938 		    (capabilities & WLAN_CAPABILITY_IBSS)) {
1939 			memset(&iwe, 0, sizeof(iwe));
1940 			iwe.cmd = IWEVCUSTOM;
1941 			sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
1942 			iwe.u.data.length = strlen(buf);
1943 			current_ev = iwe_stream_add_point(info, current_ev,
1944 							  end_buf, &iwe, buf);
1945 		}
1946 	}
1947 	kfree(buf);
1948 
1949 	if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) {
1950 		memset(&iwe, 0, sizeof(iwe));
1951 		iwe.cmd = IWEVGENIE;
1952 		iwe.u.data.length = bss->wpa_ie_len;
1953 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1954 						  &iwe, bss->wpa_ie);
1955 	}
1956 
1957 	if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1958 		memset(&iwe, 0, sizeof(iwe));
1959 		iwe.cmd = IWEVGENIE;
1960 		iwe.u.data.length = bss->rsn_ie_len;
1961 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1962 						  &iwe, bss->rsn_ie);
1963 	}
1964 
1965 	return current_ev;
1966 }
1967 
1968 
1969 /* Translate scan data returned from the card to a card independent
1970  * format that the Wireless Tools will understand - Jean II */
prism2_translate_scan(local_info_t * local,struct iw_request_info * info,char * buffer,int buflen)1971 static inline int prism2_translate_scan(local_info_t *local,
1972 					struct iw_request_info *info,
1973 					char *buffer, int buflen)
1974 {
1975 	struct hfa384x_hostscan_result *scan;
1976 	int entry;
1977 	char *current_ev = buffer;
1978 	char *end_buf = buffer + buflen;
1979 	struct list_head *ptr;
1980 
1981 	spin_lock_bh(&local->lock);
1982 
1983 	list_for_each(ptr, &local->bss_list) {
1984 		struct hostap_bss_info *bss;
1985 		bss = list_entry(ptr, struct hostap_bss_info, list);
1986 		bss->included = 0;
1987 	}
1988 
1989 	for (entry = 0; entry < local->last_scan_results_count; entry++) {
1990 		int found = 0;
1991 		scan = &local->last_scan_results[entry];
1992 
1993 		/* Report every SSID if the AP is using multiple SSIDs. If no
1994 		 * BSS record is found (e.g., when WPA mode is disabled),
1995 		 * report the AP once. */
1996 		list_for_each(ptr, &local->bss_list) {
1997 			struct hostap_bss_info *bss;
1998 			bss = list_entry(ptr, struct hostap_bss_info, list);
1999 			if (ether_addr_equal(bss->bssid, scan->bssid)) {
2000 				bss->included = 1;
2001 				current_ev = __prism2_translate_scan(
2002 					local, info, scan, bss, current_ev,
2003 					end_buf);
2004 				found++;
2005 			}
2006 		}
2007 		if (!found) {
2008 			current_ev = __prism2_translate_scan(
2009 				local, info, scan, NULL, current_ev, end_buf);
2010 		}
2011 		/* Check if there is space for one more entry */
2012 		if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2013 			/* Ask user space to try again with a bigger buffer */
2014 			spin_unlock_bh(&local->lock);
2015 			return -E2BIG;
2016 		}
2017 	}
2018 
2019 	/* Prism2 firmware has limits (32 at least in some versions) for number
2020 	 * of BSSes in scan results. Extend this limit by using local BSS list.
2021 	 */
2022 	list_for_each(ptr, &local->bss_list) {
2023 		struct hostap_bss_info *bss;
2024 		bss = list_entry(ptr, struct hostap_bss_info, list);
2025 		if (bss->included)
2026 			continue;
2027 		current_ev = __prism2_translate_scan(local, info, NULL, bss,
2028 						     current_ev, end_buf);
2029 		/* Check if there is space for one more entry */
2030 		if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2031 			/* Ask user space to try again with a bigger buffer */
2032 			spin_unlock_bh(&local->lock);
2033 			return -E2BIG;
2034 		}
2035 	}
2036 
2037 	spin_unlock_bh(&local->lock);
2038 
2039 	return current_ev - buffer;
2040 }
2041 #endif /* PRISM2_NO_STATION_MODES */
2042 
2043 
prism2_ioctl_giwscan_sta(struct net_device * dev,struct iw_request_info * info,struct iw_point * data,char * extra)2044 static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2045 					   struct iw_request_info *info,
2046 					   struct iw_point *data, char *extra)
2047 {
2048 #ifdef PRISM2_NO_STATION_MODES
2049 	return -EOPNOTSUPP;
2050 #else /* PRISM2_NO_STATION_MODES */
2051 	struct hostap_interface *iface;
2052 	local_info_t *local;
2053 	int res;
2054 
2055 	iface = netdev_priv(dev);
2056 	local = iface->local;
2057 
2058 	/* Wait until the scan is finished. We can probably do better
2059 	 * than that - Jean II */
2060 	if (local->scan_timestamp &&
2061 	    time_before(jiffies, local->scan_timestamp + 3 * HZ)) {
2062 		/* Important note : we don't want to block the caller
2063 		 * until results are ready for various reasons.
2064 		 * First, managing wait queues is complex and racy
2065 		 * (there may be multiple simultaneous callers).
2066 		 * Second, we grab some rtnetlink lock before coming
2067 		 * here (in dev_ioctl()).
2068 		 * Third, the caller can wait on the Wireless Event
2069 		 * - Jean II */
2070 		return -EAGAIN;
2071 	}
2072 	local->scan_timestamp = 0;
2073 
2074 	res = prism2_translate_scan(local, info, extra, data->length);
2075 
2076 	if (res >= 0) {
2077 		data->length = res;
2078 		return 0;
2079 	} else {
2080 		data->length = 0;
2081 		return res;
2082 	}
2083 #endif /* PRISM2_NO_STATION_MODES */
2084 }
2085 
2086 
prism2_ioctl_giwscan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2087 static int prism2_ioctl_giwscan(struct net_device *dev,
2088 				struct iw_request_info *info,
2089 				union iwreq_data *wrqu, char *extra)
2090 {
2091 	struct iw_point *data = &wrqu->data;
2092 	struct hostap_interface *iface;
2093 	local_info_t *local;
2094 	int res;
2095 
2096 	iface = netdev_priv(dev);
2097 	local = iface->local;
2098 
2099 	if (local->iw_mode == IW_MODE_MASTER) {
2100 		/* In MASTER mode, it doesn't make sense to go around
2101 		 * scanning the frequencies and make the stations we serve
2102 		 * wait when what the user is really interested about is the
2103 		 * list of stations and access points we are talking to.
2104 		 * So, just extract results from our cache...
2105 		 * Jean II */
2106 
2107 		/* Translate to WE format */
2108 		res = prism2_ap_translate_scan(dev, info, extra);
2109 		if (res >= 0) {
2110 			printk(KERN_DEBUG "Scan result translation succeeded "
2111 			       "(length=%d)\n", res);
2112 			data->length = res;
2113 			return 0;
2114 		} else {
2115 			printk(KERN_DEBUG
2116 			       "Scan result translation failed (res=%d)\n",
2117 			       res);
2118 			data->length = 0;
2119 			return res;
2120 		}
2121 	} else {
2122 		/* Station mode */
2123 		return prism2_ioctl_giwscan_sta(dev, info, data, extra);
2124 	}
2125 }
2126 
2127 
2128 static const struct iw_priv_args prism2_priv[] = {
2129 	{ PRISM2_IOCTL_MONITOR,
2130 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
2131 	{ PRISM2_IOCTL_READMIF,
2132 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
2133 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
2134 	{ PRISM2_IOCTL_WRITEMIF,
2135 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, 0, "writemif" },
2136 	{ PRISM2_IOCTL_RESET,
2137 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "reset" },
2138 	{ PRISM2_IOCTL_INQUIRE,
2139 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inquire" },
2140 	{ PRISM2_IOCTL_SET_RID_WORD,
2141 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_rid_word" },
2142 	{ PRISM2_IOCTL_MACCMD,
2143 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maccmd" },
2144 	{ PRISM2_IOCTL_WDS_ADD,
2145 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_add" },
2146 	{ PRISM2_IOCTL_WDS_DEL,
2147 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_del" },
2148 	{ PRISM2_IOCTL_ADDMAC,
2149 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addmac" },
2150 	{ PRISM2_IOCTL_DELMAC,
2151 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "delmac" },
2152 	{ PRISM2_IOCTL_KICKMAC,
2153 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac" },
2154 	/* --- raw access to sub-ioctls --- */
2155 	{ PRISM2_IOCTL_PRISM2_PARAM,
2156 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "prism2_param" },
2157 	{ PRISM2_IOCTL_GET_PRISM2_PARAM,
2158 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2159 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprism2_param" },
2160 	/* --- sub-ioctls handlers --- */
2161 	{ PRISM2_IOCTL_PRISM2_PARAM,
2162 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2163 	{ PRISM2_IOCTL_GET_PRISM2_PARAM,
2164 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2165 	/* --- sub-ioctls definitions --- */
2166 	{ PRISM2_PARAM_TXRATECTRL,
2167 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txratectrl" },
2168 	{ PRISM2_PARAM_TXRATECTRL,
2169 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettxratectrl" },
2170 	{ PRISM2_PARAM_BEACON_INT,
2171 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_int" },
2172 	{ PRISM2_PARAM_BEACON_INT,
2173 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbeacon_int" },
2174 #ifndef PRISM2_NO_STATION_MODES
2175 	{ PRISM2_PARAM_PSEUDO_IBSS,
2176 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "pseudo_ibss" },
2177 	{ PRISM2_PARAM_PSEUDO_IBSS,
2178 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpseudo_ibss" },
2179 #endif /* PRISM2_NO_STATION_MODES */
2180 	{ PRISM2_PARAM_ALC,
2181 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "alc" },
2182 	{ PRISM2_PARAM_ALC,
2183 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getalc" },
2184 	{ PRISM2_PARAM_DUMP,
2185 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dump" },
2186 	{ PRISM2_PARAM_DUMP,
2187 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdump" },
2188 	{ PRISM2_PARAM_OTHER_AP_POLICY,
2189 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "other_ap_policy" },
2190 	{ PRISM2_PARAM_OTHER_AP_POLICY,
2191 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getother_ap_pol" },
2192 	{ PRISM2_PARAM_AP_MAX_INACTIVITY,
2193 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_inactivity" },
2194 	{ PRISM2_PARAM_AP_MAX_INACTIVITY,
2195 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_inactivi" },
2196 	{ PRISM2_PARAM_AP_BRIDGE_PACKETS,
2197 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bridge_packets" },
2198 	{ PRISM2_PARAM_AP_BRIDGE_PACKETS,
2199 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbridge_packe" },
2200 	{ PRISM2_PARAM_DTIM_PERIOD,
2201 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dtim_period" },
2202 	{ PRISM2_PARAM_DTIM_PERIOD,
2203 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdtim_period" },
2204 	{ PRISM2_PARAM_AP_NULLFUNC_ACK,
2205 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "nullfunc_ack" },
2206 	{ PRISM2_PARAM_AP_NULLFUNC_ACK,
2207 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getnullfunc_ack" },
2208 	{ PRISM2_PARAM_MAX_WDS,
2209 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_wds" },
2210 	{ PRISM2_PARAM_MAX_WDS,
2211 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_wds" },
2212 	{ PRISM2_PARAM_AP_AUTOM_AP_WDS,
2213 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "autom_ap_wds" },
2214 	{ PRISM2_PARAM_AP_AUTOM_AP_WDS,
2215 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getautom_ap_wds" },
2216 	{ PRISM2_PARAM_AP_AUTH_ALGS,
2217 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_auth_algs" },
2218 	{ PRISM2_PARAM_AP_AUTH_ALGS,
2219 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_auth_algs" },
2220 	{ PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2221 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "allow_fcserr" },
2222 	{ PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2223 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getallow_fcserr" },
2224 	{ PRISM2_PARAM_HOST_ENCRYPT,
2225 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_encrypt" },
2226 	{ PRISM2_PARAM_HOST_ENCRYPT,
2227 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_encrypt" },
2228 	{ PRISM2_PARAM_HOST_DECRYPT,
2229 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_decrypt" },
2230 	{ PRISM2_PARAM_HOST_DECRYPT,
2231 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_decrypt" },
2232 #ifndef PRISM2_NO_STATION_MODES
2233 	{ PRISM2_PARAM_HOST_ROAMING,
2234 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_roaming" },
2235 	{ PRISM2_PARAM_HOST_ROAMING,
2236 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_roaming" },
2237 #endif /* PRISM2_NO_STATION_MODES */
2238 	{ PRISM2_PARAM_BCRX_STA_KEY,
2239 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bcrx_sta_key" },
2240 	{ PRISM2_PARAM_BCRX_STA_KEY,
2241 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbcrx_sta_key" },
2242 	{ PRISM2_PARAM_IEEE_802_1X,
2243 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" },
2244 	{ PRISM2_PARAM_IEEE_802_1X,
2245 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" },
2246 	{ PRISM2_PARAM_ANTSEL_TX,
2247 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_tx" },
2248 	{ PRISM2_PARAM_ANTSEL_TX,
2249 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_tx" },
2250 	{ PRISM2_PARAM_ANTSEL_RX,
2251 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" },
2252 	{ PRISM2_PARAM_ANTSEL_RX,
2253 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" },
2254 	{ PRISM2_PARAM_MONITOR_TYPE,
2255 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" },
2256 	{ PRISM2_PARAM_MONITOR_TYPE,
2257 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" },
2258 	{ PRISM2_PARAM_WDS_TYPE,
2259 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" },
2260 	{ PRISM2_PARAM_WDS_TYPE,
2261 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwds_type" },
2262 	{ PRISM2_PARAM_HOSTSCAN,
2263 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostscan" },
2264 	{ PRISM2_PARAM_HOSTSCAN,
2265 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostscan" },
2266 	{ PRISM2_PARAM_AP_SCAN,
2267 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_scan" },
2268 	{ PRISM2_PARAM_AP_SCAN,
2269 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_scan" },
2270 	{ PRISM2_PARAM_ENH_SEC,
2271 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "enh_sec" },
2272 	{ PRISM2_PARAM_ENH_SEC,
2273 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getenh_sec" },
2274 #ifdef PRISM2_IO_DEBUG
2275 	{ PRISM2_PARAM_IO_DEBUG,
2276 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "io_debug" },
2277 	{ PRISM2_PARAM_IO_DEBUG,
2278 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getio_debug" },
2279 #endif /* PRISM2_IO_DEBUG */
2280 	{ PRISM2_PARAM_BASIC_RATES,
2281 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "basic_rates" },
2282 	{ PRISM2_PARAM_BASIC_RATES,
2283 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbasic_rates" },
2284 	{ PRISM2_PARAM_OPER_RATES,
2285 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oper_rates" },
2286 	{ PRISM2_PARAM_OPER_RATES,
2287 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getoper_rates" },
2288 	{ PRISM2_PARAM_HOSTAPD,
2289 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd" },
2290 	{ PRISM2_PARAM_HOSTAPD,
2291 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd" },
2292 	{ PRISM2_PARAM_HOSTAPD_STA,
2293 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd_sta" },
2294 	{ PRISM2_PARAM_HOSTAPD_STA,
2295 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd_sta" },
2296 	{ PRISM2_PARAM_WPA,
2297 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wpa" },
2298 	{ PRISM2_PARAM_WPA,
2299 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwpa" },
2300 	{ PRISM2_PARAM_PRIVACY_INVOKED,
2301 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "privacy_invoked" },
2302 	{ PRISM2_PARAM_PRIVACY_INVOKED,
2303 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprivacy_invo" },
2304 	{ PRISM2_PARAM_TKIP_COUNTERMEASURES,
2305 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "tkip_countermea" },
2306 	{ PRISM2_PARAM_TKIP_COUNTERMEASURES,
2307 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettkip_counter" },
2308 	{ PRISM2_PARAM_DROP_UNENCRYPTED,
2309 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" },
2310 	{ PRISM2_PARAM_DROP_UNENCRYPTED,
2311 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" },
2312 	{ PRISM2_PARAM_SCAN_CHANNEL_MASK,
2313 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "scan_channels" },
2314 	{ PRISM2_PARAM_SCAN_CHANNEL_MASK,
2315 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getscan_channel" },
2316 };
2317 
2318 
prism2_ioctl_priv_inquire(struct net_device * dev,int * i)2319 static int prism2_ioctl_priv_inquire(struct net_device *dev, int *i)
2320 {
2321 	struct hostap_interface *iface;
2322 	local_info_t *local;
2323 
2324 	iface = netdev_priv(dev);
2325 	local = iface->local;
2326 
2327 	if (local->func->cmd(dev, HFA384X_CMDCODE_INQUIRE, *i, NULL, NULL))
2328 		return -EOPNOTSUPP;
2329 
2330 	return 0;
2331 }
2332 
2333 
prism2_ioctl_priv_prism2_param(struct net_device * dev,struct iw_request_info * info,union iwreq_data * uwrq,char * extra)2334 static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2335 					  struct iw_request_info *info,
2336 					  union iwreq_data *uwrq, char *extra)
2337 {
2338 	struct hostap_interface *iface;
2339 	local_info_t *local;
2340 	int *i = (int *) extra;
2341 	int param = *i;
2342 	int value = *(i + 1);
2343 	int ret = 0;
2344 	u16 val;
2345 
2346 	iface = netdev_priv(dev);
2347 	local = iface->local;
2348 
2349 	switch (param) {
2350 	case PRISM2_PARAM_TXRATECTRL:
2351 		local->fw_tx_rate_control = value;
2352 		break;
2353 
2354 	case PRISM2_PARAM_BEACON_INT:
2355 		if (hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, value) ||
2356 		    local->func->reset_port(dev))
2357 			ret = -EINVAL;
2358 		else
2359 			local->beacon_int = value;
2360 		break;
2361 
2362 #ifndef PRISM2_NO_STATION_MODES
2363 	case PRISM2_PARAM_PSEUDO_IBSS:
2364 		if (value == local->pseudo_adhoc)
2365 			break;
2366 
2367 		if (value != 0 && value != 1) {
2368 			ret = -EINVAL;
2369 			break;
2370 		}
2371 
2372 		printk(KERN_DEBUG "prism2: %s: pseudo IBSS change %d -> %d\n",
2373 		       dev->name, local->pseudo_adhoc, value);
2374 		local->pseudo_adhoc = value;
2375 		if (local->iw_mode != IW_MODE_ADHOC)
2376 			break;
2377 
2378 		if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2379 				    hostap_get_porttype(local))) {
2380 			ret = -EOPNOTSUPP;
2381 			break;
2382 		}
2383 
2384 		if (local->func->reset_port(dev))
2385 			ret = -EINVAL;
2386 		break;
2387 #endif /* PRISM2_NO_STATION_MODES */
2388 
2389 	case PRISM2_PARAM_ALC:
2390 		printk(KERN_DEBUG "%s: %s ALC\n", dev->name,
2391 		       value == 0 ? "Disabling" : "Enabling");
2392 		val = HFA384X_TEST_CFG_BIT_ALC;
2393 		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
2394 				 (HFA384X_TEST_CFG_BITS << 8),
2395 				 value == 0 ? 0 : 1, &val, NULL);
2396 		break;
2397 
2398 	case PRISM2_PARAM_DUMP:
2399 		local->frame_dump = value;
2400 		break;
2401 
2402 	case PRISM2_PARAM_OTHER_AP_POLICY:
2403 		if (value < 0 || value > 3) {
2404 			ret = -EINVAL;
2405 			break;
2406 		}
2407 		if (local->ap != NULL)
2408 			local->ap->ap_policy = value;
2409 		break;
2410 
2411 	case PRISM2_PARAM_AP_MAX_INACTIVITY:
2412 		if (value < 0 || value > 7 * 24 * 60 * 60) {
2413 			ret = -EINVAL;
2414 			break;
2415 		}
2416 		if (local->ap != NULL)
2417 			local->ap->max_inactivity = value * HZ;
2418 		break;
2419 
2420 	case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2421 		if (local->ap != NULL)
2422 			local->ap->bridge_packets = value;
2423 		break;
2424 
2425 	case PRISM2_PARAM_DTIM_PERIOD:
2426 		if (value < 0 || value > 65535) {
2427 			ret = -EINVAL;
2428 			break;
2429 		}
2430 		if (hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, value)
2431 		    || local->func->reset_port(dev))
2432 			ret = -EINVAL;
2433 		else
2434 			local->dtim_period = value;
2435 		break;
2436 
2437 	case PRISM2_PARAM_AP_NULLFUNC_ACK:
2438 		if (local->ap != NULL)
2439 			local->ap->nullfunc_ack = value;
2440 		break;
2441 
2442 	case PRISM2_PARAM_MAX_WDS:
2443 		local->wds_max_connections = value;
2444 		break;
2445 
2446 	case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2447 		if (local->ap != NULL) {
2448 			if (!local->ap->autom_ap_wds && value) {
2449 				/* add WDS link to all APs in STA table */
2450 				hostap_add_wds_links(local);
2451 			}
2452 			local->ap->autom_ap_wds = value;
2453 		}
2454 		break;
2455 
2456 	case PRISM2_PARAM_AP_AUTH_ALGS:
2457 		local->auth_algs = value;
2458 		if (hostap_set_auth_algs(local))
2459 			ret = -EINVAL;
2460 		break;
2461 
2462 	case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2463 		local->monitor_allow_fcserr = value;
2464 		break;
2465 
2466 	case PRISM2_PARAM_HOST_ENCRYPT:
2467 		local->host_encrypt = value;
2468 		if (hostap_set_encryption(local) ||
2469 		    local->func->reset_port(dev))
2470 			ret = -EINVAL;
2471 		break;
2472 
2473 	case PRISM2_PARAM_HOST_DECRYPT:
2474 		local->host_decrypt = value;
2475 		if (hostap_set_encryption(local) ||
2476 		    local->func->reset_port(dev))
2477 			ret = -EINVAL;
2478 		break;
2479 
2480 #ifndef PRISM2_NO_STATION_MODES
2481 	case PRISM2_PARAM_HOST_ROAMING:
2482 		if (value < 0 || value > 2) {
2483 			ret = -EINVAL;
2484 			break;
2485 		}
2486 		local->host_roaming = value;
2487 		if (hostap_set_roaming(local) || local->func->reset_port(dev))
2488 			ret = -EINVAL;
2489 		break;
2490 #endif /* PRISM2_NO_STATION_MODES */
2491 
2492 	case PRISM2_PARAM_BCRX_STA_KEY:
2493 		local->bcrx_sta_key = value;
2494 		break;
2495 
2496 	case PRISM2_PARAM_IEEE_802_1X:
2497 		local->ieee_802_1x = value;
2498 		break;
2499 
2500 	case PRISM2_PARAM_ANTSEL_TX:
2501 		if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2502 			ret = -EINVAL;
2503 			break;
2504 		}
2505 		local->antsel_tx = value;
2506 		hostap_set_antsel(local);
2507 		break;
2508 
2509 	case PRISM2_PARAM_ANTSEL_RX:
2510 		if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2511 			ret = -EINVAL;
2512 			break;
2513 		}
2514 		local->antsel_rx = value;
2515 		hostap_set_antsel(local);
2516 		break;
2517 
2518 	case PRISM2_PARAM_MONITOR_TYPE:
2519 		if (value != PRISM2_MONITOR_80211 &&
2520 		    value != PRISM2_MONITOR_CAPHDR &&
2521 		    value != PRISM2_MONITOR_PRISM &&
2522 		    value != PRISM2_MONITOR_RADIOTAP) {
2523 			ret = -EINVAL;
2524 			break;
2525 		}
2526 		local->monitor_type = value;
2527 		if (local->iw_mode == IW_MODE_MONITOR)
2528 			hostap_monitor_set_type(local);
2529 		break;
2530 
2531 	case PRISM2_PARAM_WDS_TYPE:
2532 		local->wds_type = value;
2533 		break;
2534 
2535 	case PRISM2_PARAM_HOSTSCAN:
2536 	{
2537 		struct hfa384x_hostscan_request scan_req;
2538 		u16 rate;
2539 
2540 		memset(&scan_req, 0, sizeof(scan_req));
2541 		scan_req.channel_list = cpu_to_le16(0x3fff);
2542 		switch (value) {
2543 		case 1: rate = HFA384X_RATES_1MBPS; break;
2544 		case 2: rate = HFA384X_RATES_2MBPS; break;
2545 		case 3: rate = HFA384X_RATES_5MBPS; break;
2546 		case 4: rate = HFA384X_RATES_11MBPS; break;
2547 		default: rate = HFA384X_RATES_1MBPS; break;
2548 		}
2549 		scan_req.txrate = cpu_to_le16(rate);
2550 		/* leave SSID empty to accept all SSIDs */
2551 
2552 		if (local->iw_mode == IW_MODE_MASTER) {
2553 			if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2554 					    HFA384X_PORTTYPE_BSS) ||
2555 			    local->func->reset_port(dev))
2556 				printk(KERN_DEBUG "Leaving Host AP mode "
2557 				       "for HostScan failed\n");
2558 		}
2559 
2560 		if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
2561 					 sizeof(scan_req))) {
2562 			printk(KERN_DEBUG "HOSTSCAN failed\n");
2563 			ret = -EINVAL;
2564 		}
2565 		if (local->iw_mode == IW_MODE_MASTER) {
2566 			wait_queue_entry_t __wait;
2567 			init_waitqueue_entry(&__wait, current);
2568 			add_wait_queue(&local->hostscan_wq, &__wait);
2569 			set_current_state(TASK_INTERRUPTIBLE);
2570 			schedule_timeout(HZ);
2571 			if (signal_pending(current))
2572 				ret = -EINTR;
2573 			set_current_state(TASK_RUNNING);
2574 			remove_wait_queue(&local->hostscan_wq, &__wait);
2575 
2576 			if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2577 					    HFA384X_PORTTYPE_HOSTAP) ||
2578 			    local->func->reset_port(dev))
2579 				printk(KERN_DEBUG "Returning to Host AP mode "
2580 				       "after HostScan failed\n");
2581 		}
2582 		break;
2583 	}
2584 
2585 	case PRISM2_PARAM_AP_SCAN:
2586 		local->passive_scan_interval = value;
2587 		if (timer_pending(&local->passive_scan_timer))
2588 			del_timer(&local->passive_scan_timer);
2589 		if (value > 0 && value < INT_MAX / HZ) {
2590 			local->passive_scan_timer.expires = jiffies +
2591 				local->passive_scan_interval * HZ;
2592 			add_timer(&local->passive_scan_timer);
2593 		}
2594 		break;
2595 
2596 	case PRISM2_PARAM_ENH_SEC:
2597 		if (value < 0 || value > 3) {
2598 			ret = -EINVAL;
2599 			break;
2600 		}
2601 		local->enh_sec = value;
2602 		if (hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY,
2603 				    local->enh_sec) ||
2604 		    local->func->reset_port(dev)) {
2605 			printk(KERN_INFO "%s: cnfEnhSecurity requires STA f/w "
2606 			       "1.6.3 or newer\n", dev->name);
2607 			ret = -EOPNOTSUPP;
2608 		}
2609 		break;
2610 
2611 #ifdef PRISM2_IO_DEBUG
2612 	case PRISM2_PARAM_IO_DEBUG:
2613 		local->io_debug_enabled = value;
2614 		break;
2615 #endif /* PRISM2_IO_DEBUG */
2616 
2617 	case PRISM2_PARAM_BASIC_RATES:
2618 		if ((value & local->tx_rate_control) != value || value == 0) {
2619 			printk(KERN_INFO "%s: invalid basic rate set - basic "
2620 			       "rates must be in supported rate set\n",
2621 			       dev->name);
2622 			ret = -EINVAL;
2623 			break;
2624 		}
2625 		local->basic_rates = value;
2626 		if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
2627 				    local->basic_rates) ||
2628 		    local->func->reset_port(dev))
2629 			ret = -EINVAL;
2630 		break;
2631 
2632 	case PRISM2_PARAM_OPER_RATES:
2633 		local->tx_rate_control = value;
2634 		if (hostap_set_rate(dev))
2635 			ret = -EINVAL;
2636 		break;
2637 
2638 	case PRISM2_PARAM_HOSTAPD:
2639 		ret = hostap_set_hostapd(local, value, 1);
2640 		break;
2641 
2642 	case PRISM2_PARAM_HOSTAPD_STA:
2643 		ret = hostap_set_hostapd_sta(local, value, 1);
2644 		break;
2645 
2646 	case PRISM2_PARAM_WPA:
2647 		local->wpa = value;
2648 		if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2649 			ret = -EOPNOTSUPP;
2650 		else if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
2651 					 value ? 1 : 0))
2652 			ret = -EINVAL;
2653 		break;
2654 
2655 	case PRISM2_PARAM_PRIVACY_INVOKED:
2656 		local->privacy_invoked = value;
2657 		if (hostap_set_encryption(local) ||
2658 		    local->func->reset_port(dev))
2659 			ret = -EINVAL;
2660 		break;
2661 
2662 	case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2663 		local->tkip_countermeasures = value;
2664 		break;
2665 
2666 	case PRISM2_PARAM_DROP_UNENCRYPTED:
2667 		local->drop_unencrypted = value;
2668 		break;
2669 
2670 	case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2671 		local->scan_channel_mask = value;
2672 		break;
2673 
2674 	default:
2675 		printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
2676 		       dev->name, param);
2677 		ret = -EOPNOTSUPP;
2678 		break;
2679 	}
2680 
2681 	return ret;
2682 }
2683 
2684 
prism2_ioctl_priv_get_prism2_param(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2685 static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
2686 					      struct iw_request_info *info,
2687 					      union iwreq_data *wrqu, char *extra)
2688 {
2689 	struct hostap_interface *iface;
2690 	local_info_t *local;
2691 	int *param = (int *) extra;
2692 	int ret = 0;
2693 
2694 	iface = netdev_priv(dev);
2695 	local = iface->local;
2696 
2697 	switch (*param) {
2698 	case PRISM2_PARAM_TXRATECTRL:
2699 		*param = local->fw_tx_rate_control;
2700 		break;
2701 
2702 	case PRISM2_PARAM_BEACON_INT:
2703 		*param = local->beacon_int;
2704 		break;
2705 
2706 	case PRISM2_PARAM_PSEUDO_IBSS:
2707 		*param = local->pseudo_adhoc;
2708 		break;
2709 
2710 	case PRISM2_PARAM_ALC:
2711 		ret = -EOPNOTSUPP; /* FIX */
2712 		break;
2713 
2714 	case PRISM2_PARAM_DUMP:
2715 		*param = local->frame_dump;
2716 		break;
2717 
2718 	case PRISM2_PARAM_OTHER_AP_POLICY:
2719 		if (local->ap != NULL)
2720 			*param = local->ap->ap_policy;
2721 		else
2722 			ret = -EOPNOTSUPP;
2723 		break;
2724 
2725 	case PRISM2_PARAM_AP_MAX_INACTIVITY:
2726 		if (local->ap != NULL)
2727 			*param = local->ap->max_inactivity / HZ;
2728 		else
2729 			ret = -EOPNOTSUPP;
2730 		break;
2731 
2732 	case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2733 		if (local->ap != NULL)
2734 			*param = local->ap->bridge_packets;
2735 		else
2736 			ret = -EOPNOTSUPP;
2737 		break;
2738 
2739 	case PRISM2_PARAM_DTIM_PERIOD:
2740 		*param = local->dtim_period;
2741 		break;
2742 
2743 	case PRISM2_PARAM_AP_NULLFUNC_ACK:
2744 		if (local->ap != NULL)
2745 			*param = local->ap->nullfunc_ack;
2746 		else
2747 			ret = -EOPNOTSUPP;
2748 		break;
2749 
2750 	case PRISM2_PARAM_MAX_WDS:
2751 		*param = local->wds_max_connections;
2752 		break;
2753 
2754 	case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2755 		if (local->ap != NULL)
2756 			*param = local->ap->autom_ap_wds;
2757 		else
2758 			ret = -EOPNOTSUPP;
2759 		break;
2760 
2761 	case PRISM2_PARAM_AP_AUTH_ALGS:
2762 		*param = local->auth_algs;
2763 		break;
2764 
2765 	case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2766 		*param = local->monitor_allow_fcserr;
2767 		break;
2768 
2769 	case PRISM2_PARAM_HOST_ENCRYPT:
2770 		*param = local->host_encrypt;
2771 		break;
2772 
2773 	case PRISM2_PARAM_HOST_DECRYPT:
2774 		*param = local->host_decrypt;
2775 		break;
2776 
2777 	case PRISM2_PARAM_HOST_ROAMING:
2778 		*param = local->host_roaming;
2779 		break;
2780 
2781 	case PRISM2_PARAM_BCRX_STA_KEY:
2782 		*param = local->bcrx_sta_key;
2783 		break;
2784 
2785 	case PRISM2_PARAM_IEEE_802_1X:
2786 		*param = local->ieee_802_1x;
2787 		break;
2788 
2789 	case PRISM2_PARAM_ANTSEL_TX:
2790 		*param = local->antsel_tx;
2791 		break;
2792 
2793 	case PRISM2_PARAM_ANTSEL_RX:
2794 		*param = local->antsel_rx;
2795 		break;
2796 
2797 	case PRISM2_PARAM_MONITOR_TYPE:
2798 		*param = local->monitor_type;
2799 		break;
2800 
2801 	case PRISM2_PARAM_WDS_TYPE:
2802 		*param = local->wds_type;
2803 		break;
2804 
2805 	case PRISM2_PARAM_HOSTSCAN:
2806 		ret = -EOPNOTSUPP;
2807 		break;
2808 
2809 	case PRISM2_PARAM_AP_SCAN:
2810 		*param = local->passive_scan_interval;
2811 		break;
2812 
2813 	case PRISM2_PARAM_ENH_SEC:
2814 		*param = local->enh_sec;
2815 		break;
2816 
2817 #ifdef PRISM2_IO_DEBUG
2818 	case PRISM2_PARAM_IO_DEBUG:
2819 		*param = local->io_debug_enabled;
2820 		break;
2821 #endif /* PRISM2_IO_DEBUG */
2822 
2823 	case PRISM2_PARAM_BASIC_RATES:
2824 		*param = local->basic_rates;
2825 		break;
2826 
2827 	case PRISM2_PARAM_OPER_RATES:
2828 		*param = local->tx_rate_control;
2829 		break;
2830 
2831 	case PRISM2_PARAM_HOSTAPD:
2832 		*param = local->hostapd;
2833 		break;
2834 
2835 	case PRISM2_PARAM_HOSTAPD_STA:
2836 		*param = local->hostapd_sta;
2837 		break;
2838 
2839 	case PRISM2_PARAM_WPA:
2840 		if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2841 			ret = -EOPNOTSUPP;
2842 		*param = local->wpa;
2843 		break;
2844 
2845 	case PRISM2_PARAM_PRIVACY_INVOKED:
2846 		*param = local->privacy_invoked;
2847 		break;
2848 
2849 	case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2850 		*param = local->tkip_countermeasures;
2851 		break;
2852 
2853 	case PRISM2_PARAM_DROP_UNENCRYPTED:
2854 		*param = local->drop_unencrypted;
2855 		break;
2856 
2857 	case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2858 		*param = local->scan_channel_mask;
2859 		break;
2860 
2861 	default:
2862 		printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
2863 		       dev->name, *param);
2864 		ret = -EOPNOTSUPP;
2865 		break;
2866 	}
2867 
2868 	return ret;
2869 }
2870 
2871 
prism2_ioctl_priv_readmif(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2872 static int prism2_ioctl_priv_readmif(struct net_device *dev,
2873 				     struct iw_request_info *info,
2874 				     union iwreq_data *wrqu, char *extra)
2875 {
2876 	struct hostap_interface *iface;
2877 	local_info_t *local;
2878 	u16 resp0;
2879 
2880 	iface = netdev_priv(dev);
2881 	local = iface->local;
2882 
2883 	if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, *extra, NULL,
2884 			     &resp0))
2885 		return -EOPNOTSUPP;
2886 	else
2887 		*extra = resp0;
2888 
2889 	return 0;
2890 }
2891 
2892 
prism2_ioctl_priv_writemif(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2893 static int prism2_ioctl_priv_writemif(struct net_device *dev,
2894 				      struct iw_request_info *info,
2895 				      union iwreq_data *wrqu, char *extra)
2896 {
2897 	struct hostap_interface *iface;
2898 	local_info_t *local;
2899 	u16 cr, val;
2900 
2901 	iface = netdev_priv(dev);
2902 	local = iface->local;
2903 
2904 	cr = *extra;
2905 	val = *(extra + 1);
2906 	if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, cr, &val, NULL))
2907 		return -EOPNOTSUPP;
2908 
2909 	return 0;
2910 }
2911 
2912 
prism2_ioctl_priv_monitor(struct net_device * dev,int * i)2913 static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
2914 {
2915 	struct hostap_interface *iface;
2916 	local_info_t *local;
2917 	int ret = 0;
2918 	union iwreq_data wrqu;
2919 
2920 	iface = netdev_priv(dev);
2921 	local = iface->local;
2922 
2923 	printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
2924 	       "- update software to use iwconfig mode monitor\n",
2925 	       dev->name, task_pid_nr(current), current->comm);
2926 
2927 	/* Backward compatibility code - this can be removed at some point */
2928 
2929 	if (*i == 0) {
2930 		/* Disable monitor mode - old mode was not saved, so go to
2931 		 * Master mode */
2932 		wrqu.mode = IW_MODE_MASTER;
2933 		ret = prism2_ioctl_siwmode(dev, NULL, &wrqu, NULL);
2934 	} else if (*i == 1) {
2935 		/* netlink socket mode is not supported anymore since it did
2936 		 * not separate different devices from each other and was not
2937 		 * best method for delivering large amount of packets to
2938 		 * user space */
2939 		ret = -EOPNOTSUPP;
2940 	} else if (*i == 2 || *i == 3) {
2941 		switch (*i) {
2942 		case 2:
2943 			local->monitor_type = PRISM2_MONITOR_80211;
2944 			break;
2945 		case 3:
2946 			local->monitor_type = PRISM2_MONITOR_PRISM;
2947 			break;
2948 		}
2949 		wrqu.mode = IW_MODE_MONITOR;
2950 		ret = prism2_ioctl_siwmode(dev, NULL, &wrqu, NULL);
2951 		hostap_monitor_mode_enable(local);
2952 	} else
2953 		ret = -EINVAL;
2954 
2955 	return ret;
2956 }
2957 
2958 
prism2_ioctl_priv_reset(struct net_device * dev,int * i)2959 static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
2960 {
2961 	struct hostap_interface *iface;
2962 	local_info_t *local;
2963 
2964 	iface = netdev_priv(dev);
2965 	local = iface->local;
2966 
2967 	printk(KERN_DEBUG "%s: manual reset request(%d)\n", dev->name, *i);
2968 	switch (*i) {
2969 	case 0:
2970 		/* Disable and enable card */
2971 		local->func->hw_shutdown(dev, 1);
2972 		local->func->hw_config(dev, 0);
2973 		break;
2974 
2975 	case 1:
2976 		/* COR sreset */
2977 		local->func->hw_reset(dev);
2978 		break;
2979 
2980 	case 2:
2981 		/* Disable and enable port 0 */
2982 		local->func->reset_port(dev);
2983 		break;
2984 
2985 	case 3:
2986 		prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
2987 		if (local->func->cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL,
2988 				     NULL))
2989 			return -EINVAL;
2990 		break;
2991 
2992 	case 4:
2993 		if (local->func->cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL,
2994 				     NULL))
2995 			return -EINVAL;
2996 		break;
2997 
2998 	default:
2999 		printk(KERN_DEBUG "Unknown reset request %d\n", *i);
3000 		return -EOPNOTSUPP;
3001 	}
3002 
3003 	return 0;
3004 }
3005 
3006 
prism2_ioctl_priv_set_rid_word(struct net_device * dev,int * i)3007 static int prism2_ioctl_priv_set_rid_word(struct net_device *dev, int *i)
3008 {
3009 	int rid = *i;
3010 	int value = *(i + 1);
3011 
3012 	printk(KERN_DEBUG "%s: Set RID[0x%X] = %d\n", dev->name, rid, value);
3013 
3014 	if (hostap_set_word(dev, rid, value))
3015 		return -EINVAL;
3016 
3017 	return 0;
3018 }
3019 
3020 
3021 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
ap_mac_cmd_ioctl(local_info_t * local,int * cmd)3022 static int ap_mac_cmd_ioctl(local_info_t *local, int *cmd)
3023 {
3024 	int ret = 0;
3025 
3026 	switch (*cmd) {
3027 	case AP_MAC_CMD_POLICY_OPEN:
3028 		local->ap->mac_restrictions.policy = MAC_POLICY_OPEN;
3029 		break;
3030 	case AP_MAC_CMD_POLICY_ALLOW:
3031 		local->ap->mac_restrictions.policy = MAC_POLICY_ALLOW;
3032 		break;
3033 	case AP_MAC_CMD_POLICY_DENY:
3034 		local->ap->mac_restrictions.policy = MAC_POLICY_DENY;
3035 		break;
3036 	case AP_MAC_CMD_FLUSH:
3037 		ap_control_flush_macs(&local->ap->mac_restrictions);
3038 		break;
3039 	case AP_MAC_CMD_KICKALL:
3040 		ap_control_kickall(local->ap);
3041 		hostap_deauth_all_stas(local->dev, local->ap, 0);
3042 		break;
3043 	default:
3044 		ret = -EOPNOTSUPP;
3045 		break;
3046 	}
3047 
3048 	return ret;
3049 }
3050 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3051 
3052 
3053 #ifdef PRISM2_DOWNLOAD_SUPPORT
prism2_ioctl_priv_download(local_info_t * local,struct iw_point * p)3054 static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
3055 {
3056 	struct prism2_download_param *param;
3057 	int ret = 0;
3058 
3059 	if (p->length < sizeof(struct prism2_download_param) ||
3060 	    p->length > 1024 || !p->pointer)
3061 		return -EINVAL;
3062 
3063 	param = memdup_user(p->pointer, p->length);
3064 	if (IS_ERR(param)) {
3065 		return PTR_ERR(param);
3066 	}
3067 
3068 	if (p->length < sizeof(struct prism2_download_param) +
3069 	    param->num_areas * sizeof(struct prism2_download_area)) {
3070 		ret = -EINVAL;
3071 		goto out;
3072 	}
3073 
3074 	ret = local->func->download(local, param);
3075 
3076  out:
3077 	kfree(param);
3078 	return ret;
3079 }
3080 #endif /* PRISM2_DOWNLOAD_SUPPORT */
3081 
3082 
prism2_set_genericelement(struct net_device * dev,u8 * elem,size_t len)3083 static int prism2_set_genericelement(struct net_device *dev, u8 *elem,
3084 				     size_t len)
3085 {
3086 	struct hostap_interface *iface = netdev_priv(dev);
3087 	local_info_t *local = iface->local;
3088 	u8 *buf;
3089 
3090 	/*
3091 	 * Add 16-bit length in the beginning of the buffer because Prism2 RID
3092 	 * includes it.
3093 	 */
3094 	buf = kmalloc(len + 2, GFP_KERNEL);
3095 	if (buf == NULL)
3096 		return -ENOMEM;
3097 
3098 	*((__le16 *) buf) = cpu_to_le16(len);
3099 	memcpy(buf + 2, elem, len);
3100 
3101 	kfree(local->generic_elem);
3102 	local->generic_elem = buf;
3103 	local->generic_elem_len = len + 2;
3104 
3105 	return local->func->set_rid(local->dev, HFA384X_RID_GENERICELEMENT,
3106 				    buf, len + 2);
3107 }
3108 
3109 
prism2_ioctl_siwauth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3110 static int prism2_ioctl_siwauth(struct net_device *dev,
3111 				struct iw_request_info *info,
3112 				union iwreq_data *wrqu, char *extra)
3113 {
3114 	struct iw_param *data = &wrqu->param;
3115 	struct hostap_interface *iface = netdev_priv(dev);
3116 	local_info_t *local = iface->local;
3117 
3118 	switch (data->flags & IW_AUTH_INDEX) {
3119 	case IW_AUTH_WPA_VERSION:
3120 	case IW_AUTH_CIPHER_PAIRWISE:
3121 	case IW_AUTH_CIPHER_GROUP:
3122 	case IW_AUTH_KEY_MGMT:
3123 		/*
3124 		 * Host AP driver does not use these parameters and allows
3125 		 * wpa_supplicant to control them internally.
3126 		 */
3127 		break;
3128 	case IW_AUTH_TKIP_COUNTERMEASURES:
3129 		local->tkip_countermeasures = data->value;
3130 		break;
3131 	case IW_AUTH_DROP_UNENCRYPTED:
3132 		local->drop_unencrypted = data->value;
3133 		break;
3134 	case IW_AUTH_80211_AUTH_ALG:
3135 		local->auth_algs = data->value;
3136 		break;
3137 	case IW_AUTH_WPA_ENABLED:
3138 		if (data->value == 0) {
3139 			local->wpa = 0;
3140 			if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3141 				break;
3142 			prism2_set_genericelement(dev, "", 0);
3143 			local->host_roaming = 0;
3144 			local->privacy_invoked = 0;
3145 			if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
3146 					    0) ||
3147 			    hostap_set_roaming(local) ||
3148 			    hostap_set_encryption(local) ||
3149 			    local->func->reset_port(dev))
3150 				return -EINVAL;
3151 			break;
3152 		}
3153 		if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3154 			return -EOPNOTSUPP;
3155 		local->host_roaming = 2;
3156 		local->privacy_invoked = 1;
3157 		local->wpa = 1;
3158 		if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1) ||
3159 		    hostap_set_roaming(local) ||
3160 		    hostap_set_encryption(local) ||
3161 		    local->func->reset_port(dev))
3162 			return -EINVAL;
3163 		break;
3164 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3165 		local->ieee_802_1x = data->value;
3166 		break;
3167 	case IW_AUTH_PRIVACY_INVOKED:
3168 		local->privacy_invoked = data->value;
3169 		break;
3170 	default:
3171 		return -EOPNOTSUPP;
3172 	}
3173 	return 0;
3174 }
3175 
3176 
prism2_ioctl_giwauth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3177 static int prism2_ioctl_giwauth(struct net_device *dev,
3178 				struct iw_request_info *info,
3179 				union iwreq_data *wrqu, char *extra)
3180 {
3181 	struct iw_param *data = &wrqu->param;
3182 	struct hostap_interface *iface = netdev_priv(dev);
3183 	local_info_t *local = iface->local;
3184 
3185 	switch (data->flags & IW_AUTH_INDEX) {
3186 	case IW_AUTH_WPA_VERSION:
3187 	case IW_AUTH_CIPHER_PAIRWISE:
3188 	case IW_AUTH_CIPHER_GROUP:
3189 	case IW_AUTH_KEY_MGMT:
3190 		/*
3191 		 * Host AP driver does not use these parameters and allows
3192 		 * wpa_supplicant to control them internally.
3193 		 */
3194 		return -EOPNOTSUPP;
3195 	case IW_AUTH_TKIP_COUNTERMEASURES:
3196 		data->value = local->tkip_countermeasures;
3197 		break;
3198 	case IW_AUTH_DROP_UNENCRYPTED:
3199 		data->value = local->drop_unencrypted;
3200 		break;
3201 	case IW_AUTH_80211_AUTH_ALG:
3202 		data->value = local->auth_algs;
3203 		break;
3204 	case IW_AUTH_WPA_ENABLED:
3205 		data->value = local->wpa;
3206 		break;
3207 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3208 		data->value = local->ieee_802_1x;
3209 		break;
3210 	default:
3211 		return -EOPNOTSUPP;
3212 	}
3213 	return 0;
3214 }
3215 
3216 
prism2_ioctl_siwencodeext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3217 static int prism2_ioctl_siwencodeext(struct net_device *dev,
3218 				     struct iw_request_info *info,
3219 				     union iwreq_data *wrqu, char *extra)
3220 {
3221 	struct iw_point *erq = &wrqu->encoding;
3222 	struct hostap_interface *iface = netdev_priv(dev);
3223 	local_info_t *local = iface->local;
3224 	struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3225 	int i, ret = 0;
3226 	struct lib80211_crypto_ops *ops;
3227 	struct lib80211_crypt_data **crypt;
3228 	void *sta_ptr;
3229 	u8 *addr;
3230 	const char *alg, *module;
3231 
3232 	i = erq->flags & IW_ENCODE_INDEX;
3233 	if (i > WEP_KEYS)
3234 		return -EINVAL;
3235 	if (i < 1 || i > WEP_KEYS)
3236 		i = local->crypt_info.tx_keyidx;
3237 	else
3238 		i--;
3239 	if (i < 0 || i >= WEP_KEYS)
3240 		return -EINVAL;
3241 
3242 	addr = ext->addr.sa_data;
3243 	if (is_broadcast_ether_addr(addr)) {
3244 		sta_ptr = NULL;
3245 		crypt = &local->crypt_info.crypt[i];
3246 	} else {
3247 		if (i != 0)
3248 			return -EINVAL;
3249 		sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3250 		if (sta_ptr == NULL) {
3251 			if (local->iw_mode == IW_MODE_INFRA) {
3252 				/*
3253 				 * TODO: add STA entry for the current AP so
3254 				 * that unicast key can be used. For now, this
3255 				 * is emulated by using default key idx 0.
3256 				 */
3257 				i = 0;
3258 				crypt = &local->crypt_info.crypt[i];
3259 			} else
3260 				return -EINVAL;
3261 		}
3262 	}
3263 
3264 	if ((erq->flags & IW_ENCODE_DISABLED) ||
3265 	    ext->alg == IW_ENCODE_ALG_NONE) {
3266 		if (*crypt)
3267 			lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3268 		goto done;
3269 	}
3270 
3271 	switch (ext->alg) {
3272 	case IW_ENCODE_ALG_WEP:
3273 		alg = "WEP";
3274 		module = "lib80211_crypt_wep";
3275 		break;
3276 	case IW_ENCODE_ALG_TKIP:
3277 		alg = "TKIP";
3278 		module = "lib80211_crypt_tkip";
3279 		break;
3280 	case IW_ENCODE_ALG_CCMP:
3281 		alg = "CCMP";
3282 		module = "lib80211_crypt_ccmp";
3283 		break;
3284 	default:
3285 		printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
3286 		       local->dev->name, ext->alg);
3287 		ret = -EOPNOTSUPP;
3288 		goto done;
3289 	}
3290 
3291 	ops = lib80211_get_crypto_ops(alg);
3292 	if (ops == NULL) {
3293 		request_module(module);
3294 		ops = lib80211_get_crypto_ops(alg);
3295 	}
3296 	if (ops == NULL) {
3297 		printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3298 		       local->dev->name, alg);
3299 		ret = -EOPNOTSUPP;
3300 		goto done;
3301 	}
3302 
3303 	if (sta_ptr || ext->alg != IW_ENCODE_ALG_WEP) {
3304 		/*
3305 		 * Per station encryption and other than WEP algorithms
3306 		 * require host-based encryption, so force them on
3307 		 * automatically.
3308 		 */
3309 		local->host_decrypt = local->host_encrypt = 1;
3310 	}
3311 
3312 	if (*crypt == NULL || (*crypt)->ops != ops) {
3313 		struct lib80211_crypt_data *new_crypt;
3314 
3315 		lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3316 
3317 		new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
3318 				GFP_KERNEL);
3319 		if (new_crypt == NULL) {
3320 			ret = -ENOMEM;
3321 			goto done;
3322 		}
3323 		new_crypt->ops = ops;
3324 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3325 			new_crypt->priv = new_crypt->ops->init(i);
3326 		if (new_crypt->priv == NULL) {
3327 			kfree(new_crypt);
3328 			ret = -EINVAL;
3329 			goto done;
3330 		}
3331 
3332 		*crypt = new_crypt;
3333 	}
3334 
3335 	/*
3336 	 * TODO: if ext_flags does not have IW_ENCODE_EXT_RX_SEQ_VALID, the
3337 	 * existing seq# should not be changed.
3338 	 * TODO: if ext_flags has IW_ENCODE_EXT_TX_SEQ_VALID, next TX seq#
3339 	 * should be changed to something else than zero.
3340 	 */
3341 	if ((!(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) || ext->key_len > 0)
3342 	    && (*crypt)->ops->set_key &&
3343 	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
3344 				   (*crypt)->priv) < 0) {
3345 		printk(KERN_DEBUG "%s: key setting failed\n",
3346 		       local->dev->name);
3347 		ret = -EINVAL;
3348 		goto done;
3349 	}
3350 
3351 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3352 		if (!sta_ptr)
3353 			local->crypt_info.tx_keyidx = i;
3354 	}
3355 
3356 
3357 	if (sta_ptr == NULL && ext->key_len > 0) {
3358 		int first = 1, j;
3359 		for (j = 0; j < WEP_KEYS; j++) {
3360 			if (j != i && local->crypt_info.crypt[j]) {
3361 				first = 0;
3362 				break;
3363 			}
3364 		}
3365 		if (first)
3366 			local->crypt_info.tx_keyidx = i;
3367 	}
3368 
3369  done:
3370 	if (sta_ptr)
3371 		hostap_handle_sta_release(sta_ptr);
3372 
3373 	local->open_wep = erq->flags & IW_ENCODE_OPEN;
3374 
3375 	/*
3376 	 * Do not reset port0 if card is in Managed mode since resetting will
3377 	 * generate new IEEE 802.11 authentication which may end up in looping
3378 	 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3379 	 * after WEP configuration. However, keys are apparently changed at
3380 	 * least in Managed mode.
3381 	 */
3382 	if (ret == 0 &&
3383 	    (hostap_set_encryption(local) ||
3384 	     (local->iw_mode != IW_MODE_INFRA &&
3385 	      local->func->reset_port(local->dev))))
3386 		ret = -EINVAL;
3387 
3388 	return ret;
3389 }
3390 
3391 
prism2_ioctl_giwencodeext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3392 static int prism2_ioctl_giwencodeext(struct net_device *dev,
3393 				     struct iw_request_info *info,
3394 				     union iwreq_data *wrqu, char *extra)
3395 {
3396 	struct iw_point *erq = &wrqu->encoding;
3397 	struct hostap_interface *iface = netdev_priv(dev);
3398 	local_info_t *local = iface->local;
3399 	struct lib80211_crypt_data **crypt;
3400 	void *sta_ptr;
3401 	int max_key_len, i;
3402 	struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3403 	u8 *addr;
3404 
3405 	max_key_len = erq->length - sizeof(*ext);
3406 	if (max_key_len < 0)
3407 		return -EINVAL;
3408 
3409 	i = erq->flags & IW_ENCODE_INDEX;
3410 	if (i < 1 || i > WEP_KEYS)
3411 		i = local->crypt_info.tx_keyidx;
3412 	else
3413 		i--;
3414 
3415 	addr = ext->addr.sa_data;
3416 	if (is_broadcast_ether_addr(addr)) {
3417 		sta_ptr = NULL;
3418 		crypt = &local->crypt_info.crypt[i];
3419 	} else {
3420 		i = 0;
3421 		sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3422 		if (sta_ptr == NULL)
3423 			return -EINVAL;
3424 	}
3425 	erq->flags = i + 1;
3426 	memset(ext, 0, sizeof(*ext));
3427 
3428 	if (*crypt == NULL || (*crypt)->ops == NULL) {
3429 		ext->alg = IW_ENCODE_ALG_NONE;
3430 		ext->key_len = 0;
3431 		erq->flags |= IW_ENCODE_DISABLED;
3432 	} else {
3433 		if (strcmp((*crypt)->ops->name, "WEP") == 0)
3434 			ext->alg = IW_ENCODE_ALG_WEP;
3435 		else if (strcmp((*crypt)->ops->name, "TKIP") == 0)
3436 			ext->alg = IW_ENCODE_ALG_TKIP;
3437 		else if (strcmp((*crypt)->ops->name, "CCMP") == 0)
3438 			ext->alg = IW_ENCODE_ALG_CCMP;
3439 		else
3440 			return -EINVAL;
3441 
3442 		if ((*crypt)->ops->get_key) {
3443 			ext->key_len =
3444 				(*crypt)->ops->get_key(ext->key,
3445 						       max_key_len,
3446 						       ext->tx_seq,
3447 						       (*crypt)->priv);
3448 			if (ext->key_len &&
3449 			    (ext->alg == IW_ENCODE_ALG_TKIP ||
3450 			     ext->alg == IW_ENCODE_ALG_CCMP))
3451 				ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
3452 		}
3453 	}
3454 
3455 	if (sta_ptr)
3456 		hostap_handle_sta_release(sta_ptr);
3457 
3458 	return 0;
3459 }
3460 
3461 
prism2_ioctl_set_encryption(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3462 static int prism2_ioctl_set_encryption(local_info_t *local,
3463 				       struct prism2_hostapd_param *param,
3464 				       int param_len)
3465 {
3466 	int ret = 0;
3467 	struct lib80211_crypto_ops *ops;
3468 	struct lib80211_crypt_data **crypt;
3469 	void *sta_ptr;
3470 
3471 	param->u.crypt.err = 0;
3472 	param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0';
3473 
3474 	if (param_len !=
3475 	    (int) ((char *) param->u.crypt.key - (char *) param) +
3476 	    param->u.crypt.key_len)
3477 		return -EINVAL;
3478 
3479 	if (is_broadcast_ether_addr(param->sta_addr)) {
3480 		if (param->u.crypt.idx >= WEP_KEYS)
3481 			return -EINVAL;
3482 		sta_ptr = NULL;
3483 		crypt = &local->crypt_info.crypt[param->u.crypt.idx];
3484 	} else {
3485 		if (param->u.crypt.idx)
3486 			return -EINVAL;
3487 		sta_ptr = ap_crypt_get_ptrs(
3488 			local->ap, param->sta_addr,
3489 			(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT),
3490 			&crypt);
3491 
3492 		if (sta_ptr == NULL) {
3493 			param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3494 			return -EINVAL;
3495 		}
3496 	}
3497 
3498 	if (strcmp(param->u.crypt.alg, "none") == 0) {
3499 		if (crypt)
3500 			lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3501 		goto done;
3502 	}
3503 
3504 	ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3505 	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3506 		request_module("lib80211_crypt_wep");
3507 		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3508 	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3509 		request_module("lib80211_crypt_tkip");
3510 		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3511 	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3512 		request_module("lib80211_crypt_ccmp");
3513 		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3514 	}
3515 	if (ops == NULL) {
3516 		printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3517 		       local->dev->name, param->u.crypt.alg);
3518 		param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
3519 		ret = -EINVAL;
3520 		goto done;
3521 	}
3522 
3523 	/* station based encryption and other than WEP algorithms require
3524 	 * host-based encryption, so force them on automatically */
3525 	local->host_decrypt = local->host_encrypt = 1;
3526 
3527 	if (*crypt == NULL || (*crypt)->ops != ops) {
3528 		struct lib80211_crypt_data *new_crypt;
3529 
3530 		lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3531 
3532 		new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
3533 				GFP_KERNEL);
3534 		if (new_crypt == NULL) {
3535 			ret = -ENOMEM;
3536 			goto done;
3537 		}
3538 		new_crypt->ops = ops;
3539 		new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
3540 		if (new_crypt->priv == NULL) {
3541 			kfree(new_crypt);
3542 			param->u.crypt.err =
3543 				HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED;
3544 			ret = -EINVAL;
3545 			goto done;
3546 		}
3547 
3548 		*crypt = new_crypt;
3549 	}
3550 
3551 	if ((!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) ||
3552 	     param->u.crypt.key_len > 0) && (*crypt)->ops->set_key &&
3553 	    (*crypt)->ops->set_key(param->u.crypt.key,
3554 				   param->u.crypt.key_len, param->u.crypt.seq,
3555 				   (*crypt)->priv) < 0) {
3556 		printk(KERN_DEBUG "%s: key setting failed\n",
3557 		       local->dev->name);
3558 		param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
3559 		ret = -EINVAL;
3560 		goto done;
3561 	}
3562 
3563 	if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
3564 		if (!sta_ptr)
3565 			local->crypt_info.tx_keyidx = param->u.crypt.idx;
3566 		else if (param->u.crypt.idx) {
3567 			printk(KERN_DEBUG "%s: TX key idx setting failed\n",
3568 			       local->dev->name);
3569 			param->u.crypt.err =
3570 				HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED;
3571 			ret = -EINVAL;
3572 			goto done;
3573 		}
3574 	}
3575 
3576  done:
3577 	if (sta_ptr)
3578 		hostap_handle_sta_release(sta_ptr);
3579 
3580 	/* Do not reset port0 if card is in Managed mode since resetting will
3581 	 * generate new IEEE 802.11 authentication which may end up in looping
3582 	 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3583 	 * after WEP configuration. However, keys are apparently changed at
3584 	 * least in Managed mode. */
3585 	if (ret == 0 &&
3586 	    (hostap_set_encryption(local) ||
3587 	     (local->iw_mode != IW_MODE_INFRA &&
3588 	      local->func->reset_port(local->dev)))) {
3589 		param->u.crypt.err = HOSTAP_CRYPT_ERR_CARD_CONF_FAILED;
3590 		return -EINVAL;
3591 	}
3592 
3593 	return ret;
3594 }
3595 
3596 
prism2_ioctl_get_encryption(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3597 static int prism2_ioctl_get_encryption(local_info_t *local,
3598 				       struct prism2_hostapd_param *param,
3599 				       int param_len)
3600 {
3601 	struct lib80211_crypt_data **crypt;
3602 	void *sta_ptr;
3603 	int max_key_len;
3604 
3605 	param->u.crypt.err = 0;
3606 
3607 	max_key_len = param_len -
3608 		(int) ((char *) param->u.crypt.key - (char *) param);
3609 	if (max_key_len < 0)
3610 		return -EINVAL;
3611 
3612 	if (is_broadcast_ether_addr(param->sta_addr)) {
3613 		sta_ptr = NULL;
3614 		if (param->u.crypt.idx >= WEP_KEYS)
3615 			param->u.crypt.idx = local->crypt_info.tx_keyidx;
3616 		crypt = &local->crypt_info.crypt[param->u.crypt.idx];
3617 	} else {
3618 		param->u.crypt.idx = 0;
3619 		sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
3620 					    &crypt);
3621 
3622 		if (sta_ptr == NULL) {
3623 			param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3624 			return -EINVAL;
3625 		}
3626 	}
3627 
3628 	if (*crypt == NULL || (*crypt)->ops == NULL) {
3629 		memcpy(param->u.crypt.alg, "none", 5);
3630 		param->u.crypt.key_len = 0;
3631 		param->u.crypt.idx = 0xff;
3632 	} else {
3633 		strscpy(param->u.crypt.alg, (*crypt)->ops->name,
3634 			HOSTAP_CRYPT_ALG_NAME_LEN);
3635 		param->u.crypt.key_len = 0;
3636 
3637 		memset(param->u.crypt.seq, 0, 8);
3638 		if ((*crypt)->ops->get_key) {
3639 			param->u.crypt.key_len =
3640 				(*crypt)->ops->get_key(param->u.crypt.key,
3641 						       max_key_len,
3642 						       param->u.crypt.seq,
3643 						       (*crypt)->priv);
3644 		}
3645 	}
3646 
3647 	if (sta_ptr)
3648 		hostap_handle_sta_release(sta_ptr);
3649 
3650 	return 0;
3651 }
3652 
3653 
prism2_ioctl_get_rid(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3654 static int prism2_ioctl_get_rid(local_info_t *local,
3655 				struct prism2_hostapd_param *param,
3656 				int param_len)
3657 {
3658 	int max_len, res;
3659 
3660 	max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3661 	if (max_len < 0)
3662 		return -EINVAL;
3663 
3664 	res = local->func->get_rid(local->dev, param->u.rid.rid,
3665 				   param->u.rid.data, param->u.rid.len, 0);
3666 	if (res >= 0) {
3667 		param->u.rid.len = res;
3668 		return 0;
3669 	}
3670 
3671 	return res;
3672 }
3673 
3674 
prism2_ioctl_set_rid(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3675 static int prism2_ioctl_set_rid(local_info_t *local,
3676 				struct prism2_hostapd_param *param,
3677 				int param_len)
3678 {
3679 	int max_len;
3680 
3681 	max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3682 	if (max_len < 0 || max_len < param->u.rid.len)
3683 		return -EINVAL;
3684 
3685 	return local->func->set_rid(local->dev, param->u.rid.rid,
3686 				    param->u.rid.data, param->u.rid.len);
3687 }
3688 
3689 
prism2_ioctl_set_assoc_ap_addr(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3690 static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local,
3691 					  struct prism2_hostapd_param *param,
3692 					  int param_len)
3693 {
3694 	printk(KERN_DEBUG "%ssta: associated as client with AP %pM\n",
3695 	       local->dev->name, param->sta_addr);
3696 	memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN);
3697 	return 0;
3698 }
3699 
3700 
prism2_ioctl_siwgenie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3701 static int prism2_ioctl_siwgenie(struct net_device *dev,
3702 				 struct iw_request_info *info,
3703 				 union iwreq_data *wrqu, char *extra)
3704 {
3705 	struct iw_point *data = &wrqu->data;
3706 	return prism2_set_genericelement(dev, extra, data->length);
3707 }
3708 
3709 
prism2_ioctl_giwgenie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3710 static int prism2_ioctl_giwgenie(struct net_device *dev,
3711 				 struct iw_request_info *info,
3712 				 union iwreq_data *wrqu, char *extra)
3713 {
3714 	struct iw_point *data = &wrqu->data;
3715 	struct hostap_interface *iface = netdev_priv(dev);
3716 	local_info_t *local = iface->local;
3717 	int len = local->generic_elem_len - 2;
3718 
3719 	if (len <= 0 || local->generic_elem == NULL) {
3720 		data->length = 0;
3721 		return 0;
3722 	}
3723 
3724 	if (data->length < len)
3725 		return -E2BIG;
3726 
3727 	data->length = len;
3728 	memcpy(extra, local->generic_elem + 2, len);
3729 
3730 	return 0;
3731 }
3732 
3733 
prism2_ioctl_set_generic_element(local_info_t * local,struct prism2_hostapd_param * param,int param_len)3734 static int prism2_ioctl_set_generic_element(local_info_t *local,
3735 					    struct prism2_hostapd_param *param,
3736 					    int param_len)
3737 {
3738 	int max_len, len;
3739 
3740 	len = param->u.generic_elem.len;
3741 	max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
3742 	if (max_len < 0 || max_len < len)
3743 		return -EINVAL;
3744 
3745 	return prism2_set_genericelement(local->dev,
3746 					 param->u.generic_elem.data, len);
3747 }
3748 
3749 
prism2_ioctl_siwmlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3750 static int prism2_ioctl_siwmlme(struct net_device *dev,
3751 				struct iw_request_info *info,
3752 				union iwreq_data *wrqu, char *extra)
3753 {
3754 	struct hostap_interface *iface = netdev_priv(dev);
3755 	local_info_t *local = iface->local;
3756 	struct iw_mlme *mlme = (struct iw_mlme *) extra;
3757 	__le16 reason;
3758 
3759 	reason = cpu_to_le16(mlme->reason_code);
3760 
3761 	switch (mlme->cmd) {
3762 	case IW_MLME_DEAUTH:
3763 		return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3764 					    IEEE80211_STYPE_DEAUTH,
3765 					    (u8 *) &reason, 2);
3766 	case IW_MLME_DISASSOC:
3767 		return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3768 					    IEEE80211_STYPE_DISASSOC,
3769 					    (u8 *) &reason, 2);
3770 	default:
3771 		return -EOPNOTSUPP;
3772 	}
3773 }
3774 
3775 
prism2_ioctl_mlme(local_info_t * local,struct prism2_hostapd_param * param)3776 static int prism2_ioctl_mlme(local_info_t *local,
3777 			     struct prism2_hostapd_param *param)
3778 {
3779 	__le16 reason;
3780 
3781 	reason = cpu_to_le16(param->u.mlme.reason_code);
3782 	switch (param->u.mlme.cmd) {
3783 	case MLME_STA_DEAUTH:
3784 		return prism2_sta_send_mgmt(local, param->sta_addr,
3785 					    IEEE80211_STYPE_DEAUTH,
3786 					    (u8 *) &reason, 2);
3787 	case MLME_STA_DISASSOC:
3788 		return prism2_sta_send_mgmt(local, param->sta_addr,
3789 					    IEEE80211_STYPE_DISASSOC,
3790 					    (u8 *) &reason, 2);
3791 	default:
3792 		return -EOPNOTSUPP;
3793 	}
3794 }
3795 
3796 
prism2_ioctl_scan_req(local_info_t * local,struct prism2_hostapd_param * param)3797 static int prism2_ioctl_scan_req(local_info_t *local,
3798 				 struct prism2_hostapd_param *param)
3799 {
3800 #ifndef PRISM2_NO_STATION_MODES
3801 	if ((local->iw_mode != IW_MODE_INFRA &&
3802 	     local->iw_mode != IW_MODE_ADHOC) ||
3803 	    (local->sta_fw_ver < PRISM2_FW_VER(1,3,1)))
3804 		return -EOPNOTSUPP;
3805 
3806 	if (!local->dev_enabled)
3807 		return -ENETDOWN;
3808 
3809 	return prism2_request_hostscan(local->dev, param->u.scan_req.ssid,
3810 				       param->u.scan_req.ssid_len);
3811 #else /* PRISM2_NO_STATION_MODES */
3812 	return -EOPNOTSUPP;
3813 #endif /* PRISM2_NO_STATION_MODES */
3814 }
3815 
3816 
prism2_ioctl_priv_hostapd(local_info_t * local,struct iw_point * p)3817 static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
3818 {
3819 	struct prism2_hostapd_param *param;
3820 	int ret = 0;
3821 	int ap_ioctl = 0;
3822 
3823 	if (p->length < sizeof(struct prism2_hostapd_param) ||
3824 	    p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
3825 		return -EINVAL;
3826 
3827 	param = memdup_user(p->pointer, p->length);
3828 	if (IS_ERR(param)) {
3829 		return PTR_ERR(param);
3830 	}
3831 
3832 	switch (param->cmd) {
3833 	case PRISM2_SET_ENCRYPTION:
3834 		ret = prism2_ioctl_set_encryption(local, param, p->length);
3835 		break;
3836 	case PRISM2_GET_ENCRYPTION:
3837 		ret = prism2_ioctl_get_encryption(local, param, p->length);
3838 		break;
3839 	case PRISM2_HOSTAPD_GET_RID:
3840 		ret = prism2_ioctl_get_rid(local, param, p->length);
3841 		break;
3842 	case PRISM2_HOSTAPD_SET_RID:
3843 		ret = prism2_ioctl_set_rid(local, param, p->length);
3844 		break;
3845 	case PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR:
3846 		ret = prism2_ioctl_set_assoc_ap_addr(local, param, p->length);
3847 		break;
3848 	case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
3849 		ret = prism2_ioctl_set_generic_element(local, param,
3850 						       p->length);
3851 		break;
3852 	case PRISM2_HOSTAPD_MLME:
3853 		ret = prism2_ioctl_mlme(local, param);
3854 		break;
3855 	case PRISM2_HOSTAPD_SCAN_REQ:
3856 		ret = prism2_ioctl_scan_req(local, param);
3857 		break;
3858 	default:
3859 		ret = prism2_hostapd(local->ap, param);
3860 		ap_ioctl = 1;
3861 		break;
3862 	}
3863 
3864 	if (ret == 1 || !ap_ioctl) {
3865 		if (copy_to_user(p->pointer, param, p->length)) {
3866 			ret = -EFAULT;
3867 			goto out;
3868 		} else if (ap_ioctl)
3869 			ret = 0;
3870 	}
3871 
3872  out:
3873 	kfree(param);
3874 	return ret;
3875 }
3876 
3877 
prism2_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)3878 static void prism2_get_drvinfo(struct net_device *dev,
3879 			       struct ethtool_drvinfo *info)
3880 {
3881 	struct hostap_interface *iface;
3882 	local_info_t *local;
3883 
3884 	iface = netdev_priv(dev);
3885 	local = iface->local;
3886 
3887 	strscpy(info->driver, "hostap", sizeof(info->driver));
3888 	snprintf(info->fw_version, sizeof(info->fw_version),
3889 		 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
3890 		 (local->sta_fw_ver >> 8) & 0xff,
3891 		 local->sta_fw_ver & 0xff);
3892 }
3893 
3894 const struct ethtool_ops prism2_ethtool_ops = {
3895 	.get_drvinfo = prism2_get_drvinfo
3896 };
3897 
3898 
3899 /* Structures to export the Wireless Handlers */
3900 
3901 static const iw_handler prism2_handler[] =
3902 {
3903 	IW_HANDLER(SIOCGIWNAME,		prism2_get_name),
3904 	IW_HANDLER(SIOCSIWFREQ,		prism2_ioctl_siwfreq),
3905 	IW_HANDLER(SIOCGIWFREQ,		prism2_ioctl_giwfreq),
3906 	IW_HANDLER(SIOCSIWMODE,		prism2_ioctl_siwmode),
3907 	IW_HANDLER(SIOCGIWMODE,		prism2_ioctl_giwmode),
3908 	IW_HANDLER(SIOCSIWSENS,		prism2_ioctl_siwsens),
3909 	IW_HANDLER(SIOCGIWSENS,		prism2_ioctl_giwsens),
3910 	IW_HANDLER(SIOCGIWRANGE,	prism2_ioctl_giwrange),
3911 	IW_HANDLER(SIOCSIWSPY,		iw_handler_set_spy),
3912 	IW_HANDLER(SIOCGIWSPY,		iw_handler_get_spy),
3913 	IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
3914 	IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
3915 	IW_HANDLER(SIOCSIWAP,		prism2_ioctl_siwap),
3916 	IW_HANDLER(SIOCGIWAP,		prism2_ioctl_giwap),
3917 	IW_HANDLER(SIOCSIWMLME,		prism2_ioctl_siwmlme),
3918 	IW_HANDLER(SIOCGIWAPLIST,       prism2_ioctl_giwaplist),
3919 	IW_HANDLER(SIOCSIWSCAN,		prism2_ioctl_siwscan),
3920 	IW_HANDLER(SIOCGIWSCAN,		prism2_ioctl_giwscan),
3921 	IW_HANDLER(SIOCSIWESSID,        prism2_ioctl_siwessid),
3922 	IW_HANDLER(SIOCGIWESSID,        prism2_ioctl_giwessid),
3923 	IW_HANDLER(SIOCSIWNICKN,        prism2_ioctl_siwnickn),
3924 	IW_HANDLER(SIOCGIWNICKN,        prism2_ioctl_giwnickn),
3925 	IW_HANDLER(SIOCSIWRATE,		prism2_ioctl_siwrate),
3926 	IW_HANDLER(SIOCGIWRATE,		prism2_ioctl_giwrate),
3927 	IW_HANDLER(SIOCSIWRTS,		prism2_ioctl_siwrts),
3928 	IW_HANDLER(SIOCGIWRTS,		prism2_ioctl_giwrts),
3929 	IW_HANDLER(SIOCSIWFRAG,		prism2_ioctl_siwfrag),
3930 	IW_HANDLER(SIOCGIWFRAG,		prism2_ioctl_giwfrag),
3931 	IW_HANDLER(SIOCSIWTXPOW,        prism2_ioctl_siwtxpow),
3932 	IW_HANDLER(SIOCGIWTXPOW,        prism2_ioctl_giwtxpow),
3933 	IW_HANDLER(SIOCSIWRETRY,        prism2_ioctl_siwretry),
3934 	IW_HANDLER(SIOCGIWRETRY,        prism2_ioctl_giwretry),
3935 	IW_HANDLER(SIOCSIWENCODE,       prism2_ioctl_siwencode),
3936 	IW_HANDLER(SIOCGIWENCODE,       prism2_ioctl_giwencode),
3937 	IW_HANDLER(SIOCSIWPOWER,        prism2_ioctl_siwpower),
3938 	IW_HANDLER(SIOCGIWPOWER,        prism2_ioctl_giwpower),
3939 	IW_HANDLER(SIOCSIWGENIE,        prism2_ioctl_siwgenie),
3940 	IW_HANDLER(SIOCGIWGENIE,        prism2_ioctl_giwgenie),
3941 	IW_HANDLER(SIOCSIWAUTH,		prism2_ioctl_siwauth),
3942 	IW_HANDLER(SIOCGIWAUTH,		prism2_ioctl_giwauth),
3943 	IW_HANDLER(SIOCSIWENCODEEXT,    prism2_ioctl_siwencodeext),
3944 	IW_HANDLER(SIOCGIWENCODEEXT,    prism2_ioctl_giwencodeext),
3945 };
3946 
3947 static const iw_handler prism2_private_handler[] =
3948 {						/* SIOCIWFIRSTPRIV + */
3949 	prism2_ioctl_priv_prism2_param,		/* 0 */
3950 	prism2_ioctl_priv_get_prism2_param,	/* 1 */
3951 	prism2_ioctl_priv_writemif,		/* 2 */
3952 	prism2_ioctl_priv_readmif,		/* 3 */
3953 };
3954 
3955 const struct iw_handler_def hostap_iw_handler_def =
3956 {
3957 	.num_standard	= ARRAY_SIZE(prism2_handler),
3958 	.num_private	= ARRAY_SIZE(prism2_private_handler),
3959 	.num_private_args = ARRAY_SIZE(prism2_priv),
3960 	.standard	= prism2_handler,
3961 	.private	= prism2_private_handler,
3962 	.private_args	= (struct iw_priv_args *) prism2_priv,
3963 	.get_wireless_stats = hostap_get_wireless_stats,
3964 };
3965 
3966 /* Private ioctls (iwpriv) that have not yet been converted
3967  * into new wireless extensions API */
hostap_ioctl(struct net_device * dev,struct ifreq * ifr,int cmd)3968 int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3969 {
3970 	struct iwreq *wrq = (struct iwreq *) ifr;
3971 	struct hostap_interface *iface;
3972 	local_info_t *local;
3973 	int ret = 0;
3974 
3975 	iface = netdev_priv(dev);
3976 	local = iface->local;
3977 
3978 	switch (cmd) {
3979 	case PRISM2_IOCTL_INQUIRE:
3980 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
3981 		else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name);
3982 		break;
3983 
3984 	case PRISM2_IOCTL_MONITOR:
3985 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
3986 		else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
3987 		break;
3988 
3989 	case PRISM2_IOCTL_RESET:
3990 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
3991 		else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
3992 		break;
3993 
3994 	case PRISM2_IOCTL_WDS_ADD:
3995 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
3996 		else ret = prism2_wds_add(local, wrq->u.ap_addr.sa_data, 1);
3997 		break;
3998 
3999 	case PRISM2_IOCTL_WDS_DEL:
4000 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4001 		else ret = prism2_wds_del(local, wrq->u.ap_addr.sa_data, 1, 0);
4002 		break;
4003 
4004 	case PRISM2_IOCTL_SET_RID_WORD:
4005 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4006 		else ret = prism2_ioctl_priv_set_rid_word(dev,
4007 							  (int *) wrq->u.name);
4008 		break;
4009 
4010 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
4011 	case PRISM2_IOCTL_MACCMD:
4012 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4013 		else ret = ap_mac_cmd_ioctl(local, (int *) wrq->u.name);
4014 		break;
4015 
4016 	case PRISM2_IOCTL_ADDMAC:
4017 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4018 		else ret = ap_control_add_mac(&local->ap->mac_restrictions,
4019 					      wrq->u.ap_addr.sa_data);
4020 		break;
4021 	case PRISM2_IOCTL_DELMAC:
4022 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4023 		else ret = ap_control_del_mac(&local->ap->mac_restrictions,
4024 					      wrq->u.ap_addr.sa_data);
4025 		break;
4026 	case PRISM2_IOCTL_KICKMAC:
4027 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4028 		else ret = ap_control_kick_mac(local->ap, local->dev,
4029 					       wrq->u.ap_addr.sa_data);
4030 		break;
4031 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
4032 	default:
4033 		ret = -EOPNOTSUPP;
4034 		break;
4035 	}
4036 
4037 	return ret;
4038 }
4039 
4040 /* Private ioctls that are not used with iwpriv;
4041  * in SIOCDEVPRIVATE range */
hostap_siocdevprivate(struct net_device * dev,struct ifreq * ifr,void __user * data,int cmd)4042 int hostap_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
4043 			  void __user *data, int cmd)
4044 {
4045 	struct iwreq *wrq = (struct iwreq *)ifr;
4046 	struct hostap_interface *iface;
4047 	local_info_t *local;
4048 	int ret = 0;
4049 
4050 	iface = netdev_priv(dev);
4051 	local = iface->local;
4052 
4053 	if (in_compat_syscall()) /* not implemented yet */
4054 		return -EOPNOTSUPP;
4055 
4056 	switch (cmd) {
4057 #ifdef PRISM2_DOWNLOAD_SUPPORT
4058 	case PRISM2_IOCTL_DOWNLOAD:
4059 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4060 		else ret = prism2_ioctl_priv_download(local, &wrq->u.data);
4061 		break;
4062 #endif /* PRISM2_DOWNLOAD_SUPPORT */
4063 
4064 	case PRISM2_IOCTL_HOSTAPD:
4065 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4066 		else ret = prism2_ioctl_priv_hostapd(local, &wrq->u.data);
4067 		break;
4068 
4069 	default:
4070 		ret = -EOPNOTSUPP;
4071 		break;
4072 	}
4073 
4074 	return ret;
4075 }
4076