cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hostap_ioctl.c (106082B)


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