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