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

wext-compat.c (42243B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * cfg80211 - wext compat code
      4 *
      5 * This is temporary code until all wireless functionality is migrated
      6 * into cfg80211, when that happens all the exports here go away and
      7 * we directly assign the wireless handlers of wireless interfaces.
      8 *
      9 * Copyright 2008-2009	Johannes Berg <johannes@sipsolutions.net>
     10 * Copyright (C) 2019-2021 Intel Corporation
     11 */
     12
     13#include <linux/export.h>
     14#include <linux/wireless.h>
     15#include <linux/nl80211.h>
     16#include <linux/if_arp.h>
     17#include <linux/etherdevice.h>
     18#include <linux/slab.h>
     19#include <net/iw_handler.h>
     20#include <net/cfg80211.h>
     21#include <net/cfg80211-wext.h>
     22#include "wext-compat.h"
     23#include "core.h"
     24#include "rdev-ops.h"
     25
     26int cfg80211_wext_giwname(struct net_device *dev,
     27			  struct iw_request_info *info,
     28			  char *name, char *extra)
     29{
     30	strcpy(name, "IEEE 802.11");
     31	return 0;
     32}
     33EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
     34
     35int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
     36			  u32 *mode, char *extra)
     37{
     38	struct wireless_dev *wdev = dev->ieee80211_ptr;
     39	struct cfg80211_registered_device *rdev;
     40	struct vif_params vifparams;
     41	enum nl80211_iftype type;
     42	int ret;
     43
     44	rdev = wiphy_to_rdev(wdev->wiphy);
     45
     46	switch (*mode) {
     47	case IW_MODE_INFRA:
     48		type = NL80211_IFTYPE_STATION;
     49		break;
     50	case IW_MODE_ADHOC:
     51		type = NL80211_IFTYPE_ADHOC;
     52		break;
     53	case IW_MODE_MONITOR:
     54		type = NL80211_IFTYPE_MONITOR;
     55		break;
     56	default:
     57		return -EINVAL;
     58	}
     59
     60	if (type == wdev->iftype)
     61		return 0;
     62
     63	memset(&vifparams, 0, sizeof(vifparams));
     64
     65	wiphy_lock(wdev->wiphy);
     66	ret = cfg80211_change_iface(rdev, dev, type, &vifparams);
     67	wiphy_unlock(wdev->wiphy);
     68
     69	return ret;
     70}
     71EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
     72
     73int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
     74			  u32 *mode, char *extra)
     75{
     76	struct wireless_dev *wdev = dev->ieee80211_ptr;
     77
     78	if (!wdev)
     79		return -EOPNOTSUPP;
     80
     81	switch (wdev->iftype) {
     82	case NL80211_IFTYPE_AP:
     83		*mode = IW_MODE_MASTER;
     84		break;
     85	case NL80211_IFTYPE_STATION:
     86		*mode = IW_MODE_INFRA;
     87		break;
     88	case NL80211_IFTYPE_ADHOC:
     89		*mode = IW_MODE_ADHOC;
     90		break;
     91	case NL80211_IFTYPE_MONITOR:
     92		*mode = IW_MODE_MONITOR;
     93		break;
     94	case NL80211_IFTYPE_WDS:
     95		*mode = IW_MODE_REPEAT;
     96		break;
     97	case NL80211_IFTYPE_AP_VLAN:
     98		*mode = IW_MODE_SECOND;		/* FIXME */
     99		break;
    100	default:
    101		*mode = IW_MODE_AUTO;
    102		break;
    103	}
    104	return 0;
    105}
    106EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode);
    107
    108
    109int cfg80211_wext_giwrange(struct net_device *dev,
    110			   struct iw_request_info *info,
    111			   struct iw_point *data, char *extra)
    112{
    113	struct wireless_dev *wdev = dev->ieee80211_ptr;
    114	struct iw_range *range = (struct iw_range *) extra;
    115	enum nl80211_band band;
    116	int i, c = 0;
    117
    118	if (!wdev)
    119		return -EOPNOTSUPP;
    120
    121	data->length = sizeof(struct iw_range);
    122	memset(range, 0, sizeof(struct iw_range));
    123
    124	range->we_version_compiled = WIRELESS_EXT;
    125	range->we_version_source = 21;
    126	range->retry_capa = IW_RETRY_LIMIT;
    127	range->retry_flags = IW_RETRY_LIMIT;
    128	range->min_retry = 0;
    129	range->max_retry = 255;
    130	range->min_rts = 0;
    131	range->max_rts = 2347;
    132	range->min_frag = 256;
    133	range->max_frag = 2346;
    134
    135	range->max_encoding_tokens = 4;
    136
    137	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
    138
    139	switch (wdev->wiphy->signal_type) {
    140	case CFG80211_SIGNAL_TYPE_NONE:
    141		break;
    142	case CFG80211_SIGNAL_TYPE_MBM:
    143		range->max_qual.level = (u8)-110;
    144		range->max_qual.qual = 70;
    145		range->avg_qual.qual = 35;
    146		range->max_qual.updated |= IW_QUAL_DBM;
    147		range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
    148		range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
    149		break;
    150	case CFG80211_SIGNAL_TYPE_UNSPEC:
    151		range->max_qual.level = 100;
    152		range->max_qual.qual = 100;
    153		range->avg_qual.qual = 50;
    154		range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
    155		range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
    156		break;
    157	}
    158
    159	range->avg_qual.level = range->max_qual.level / 2;
    160	range->avg_qual.noise = range->max_qual.noise / 2;
    161	range->avg_qual.updated = range->max_qual.updated;
    162
    163	for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) {
    164		switch (wdev->wiphy->cipher_suites[i]) {
    165		case WLAN_CIPHER_SUITE_TKIP:
    166			range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
    167					    IW_ENC_CAPA_WPA);
    168			break;
    169
    170		case WLAN_CIPHER_SUITE_CCMP:
    171			range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
    172					    IW_ENC_CAPA_WPA2);
    173			break;
    174
    175		case WLAN_CIPHER_SUITE_WEP40:
    176			range->encoding_size[range->num_encoding_sizes++] =
    177				WLAN_KEY_LEN_WEP40;
    178			break;
    179
    180		case WLAN_CIPHER_SUITE_WEP104:
    181			range->encoding_size[range->num_encoding_sizes++] =
    182				WLAN_KEY_LEN_WEP104;
    183			break;
    184		}
    185	}
    186
    187	for (band = 0; band < NUM_NL80211_BANDS; band ++) {
    188		struct ieee80211_supported_band *sband;
    189
    190		sband = wdev->wiphy->bands[band];
    191
    192		if (!sband)
    193			continue;
    194
    195		for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
    196			struct ieee80211_channel *chan = &sband->channels[i];
    197
    198			if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
    199				range->freq[c].i =
    200					ieee80211_frequency_to_channel(
    201						chan->center_freq);
    202				range->freq[c].m = chan->center_freq;
    203				range->freq[c].e = 6;
    204				c++;
    205			}
    206		}
    207	}
    208	range->num_channels = c;
    209	range->num_frequency = c;
    210
    211	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
    212	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
    213	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
    214
    215	if (wdev->wiphy->max_scan_ssids > 0)
    216		range->scan_capa |= IW_SCAN_CAPA_ESSID;
    217
    218	return 0;
    219}
    220EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange);
    221
    222
    223/**
    224 * cfg80211_wext_freq - get wext frequency for non-"auto"
    225 * @freq: the wext freq encoding
    226 *
    227 * Returns a frequency, or a negative error code, or 0 for auto.
    228 */
    229int cfg80211_wext_freq(struct iw_freq *freq)
    230{
    231	/*
    232	 * Parse frequency - return 0 for auto and
    233	 * -EINVAL for impossible things.
    234	 */
    235	if (freq->e == 0) {
    236		enum nl80211_band band = NL80211_BAND_2GHZ;
    237		if (freq->m < 0)
    238			return 0;
    239		if (freq->m > 14)
    240			band = NL80211_BAND_5GHZ;
    241		return ieee80211_channel_to_frequency(freq->m, band);
    242	} else {
    243		int i, div = 1000000;
    244		for (i = 0; i < freq->e; i++)
    245			div /= 10;
    246		if (div <= 0)
    247			return -EINVAL;
    248		return freq->m / div;
    249	}
    250}
    251
    252int cfg80211_wext_siwrts(struct net_device *dev,
    253			 struct iw_request_info *info,
    254			 struct iw_param *rts, char *extra)
    255{
    256	struct wireless_dev *wdev = dev->ieee80211_ptr;
    257	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    258	u32 orts = wdev->wiphy->rts_threshold;
    259	int err;
    260
    261	wiphy_lock(&rdev->wiphy);
    262	if (rts->disabled || !rts->fixed) {
    263		wdev->wiphy->rts_threshold = (u32) -1;
    264	} else if (rts->value < 0) {
    265		err = -EINVAL;
    266		goto out;
    267	} else {
    268		wdev->wiphy->rts_threshold = rts->value;
    269	}
    270
    271	err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD);
    272
    273	if (err)
    274		wdev->wiphy->rts_threshold = orts;
    275
    276out:
    277	wiphy_unlock(&rdev->wiphy);
    278	return err;
    279}
    280EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
    281
    282int cfg80211_wext_giwrts(struct net_device *dev,
    283			 struct iw_request_info *info,
    284			 struct iw_param *rts, char *extra)
    285{
    286	struct wireless_dev *wdev = dev->ieee80211_ptr;
    287
    288	rts->value = wdev->wiphy->rts_threshold;
    289	rts->disabled = rts->value == (u32) -1;
    290	rts->fixed = 1;
    291
    292	return 0;
    293}
    294EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts);
    295
    296int cfg80211_wext_siwfrag(struct net_device *dev,
    297			  struct iw_request_info *info,
    298			  struct iw_param *frag, char *extra)
    299{
    300	struct wireless_dev *wdev = dev->ieee80211_ptr;
    301	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    302	u32 ofrag = wdev->wiphy->frag_threshold;
    303	int err;
    304
    305	wiphy_lock(&rdev->wiphy);
    306	if (frag->disabled || !frag->fixed) {
    307		wdev->wiphy->frag_threshold = (u32) -1;
    308	} else if (frag->value < 256) {
    309		err = -EINVAL;
    310		goto out;
    311	} else {
    312		/* Fragment length must be even, so strip LSB. */
    313		wdev->wiphy->frag_threshold = frag->value & ~0x1;
    314	}
    315
    316	err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD);
    317	if (err)
    318		wdev->wiphy->frag_threshold = ofrag;
    319out:
    320	wiphy_unlock(&rdev->wiphy);
    321
    322	return err;
    323}
    324EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
    325
    326int cfg80211_wext_giwfrag(struct net_device *dev,
    327			  struct iw_request_info *info,
    328			  struct iw_param *frag, char *extra)
    329{
    330	struct wireless_dev *wdev = dev->ieee80211_ptr;
    331
    332	frag->value = wdev->wiphy->frag_threshold;
    333	frag->disabled = frag->value == (u32) -1;
    334	frag->fixed = 1;
    335
    336	return 0;
    337}
    338EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag);
    339
    340static int cfg80211_wext_siwretry(struct net_device *dev,
    341				  struct iw_request_info *info,
    342				  struct iw_param *retry, char *extra)
    343{
    344	struct wireless_dev *wdev = dev->ieee80211_ptr;
    345	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    346	u32 changed = 0;
    347	u8 olong = wdev->wiphy->retry_long;
    348	u8 oshort = wdev->wiphy->retry_short;
    349	int err;
    350
    351	if (retry->disabled || retry->value < 1 || retry->value > 255 ||
    352	    (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
    353		return -EINVAL;
    354
    355	wiphy_lock(&rdev->wiphy);
    356	if (retry->flags & IW_RETRY_LONG) {
    357		wdev->wiphy->retry_long = retry->value;
    358		changed |= WIPHY_PARAM_RETRY_LONG;
    359	} else if (retry->flags & IW_RETRY_SHORT) {
    360		wdev->wiphy->retry_short = retry->value;
    361		changed |= WIPHY_PARAM_RETRY_SHORT;
    362	} else {
    363		wdev->wiphy->retry_short = retry->value;
    364		wdev->wiphy->retry_long = retry->value;
    365		changed |= WIPHY_PARAM_RETRY_LONG;
    366		changed |= WIPHY_PARAM_RETRY_SHORT;
    367	}
    368
    369	err = rdev_set_wiphy_params(rdev, changed);
    370	if (err) {
    371		wdev->wiphy->retry_short = oshort;
    372		wdev->wiphy->retry_long = olong;
    373	}
    374	wiphy_unlock(&rdev->wiphy);
    375
    376	return err;
    377}
    378
    379int cfg80211_wext_giwretry(struct net_device *dev,
    380			   struct iw_request_info *info,
    381			   struct iw_param *retry, char *extra)
    382{
    383	struct wireless_dev *wdev = dev->ieee80211_ptr;
    384
    385	retry->disabled = 0;
    386
    387	if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
    388		/*
    389		 * First return short value, iwconfig will ask long value
    390		 * later if needed
    391		 */
    392		retry->flags |= IW_RETRY_LIMIT | IW_RETRY_SHORT;
    393		retry->value = wdev->wiphy->retry_short;
    394		if (wdev->wiphy->retry_long == wdev->wiphy->retry_short)
    395			retry->flags |= IW_RETRY_LONG;
    396
    397		return 0;
    398	}
    399
    400	if (retry->flags & IW_RETRY_LONG) {
    401		retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
    402		retry->value = wdev->wiphy->retry_long;
    403	}
    404
    405	return 0;
    406}
    407EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry);
    408
    409static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
    410				     struct net_device *dev, bool pairwise,
    411				     const u8 *addr, bool remove, bool tx_key,
    412				     int idx, struct key_params *params)
    413{
    414	struct wireless_dev *wdev = dev->ieee80211_ptr;
    415	int err, i;
    416	bool rejoin = false;
    417
    418	if (pairwise && !addr)
    419		return -EINVAL;
    420
    421	/*
    422	 * In many cases we won't actually need this, but it's better
    423	 * to do it first in case the allocation fails. Don't use wext.
    424	 */
    425	if (!wdev->wext.keys) {
    426		wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
    427					  GFP_KERNEL);
    428		if (!wdev->wext.keys)
    429			return -ENOMEM;
    430		for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
    431			wdev->wext.keys->params[i].key =
    432				wdev->wext.keys->data[i];
    433	}
    434
    435	if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
    436	    wdev->iftype != NL80211_IFTYPE_STATION)
    437		return -EOPNOTSUPP;
    438
    439	if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
    440		if (!wdev->current_bss)
    441			return -ENOLINK;
    442
    443		if (!rdev->ops->set_default_mgmt_key)
    444			return -EOPNOTSUPP;
    445
    446		if (idx < 4 || idx > 5)
    447			return -EINVAL;
    448	} else if (idx < 0 || idx > 3)
    449		return -EINVAL;
    450
    451	if (remove) {
    452		err = 0;
    453		if (wdev->current_bss) {
    454			/*
    455			 * If removing the current TX key, we will need to
    456			 * join a new IBSS without the privacy bit clear.
    457			 */
    458			if (idx == wdev->wext.default_key &&
    459			    wdev->iftype == NL80211_IFTYPE_ADHOC) {
    460				__cfg80211_leave_ibss(rdev, wdev->netdev, true);
    461				rejoin = true;
    462			}
    463
    464			if (!pairwise && addr &&
    465			    !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
    466				err = -ENOENT;
    467			else
    468				err = rdev_del_key(rdev, dev, idx, pairwise,
    469						   addr);
    470		}
    471		wdev->wext.connect.privacy = false;
    472		/*
    473		 * Applications using wireless extensions expect to be
    474		 * able to delete keys that don't exist, so allow that.
    475		 */
    476		if (err == -ENOENT)
    477			err = 0;
    478		if (!err) {
    479			if (!addr && idx < 4) {
    480				memset(wdev->wext.keys->data[idx], 0,
    481				       sizeof(wdev->wext.keys->data[idx]));
    482				wdev->wext.keys->params[idx].key_len = 0;
    483				wdev->wext.keys->params[idx].cipher = 0;
    484			}
    485			if (idx == wdev->wext.default_key)
    486				wdev->wext.default_key = -1;
    487			else if (idx == wdev->wext.default_mgmt_key)
    488				wdev->wext.default_mgmt_key = -1;
    489		}
    490
    491		if (!err && rejoin)
    492			err = cfg80211_ibss_wext_join(rdev, wdev);
    493
    494		return err;
    495	}
    496
    497	if (addr)
    498		tx_key = false;
    499
    500	if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
    501		return -EINVAL;
    502
    503	err = 0;
    504	if (wdev->current_bss)
    505		err = rdev_add_key(rdev, dev, idx, pairwise, addr, params);
    506	else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
    507		 params->cipher != WLAN_CIPHER_SUITE_WEP104)
    508		return -EINVAL;
    509	if (err)
    510		return err;
    511
    512	/*
    513	 * We only need to store WEP keys, since they're the only keys that
    514	 * can be set before a connection is established and persist after
    515	 * disconnecting.
    516	 */
    517	if (!addr && (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
    518		      params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
    519		wdev->wext.keys->params[idx] = *params;
    520		memcpy(wdev->wext.keys->data[idx],
    521			params->key, params->key_len);
    522		wdev->wext.keys->params[idx].key =
    523			wdev->wext.keys->data[idx];
    524	}
    525
    526	if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
    527	     params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
    528	    (tx_key || (!addr && wdev->wext.default_key == -1))) {
    529		if (wdev->current_bss) {
    530			/*
    531			 * If we are getting a new TX key from not having
    532			 * had one before we need to join a new IBSS with
    533			 * the privacy bit set.
    534			 */
    535			if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
    536			    wdev->wext.default_key == -1) {
    537				__cfg80211_leave_ibss(rdev, wdev->netdev, true);
    538				rejoin = true;
    539			}
    540			err = rdev_set_default_key(rdev, dev, idx, true, true);
    541		}
    542		if (!err) {
    543			wdev->wext.default_key = idx;
    544			if (rejoin)
    545				err = cfg80211_ibss_wext_join(rdev, wdev);
    546		}
    547		return err;
    548	}
    549
    550	if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
    551	    (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
    552		if (wdev->current_bss)
    553			err = rdev_set_default_mgmt_key(rdev, dev, idx);
    554		if (!err)
    555			wdev->wext.default_mgmt_key = idx;
    556		return err;
    557	}
    558
    559	return 0;
    560}
    561
    562static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
    563				   struct net_device *dev, bool pairwise,
    564				   const u8 *addr, bool remove, bool tx_key,
    565				   int idx, struct key_params *params)
    566{
    567	int err;
    568
    569	wdev_lock(dev->ieee80211_ptr);
    570	err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
    571					remove, tx_key, idx, params);
    572	wdev_unlock(dev->ieee80211_ptr);
    573
    574	return err;
    575}
    576
    577static int cfg80211_wext_siwencode(struct net_device *dev,
    578				   struct iw_request_info *info,
    579				   struct iw_point *erq, char *keybuf)
    580{
    581	struct wireless_dev *wdev = dev->ieee80211_ptr;
    582	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    583	int idx, err;
    584	bool remove = false;
    585	struct key_params params;
    586
    587	if (wdev->iftype != NL80211_IFTYPE_STATION &&
    588	    wdev->iftype != NL80211_IFTYPE_ADHOC)
    589		return -EOPNOTSUPP;
    590
    591	/* no use -- only MFP (set_default_mgmt_key) is optional */
    592	if (!rdev->ops->del_key ||
    593	    !rdev->ops->add_key ||
    594	    !rdev->ops->set_default_key)
    595		return -EOPNOTSUPP;
    596
    597	wiphy_lock(&rdev->wiphy);
    598	idx = erq->flags & IW_ENCODE_INDEX;
    599	if (idx == 0) {
    600		idx = wdev->wext.default_key;
    601		if (idx < 0)
    602			idx = 0;
    603	} else if (idx < 1 || idx > 4) {
    604		err = -EINVAL;
    605		goto out;
    606	} else {
    607		idx--;
    608	}
    609
    610	if (erq->flags & IW_ENCODE_DISABLED)
    611		remove = true;
    612	else if (erq->length == 0) {
    613		/* No key data - just set the default TX key index */
    614		err = 0;
    615		wdev_lock(wdev);
    616		if (wdev->current_bss)
    617			err = rdev_set_default_key(rdev, dev, idx, true,
    618						   true);
    619		if (!err)
    620			wdev->wext.default_key = idx;
    621		wdev_unlock(wdev);
    622		goto out;
    623	}
    624
    625	memset(&params, 0, sizeof(params));
    626	params.key = keybuf;
    627	params.key_len = erq->length;
    628	if (erq->length == 5) {
    629		params.cipher = WLAN_CIPHER_SUITE_WEP40;
    630	} else if (erq->length == 13) {
    631		params.cipher = WLAN_CIPHER_SUITE_WEP104;
    632	} else if (!remove) {
    633		err = -EINVAL;
    634		goto out;
    635	}
    636
    637	err = cfg80211_set_encryption(rdev, dev, false, NULL, remove,
    638				      wdev->wext.default_key == -1,
    639				      idx, &params);
    640out:
    641	wiphy_unlock(&rdev->wiphy);
    642
    643	return err;
    644}
    645
    646static int cfg80211_wext_siwencodeext(struct net_device *dev,
    647				      struct iw_request_info *info,
    648				      struct iw_point *erq, char *extra)
    649{
    650	struct wireless_dev *wdev = dev->ieee80211_ptr;
    651	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    652	struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
    653	const u8 *addr;
    654	int idx;
    655	bool remove = false;
    656	struct key_params params;
    657	u32 cipher;
    658	int ret;
    659
    660	if (wdev->iftype != NL80211_IFTYPE_STATION &&
    661	    wdev->iftype != NL80211_IFTYPE_ADHOC)
    662		return -EOPNOTSUPP;
    663
    664	/* no use -- only MFP (set_default_mgmt_key) is optional */
    665	if (!rdev->ops->del_key ||
    666	    !rdev->ops->add_key ||
    667	    !rdev->ops->set_default_key)
    668		return -EOPNOTSUPP;
    669
    670	switch (ext->alg) {
    671	case IW_ENCODE_ALG_NONE:
    672		remove = true;
    673		cipher = 0;
    674		break;
    675	case IW_ENCODE_ALG_WEP:
    676		if (ext->key_len == 5)
    677			cipher = WLAN_CIPHER_SUITE_WEP40;
    678		else if (ext->key_len == 13)
    679			cipher = WLAN_CIPHER_SUITE_WEP104;
    680		else
    681			return -EINVAL;
    682		break;
    683	case IW_ENCODE_ALG_TKIP:
    684		cipher = WLAN_CIPHER_SUITE_TKIP;
    685		break;
    686	case IW_ENCODE_ALG_CCMP:
    687		cipher = WLAN_CIPHER_SUITE_CCMP;
    688		break;
    689	case IW_ENCODE_ALG_AES_CMAC:
    690		cipher = WLAN_CIPHER_SUITE_AES_CMAC;
    691		break;
    692	default:
    693		return -EOPNOTSUPP;
    694	}
    695
    696	if (erq->flags & IW_ENCODE_DISABLED)
    697		remove = true;
    698
    699	idx = erq->flags & IW_ENCODE_INDEX;
    700	if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
    701		if (idx < 4 || idx > 5) {
    702			idx = wdev->wext.default_mgmt_key;
    703			if (idx < 0)
    704				return -EINVAL;
    705		} else
    706			idx--;
    707	} else {
    708		if (idx < 1 || idx > 4) {
    709			idx = wdev->wext.default_key;
    710			if (idx < 0)
    711				return -EINVAL;
    712		} else
    713			idx--;
    714	}
    715
    716	addr = ext->addr.sa_data;
    717	if (is_broadcast_ether_addr(addr))
    718		addr = NULL;
    719
    720	memset(&params, 0, sizeof(params));
    721	params.key = ext->key;
    722	params.key_len = ext->key_len;
    723	params.cipher = cipher;
    724
    725	if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
    726		params.seq = ext->rx_seq;
    727		params.seq_len = 6;
    728	}
    729
    730	wiphy_lock(wdev->wiphy);
    731	ret = cfg80211_set_encryption(
    732			rdev, dev,
    733			!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
    734			addr, remove,
    735			ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
    736			idx, &params);
    737	wiphy_unlock(wdev->wiphy);
    738
    739	return ret;
    740}
    741
    742static int cfg80211_wext_giwencode(struct net_device *dev,
    743				   struct iw_request_info *info,
    744				   struct iw_point *erq, char *keybuf)
    745{
    746	struct wireless_dev *wdev = dev->ieee80211_ptr;
    747	int idx;
    748
    749	if (wdev->iftype != NL80211_IFTYPE_STATION &&
    750	    wdev->iftype != NL80211_IFTYPE_ADHOC)
    751		return -EOPNOTSUPP;
    752
    753	idx = erq->flags & IW_ENCODE_INDEX;
    754	if (idx == 0) {
    755		idx = wdev->wext.default_key;
    756		if (idx < 0)
    757			idx = 0;
    758	} else if (idx < 1 || idx > 4)
    759		return -EINVAL;
    760	else
    761		idx--;
    762
    763	erq->flags = idx + 1;
    764
    765	if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
    766		erq->flags |= IW_ENCODE_DISABLED;
    767		erq->length = 0;
    768		return 0;
    769	}
    770
    771	erq->length = min_t(size_t, erq->length,
    772			    wdev->wext.keys->params[idx].key_len);
    773	memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
    774	erq->flags |= IW_ENCODE_ENABLED;
    775
    776	return 0;
    777}
    778
    779static int cfg80211_wext_siwfreq(struct net_device *dev,
    780				 struct iw_request_info *info,
    781				 struct iw_freq *wextfreq, char *extra)
    782{
    783	struct wireless_dev *wdev = dev->ieee80211_ptr;
    784	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    785	struct cfg80211_chan_def chandef = {
    786		.width = NL80211_CHAN_WIDTH_20_NOHT,
    787	};
    788	int freq, ret;
    789
    790	wiphy_lock(&rdev->wiphy);
    791
    792	switch (wdev->iftype) {
    793	case NL80211_IFTYPE_STATION:
    794		ret = cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
    795		break;
    796	case NL80211_IFTYPE_ADHOC:
    797		ret = cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
    798		break;
    799	case NL80211_IFTYPE_MONITOR:
    800		freq = cfg80211_wext_freq(wextfreq);
    801		if (freq < 0) {
    802			ret = freq;
    803			break;
    804		}
    805		if (freq == 0) {
    806			ret = -EINVAL;
    807			break;
    808		}
    809		chandef.center_freq1 = freq;
    810		chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
    811		if (!chandef.chan) {
    812			ret = -EINVAL;
    813			break;
    814		}
    815		ret = cfg80211_set_monitor_channel(rdev, &chandef);
    816		break;
    817	case NL80211_IFTYPE_MESH_POINT:
    818		freq = cfg80211_wext_freq(wextfreq);
    819		if (freq < 0) {
    820			ret = freq;
    821			break;
    822		}
    823		if (freq == 0) {
    824			ret = -EINVAL;
    825			break;
    826		}
    827		chandef.center_freq1 = freq;
    828		chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
    829		if (!chandef.chan) {
    830			ret = -EINVAL;
    831			break;
    832		}
    833		ret = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
    834		break;
    835	default:
    836		ret = -EOPNOTSUPP;
    837		break;
    838	}
    839
    840	wiphy_unlock(&rdev->wiphy);
    841
    842	return ret;
    843}
    844
    845static int cfg80211_wext_giwfreq(struct net_device *dev,
    846				 struct iw_request_info *info,
    847				 struct iw_freq *freq, char *extra)
    848{
    849	struct wireless_dev *wdev = dev->ieee80211_ptr;
    850	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    851	struct cfg80211_chan_def chandef = {};
    852	int ret;
    853
    854	wiphy_lock(&rdev->wiphy);
    855	switch (wdev->iftype) {
    856	case NL80211_IFTYPE_STATION:
    857		ret = cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
    858		break;
    859	case NL80211_IFTYPE_ADHOC:
    860		ret = cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
    861		break;
    862	case NL80211_IFTYPE_MONITOR:
    863		if (!rdev->ops->get_channel) {
    864			ret = -EINVAL;
    865			break;
    866		}
    867
    868		ret = rdev_get_channel(rdev, wdev, &chandef);
    869		if (ret)
    870			break;
    871		freq->m = chandef.chan->center_freq;
    872		freq->e = 6;
    873		ret = 0;
    874		break;
    875	default:
    876		ret = -EINVAL;
    877		break;
    878	}
    879
    880	wiphy_unlock(&rdev->wiphy);
    881
    882	return ret;
    883}
    884
    885static int cfg80211_wext_siwtxpower(struct net_device *dev,
    886				    struct iw_request_info *info,
    887				    union iwreq_data *data, char *extra)
    888{
    889	struct wireless_dev *wdev = dev->ieee80211_ptr;
    890	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    891	enum nl80211_tx_power_setting type;
    892	int dbm = 0;
    893	int ret;
    894
    895	if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
    896		return -EINVAL;
    897	if (data->txpower.flags & IW_TXPOW_RANGE)
    898		return -EINVAL;
    899
    900	if (!rdev->ops->set_tx_power)
    901		return -EOPNOTSUPP;
    902
    903	/* only change when not disabling */
    904	if (!data->txpower.disabled) {
    905		rfkill_set_sw_state(rdev->wiphy.rfkill, false);
    906
    907		if (data->txpower.fixed) {
    908			/*
    909			 * wext doesn't support negative values, see
    910			 * below where it's for automatic
    911			 */
    912			if (data->txpower.value < 0)
    913				return -EINVAL;
    914			dbm = data->txpower.value;
    915			type = NL80211_TX_POWER_FIXED;
    916			/* TODO: do regulatory check! */
    917		} else {
    918			/*
    919			 * Automatic power level setting, max being the value
    920			 * passed in from userland.
    921			 */
    922			if (data->txpower.value < 0) {
    923				type = NL80211_TX_POWER_AUTOMATIC;
    924			} else {
    925				dbm = data->txpower.value;
    926				type = NL80211_TX_POWER_LIMITED;
    927			}
    928		}
    929	} else {
    930		if (rfkill_set_sw_state(rdev->wiphy.rfkill, true))
    931			schedule_work(&rdev->rfkill_block);
    932		return 0;
    933	}
    934
    935	wiphy_lock(&rdev->wiphy);
    936	ret = rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
    937	wiphy_unlock(&rdev->wiphy);
    938
    939	return ret;
    940}
    941
    942static int cfg80211_wext_giwtxpower(struct net_device *dev,
    943				    struct iw_request_info *info,
    944				    union iwreq_data *data, char *extra)
    945{
    946	struct wireless_dev *wdev = dev->ieee80211_ptr;
    947	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
    948	int err, val;
    949
    950	if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
    951		return -EINVAL;
    952	if (data->txpower.flags & IW_TXPOW_RANGE)
    953		return -EINVAL;
    954
    955	if (!rdev->ops->get_tx_power)
    956		return -EOPNOTSUPP;
    957
    958	wiphy_lock(&rdev->wiphy);
    959	err = rdev_get_tx_power(rdev, wdev, &val);
    960	wiphy_unlock(&rdev->wiphy);
    961	if (err)
    962		return err;
    963
    964	/* well... oh well */
    965	data->txpower.fixed = 1;
    966	data->txpower.disabled = rfkill_blocked(rdev->wiphy.rfkill);
    967	data->txpower.value = val;
    968	data->txpower.flags = IW_TXPOW_DBM;
    969
    970	return 0;
    971}
    972
    973static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
    974				 s32 auth_alg)
    975{
    976	int nr_alg = 0;
    977
    978	if (!auth_alg)
    979		return -EINVAL;
    980
    981	if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM |
    982			 IW_AUTH_ALG_SHARED_KEY |
    983			 IW_AUTH_ALG_LEAP))
    984		return -EINVAL;
    985
    986	if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) {
    987		nr_alg++;
    988		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
    989	}
    990
    991	if (auth_alg & IW_AUTH_ALG_SHARED_KEY) {
    992		nr_alg++;
    993		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
    994	}
    995
    996	if (auth_alg & IW_AUTH_ALG_LEAP) {
    997		nr_alg++;
    998		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
    999	}
   1000
   1001	if (nr_alg > 1)
   1002		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
   1003
   1004	return 0;
   1005}
   1006
   1007static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
   1008{
   1009	if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
   1010			     IW_AUTH_WPA_VERSION_WPA2|
   1011		             IW_AUTH_WPA_VERSION_DISABLED))
   1012		return -EINVAL;
   1013
   1014	if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
   1015	    (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
   1016			     IW_AUTH_WPA_VERSION_WPA2)))
   1017		return -EINVAL;
   1018
   1019	if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
   1020		wdev->wext.connect.crypto.wpa_versions &=
   1021			~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
   1022
   1023	if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
   1024		wdev->wext.connect.crypto.wpa_versions |=
   1025			NL80211_WPA_VERSION_1;
   1026
   1027	if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2)
   1028		wdev->wext.connect.crypto.wpa_versions |=
   1029			NL80211_WPA_VERSION_2;
   1030
   1031	return 0;
   1032}
   1033
   1034static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
   1035{
   1036	if (cipher & IW_AUTH_CIPHER_WEP40)
   1037		wdev->wext.connect.crypto.cipher_group =
   1038			WLAN_CIPHER_SUITE_WEP40;
   1039	else if (cipher & IW_AUTH_CIPHER_WEP104)
   1040		wdev->wext.connect.crypto.cipher_group =
   1041			WLAN_CIPHER_SUITE_WEP104;
   1042	else if (cipher & IW_AUTH_CIPHER_TKIP)
   1043		wdev->wext.connect.crypto.cipher_group =
   1044			WLAN_CIPHER_SUITE_TKIP;
   1045	else if (cipher & IW_AUTH_CIPHER_CCMP)
   1046		wdev->wext.connect.crypto.cipher_group =
   1047			WLAN_CIPHER_SUITE_CCMP;
   1048	else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
   1049		wdev->wext.connect.crypto.cipher_group =
   1050			WLAN_CIPHER_SUITE_AES_CMAC;
   1051	else if (cipher & IW_AUTH_CIPHER_NONE)
   1052		wdev->wext.connect.crypto.cipher_group = 0;
   1053	else
   1054		return -EINVAL;
   1055
   1056	return 0;
   1057}
   1058
   1059static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
   1060{
   1061	int nr_ciphers = 0;
   1062	u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
   1063
   1064	if (cipher & IW_AUTH_CIPHER_WEP40) {
   1065		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40;
   1066		nr_ciphers++;
   1067	}
   1068
   1069	if (cipher & IW_AUTH_CIPHER_WEP104) {
   1070		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104;
   1071		nr_ciphers++;
   1072	}
   1073
   1074	if (cipher & IW_AUTH_CIPHER_TKIP) {
   1075		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP;
   1076		nr_ciphers++;
   1077	}
   1078
   1079	if (cipher & IW_AUTH_CIPHER_CCMP) {
   1080		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP;
   1081		nr_ciphers++;
   1082	}
   1083
   1084	if (cipher & IW_AUTH_CIPHER_AES_CMAC) {
   1085		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC;
   1086		nr_ciphers++;
   1087	}
   1088
   1089	BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5);
   1090
   1091	wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers;
   1092
   1093	return 0;
   1094}
   1095
   1096
   1097static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
   1098{
   1099	int nr_akm_suites = 0;
   1100
   1101	if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X |
   1102			IW_AUTH_KEY_MGMT_PSK))
   1103		return -EINVAL;
   1104
   1105	if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) {
   1106		wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
   1107			WLAN_AKM_SUITE_8021X;
   1108		nr_akm_suites++;
   1109	}
   1110
   1111	if (key_mgt & IW_AUTH_KEY_MGMT_PSK) {
   1112		wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
   1113			WLAN_AKM_SUITE_PSK;
   1114		nr_akm_suites++;
   1115	}
   1116
   1117	wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites;
   1118
   1119	return 0;
   1120}
   1121
   1122static int cfg80211_wext_siwauth(struct net_device *dev,
   1123				 struct iw_request_info *info,
   1124				 struct iw_param *data, char *extra)
   1125{
   1126	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1127
   1128	if (wdev->iftype != NL80211_IFTYPE_STATION)
   1129		return -EOPNOTSUPP;
   1130
   1131	switch (data->flags & IW_AUTH_INDEX) {
   1132	case IW_AUTH_PRIVACY_INVOKED:
   1133		wdev->wext.connect.privacy = data->value;
   1134		return 0;
   1135	case IW_AUTH_WPA_VERSION:
   1136		return cfg80211_set_wpa_version(wdev, data->value);
   1137	case IW_AUTH_CIPHER_GROUP:
   1138		return cfg80211_set_cipher_group(wdev, data->value);
   1139	case IW_AUTH_KEY_MGMT:
   1140		return cfg80211_set_key_mgt(wdev, data->value);
   1141	case IW_AUTH_CIPHER_PAIRWISE:
   1142		return cfg80211_set_cipher_pairwise(wdev, data->value);
   1143	case IW_AUTH_80211_AUTH_ALG:
   1144		return cfg80211_set_auth_alg(wdev, data->value);
   1145	case IW_AUTH_WPA_ENABLED:
   1146	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
   1147	case IW_AUTH_DROP_UNENCRYPTED:
   1148	case IW_AUTH_MFP:
   1149		return 0;
   1150	default:
   1151		return -EOPNOTSUPP;
   1152	}
   1153}
   1154
   1155static int cfg80211_wext_giwauth(struct net_device *dev,
   1156				 struct iw_request_info *info,
   1157				 struct iw_param *data, char *extra)
   1158{
   1159	/* XXX: what do we need? */
   1160
   1161	return -EOPNOTSUPP;
   1162}
   1163
   1164static int cfg80211_wext_siwpower(struct net_device *dev,
   1165				  struct iw_request_info *info,
   1166				  struct iw_param *wrq, char *extra)
   1167{
   1168	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1169	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1170	bool ps;
   1171	int timeout = wdev->ps_timeout;
   1172	int err;
   1173
   1174	if (wdev->iftype != NL80211_IFTYPE_STATION)
   1175		return -EINVAL;
   1176
   1177	if (!rdev->ops->set_power_mgmt)
   1178		return -EOPNOTSUPP;
   1179
   1180	if (wrq->disabled) {
   1181		ps = false;
   1182	} else {
   1183		switch (wrq->flags & IW_POWER_MODE) {
   1184		case IW_POWER_ON:       /* If not specified */
   1185		case IW_POWER_MODE:     /* If set all mask */
   1186		case IW_POWER_ALL_R:    /* If explicitely state all */
   1187			ps = true;
   1188			break;
   1189		default:                /* Otherwise we ignore */
   1190			return -EINVAL;
   1191		}
   1192
   1193		if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
   1194			return -EINVAL;
   1195
   1196		if (wrq->flags & IW_POWER_TIMEOUT)
   1197			timeout = wrq->value / 1000;
   1198	}
   1199
   1200	wiphy_lock(&rdev->wiphy);
   1201	err = rdev_set_power_mgmt(rdev, dev, ps, timeout);
   1202	wiphy_unlock(&rdev->wiphy);
   1203	if (err)
   1204		return err;
   1205
   1206	wdev->ps = ps;
   1207	wdev->ps_timeout = timeout;
   1208
   1209	return 0;
   1210
   1211}
   1212
   1213static int cfg80211_wext_giwpower(struct net_device *dev,
   1214				  struct iw_request_info *info,
   1215				  struct iw_param *wrq, char *extra)
   1216{
   1217	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1218
   1219	wrq->disabled = !wdev->ps;
   1220
   1221	return 0;
   1222}
   1223
   1224static int cfg80211_wext_siwrate(struct net_device *dev,
   1225				 struct iw_request_info *info,
   1226				 struct iw_param *rate, char *extra)
   1227{
   1228	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1229	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1230	struct cfg80211_bitrate_mask mask;
   1231	u32 fixed, maxrate;
   1232	struct ieee80211_supported_band *sband;
   1233	int band, ridx, ret;
   1234	bool match = false;
   1235
   1236	if (!rdev->ops->set_bitrate_mask)
   1237		return -EOPNOTSUPP;
   1238
   1239	memset(&mask, 0, sizeof(mask));
   1240	fixed = 0;
   1241	maxrate = (u32)-1;
   1242
   1243	if (rate->value < 0) {
   1244		/* nothing */
   1245	} else if (rate->fixed) {
   1246		fixed = rate->value / 100000;
   1247	} else {
   1248		maxrate = rate->value / 100000;
   1249	}
   1250
   1251	for (band = 0; band < NUM_NL80211_BANDS; band++) {
   1252		sband = wdev->wiphy->bands[band];
   1253		if (sband == NULL)
   1254			continue;
   1255		for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
   1256			struct ieee80211_rate *srate = &sband->bitrates[ridx];
   1257			if (fixed == srate->bitrate) {
   1258				mask.control[band].legacy = 1 << ridx;
   1259				match = true;
   1260				break;
   1261			}
   1262			if (srate->bitrate <= maxrate) {
   1263				mask.control[band].legacy |= 1 << ridx;
   1264				match = true;
   1265			}
   1266		}
   1267	}
   1268
   1269	if (!match)
   1270		return -EINVAL;
   1271
   1272	wiphy_lock(&rdev->wiphy);
   1273	ret = rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
   1274	wiphy_unlock(&rdev->wiphy);
   1275
   1276	return ret;
   1277}
   1278
   1279static int cfg80211_wext_giwrate(struct net_device *dev,
   1280				 struct iw_request_info *info,
   1281				 struct iw_param *rate, char *extra)
   1282{
   1283	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1284	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1285	struct station_info sinfo = {};
   1286	u8 addr[ETH_ALEN];
   1287	int err;
   1288
   1289	if (wdev->iftype != NL80211_IFTYPE_STATION)
   1290		return -EOPNOTSUPP;
   1291
   1292	if (!rdev->ops->get_station)
   1293		return -EOPNOTSUPP;
   1294
   1295	err = 0;
   1296	wdev_lock(wdev);
   1297	if (wdev->current_bss)
   1298		memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN);
   1299	else
   1300		err = -EOPNOTSUPP;
   1301	wdev_unlock(wdev);
   1302	if (err)
   1303		return err;
   1304
   1305	wiphy_lock(&rdev->wiphy);
   1306	err = rdev_get_station(rdev, dev, addr, &sinfo);
   1307	wiphy_unlock(&rdev->wiphy);
   1308	if (err)
   1309		return err;
   1310
   1311	if (!(sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) {
   1312		err = -EOPNOTSUPP;
   1313		goto free;
   1314	}
   1315
   1316	rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
   1317
   1318free:
   1319	cfg80211_sinfo_release_content(&sinfo);
   1320	return err;
   1321}
   1322
   1323/* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
   1324static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
   1325{
   1326	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1327	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1328	/* we are under RTNL - globally locked - so can use static structs */
   1329	static struct iw_statistics wstats;
   1330	static struct station_info sinfo = {};
   1331	u8 bssid[ETH_ALEN];
   1332	int ret;
   1333
   1334	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
   1335		return NULL;
   1336
   1337	if (!rdev->ops->get_station)
   1338		return NULL;
   1339
   1340	/* Grab BSSID of current BSS, if any */
   1341	wdev_lock(wdev);
   1342	if (!wdev->current_bss) {
   1343		wdev_unlock(wdev);
   1344		return NULL;
   1345	}
   1346	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
   1347	wdev_unlock(wdev);
   1348
   1349	memset(&sinfo, 0, sizeof(sinfo));
   1350
   1351	wiphy_lock(&rdev->wiphy);
   1352	ret = rdev_get_station(rdev, dev, bssid, &sinfo);
   1353	wiphy_unlock(&rdev->wiphy);
   1354
   1355	if (ret)
   1356		return NULL;
   1357
   1358	memset(&wstats, 0, sizeof(wstats));
   1359
   1360	switch (rdev->wiphy.signal_type) {
   1361	case CFG80211_SIGNAL_TYPE_MBM:
   1362		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
   1363			int sig = sinfo.signal;
   1364			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
   1365			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
   1366			wstats.qual.updated |= IW_QUAL_DBM;
   1367			wstats.qual.level = sig;
   1368			if (sig < -110)
   1369				sig = -110;
   1370			else if (sig > -40)
   1371				sig = -40;
   1372			wstats.qual.qual = sig + 110;
   1373			break;
   1374		}
   1375		fallthrough;
   1376	case CFG80211_SIGNAL_TYPE_UNSPEC:
   1377		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
   1378			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
   1379			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
   1380			wstats.qual.level = sinfo.signal;
   1381			wstats.qual.qual = sinfo.signal;
   1382			break;
   1383		}
   1384		fallthrough;
   1385	default:
   1386		wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
   1387		wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
   1388	}
   1389
   1390	wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
   1391	if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC))
   1392		wstats.discard.misc = sinfo.rx_dropped_misc;
   1393	if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))
   1394		wstats.discard.retries = sinfo.tx_failed;
   1395
   1396	cfg80211_sinfo_release_content(&sinfo);
   1397
   1398	return &wstats;
   1399}
   1400
   1401static int cfg80211_wext_siwap(struct net_device *dev,
   1402			       struct iw_request_info *info,
   1403			       struct sockaddr *ap_addr, char *extra)
   1404{
   1405	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1406	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1407	int ret;
   1408
   1409	wiphy_lock(&rdev->wiphy);
   1410	switch (wdev->iftype) {
   1411	case NL80211_IFTYPE_ADHOC:
   1412		ret = cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
   1413		break;
   1414	case NL80211_IFTYPE_STATION:
   1415		ret = cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
   1416		break;
   1417	default:
   1418		ret = -EOPNOTSUPP;
   1419		break;
   1420	}
   1421	wiphy_unlock(&rdev->wiphy);
   1422
   1423	return ret;
   1424}
   1425
   1426static int cfg80211_wext_giwap(struct net_device *dev,
   1427			       struct iw_request_info *info,
   1428			       struct sockaddr *ap_addr, char *extra)
   1429{
   1430	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1431	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1432	int ret;
   1433
   1434	wiphy_lock(&rdev->wiphy);
   1435	switch (wdev->iftype) {
   1436	case NL80211_IFTYPE_ADHOC:
   1437		ret = cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
   1438		break;
   1439	case NL80211_IFTYPE_STATION:
   1440		ret = cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
   1441		break;
   1442	default:
   1443		ret = -EOPNOTSUPP;
   1444		break;
   1445	}
   1446	wiphy_unlock(&rdev->wiphy);
   1447
   1448	return ret;
   1449}
   1450
   1451static int cfg80211_wext_siwessid(struct net_device *dev,
   1452				  struct iw_request_info *info,
   1453				  struct iw_point *data, char *ssid)
   1454{
   1455	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1456	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1457	int ret;
   1458
   1459	wiphy_lock(&rdev->wiphy);
   1460	switch (wdev->iftype) {
   1461	case NL80211_IFTYPE_ADHOC:
   1462		ret = cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
   1463		break;
   1464	case NL80211_IFTYPE_STATION:
   1465		ret = cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
   1466		break;
   1467	default:
   1468		ret = -EOPNOTSUPP;
   1469		break;
   1470	}
   1471	wiphy_unlock(&rdev->wiphy);
   1472
   1473	return ret;
   1474}
   1475
   1476static int cfg80211_wext_giwessid(struct net_device *dev,
   1477				  struct iw_request_info *info,
   1478				  struct iw_point *data, char *ssid)
   1479{
   1480	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1481	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1482	int ret;
   1483
   1484	data->flags = 0;
   1485	data->length = 0;
   1486
   1487	wiphy_lock(&rdev->wiphy);
   1488	switch (wdev->iftype) {
   1489	case NL80211_IFTYPE_ADHOC:
   1490		ret = cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
   1491		break;
   1492	case NL80211_IFTYPE_STATION:
   1493		ret = cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
   1494		break;
   1495	default:
   1496		ret = -EOPNOTSUPP;
   1497		break;
   1498	}
   1499	wiphy_unlock(&rdev->wiphy);
   1500
   1501	return ret;
   1502}
   1503
   1504static int cfg80211_wext_siwpmksa(struct net_device *dev,
   1505				  struct iw_request_info *info,
   1506				  struct iw_point *data, char *extra)
   1507{
   1508	struct wireless_dev *wdev = dev->ieee80211_ptr;
   1509	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
   1510	struct cfg80211_pmksa cfg_pmksa;
   1511	struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
   1512	int ret;
   1513
   1514	memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
   1515
   1516	if (wdev->iftype != NL80211_IFTYPE_STATION)
   1517		return -EINVAL;
   1518
   1519	cfg_pmksa.bssid = pmksa->bssid.sa_data;
   1520	cfg_pmksa.pmkid = pmksa->pmkid;
   1521
   1522	wiphy_lock(&rdev->wiphy);
   1523	switch (pmksa->cmd) {
   1524	case IW_PMKSA_ADD:
   1525		if (!rdev->ops->set_pmksa) {
   1526			ret = -EOPNOTSUPP;
   1527			break;
   1528		}
   1529
   1530		ret = rdev_set_pmksa(rdev, dev, &cfg_pmksa);
   1531		break;
   1532	case IW_PMKSA_REMOVE:
   1533		if (!rdev->ops->del_pmksa) {
   1534			ret = -EOPNOTSUPP;
   1535			break;
   1536		}
   1537
   1538		ret = rdev_del_pmksa(rdev, dev, &cfg_pmksa);
   1539		break;
   1540	case IW_PMKSA_FLUSH:
   1541		if (!rdev->ops->flush_pmksa) {
   1542			ret = -EOPNOTSUPP;
   1543			break;
   1544		}
   1545
   1546		ret = rdev_flush_pmksa(rdev, dev);
   1547		break;
   1548	default:
   1549		ret = -EOPNOTSUPP;
   1550		break;
   1551	}
   1552	wiphy_unlock(&rdev->wiphy);
   1553
   1554	return ret;
   1555}
   1556
   1557#define DEFINE_WEXT_COMPAT_STUB(func, type)			\
   1558	static int __ ## func(struct net_device *dev,		\
   1559			      struct iw_request_info *info,	\
   1560			      union iwreq_data *wrqu,		\
   1561			      char *extra)			\
   1562	{							\
   1563		return func(dev, info, (type *)wrqu, extra);	\
   1564	}
   1565
   1566DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwname, char)
   1567DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfreq, struct iw_freq)
   1568DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfreq, struct iw_freq)
   1569DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmode, u32)
   1570DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwmode, u32)
   1571DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrange, struct iw_point)
   1572DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwap, struct sockaddr)
   1573DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwap, struct sockaddr)
   1574DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmlme, struct iw_point)
   1575DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwscan, struct iw_point)
   1576DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwessid, struct iw_point)
   1577DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwessid, struct iw_point)
   1578DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrate, struct iw_param)
   1579DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrate, struct iw_param)
   1580DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrts, struct iw_param)
   1581DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrts, struct iw_param)
   1582DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfrag, struct iw_param)
   1583DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfrag, struct iw_param)
   1584DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwretry, struct iw_param)
   1585DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwretry, struct iw_param)
   1586DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencode, struct iw_point)
   1587DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwencode, struct iw_point)
   1588DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwpower, struct iw_param)
   1589DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpower, struct iw_param)
   1590DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwgenie, struct iw_point)
   1591DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwauth, struct iw_param)
   1592DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwauth, struct iw_param)
   1593DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencodeext, struct iw_point)
   1594DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpmksa, struct iw_point)
   1595
   1596static const iw_handler cfg80211_handlers[] = {
   1597	[IW_IOCTL_IDX(SIOCGIWNAME)]	= __cfg80211_wext_giwname,
   1598	[IW_IOCTL_IDX(SIOCSIWFREQ)]	= __cfg80211_wext_siwfreq,
   1599	[IW_IOCTL_IDX(SIOCGIWFREQ)]	= __cfg80211_wext_giwfreq,
   1600	[IW_IOCTL_IDX(SIOCSIWMODE)]	= __cfg80211_wext_siwmode,
   1601	[IW_IOCTL_IDX(SIOCGIWMODE)]	= __cfg80211_wext_giwmode,
   1602	[IW_IOCTL_IDX(SIOCGIWRANGE)]	= __cfg80211_wext_giwrange,
   1603	[IW_IOCTL_IDX(SIOCSIWAP)]	= __cfg80211_wext_siwap,
   1604	[IW_IOCTL_IDX(SIOCGIWAP)]	= __cfg80211_wext_giwap,
   1605	[IW_IOCTL_IDX(SIOCSIWMLME)]	= __cfg80211_wext_siwmlme,
   1606	[IW_IOCTL_IDX(SIOCSIWSCAN)]	= cfg80211_wext_siwscan,
   1607	[IW_IOCTL_IDX(SIOCGIWSCAN)]	= __cfg80211_wext_giwscan,
   1608	[IW_IOCTL_IDX(SIOCSIWESSID)]	= __cfg80211_wext_siwessid,
   1609	[IW_IOCTL_IDX(SIOCGIWESSID)]	= __cfg80211_wext_giwessid,
   1610	[IW_IOCTL_IDX(SIOCSIWRATE)]	= __cfg80211_wext_siwrate,
   1611	[IW_IOCTL_IDX(SIOCGIWRATE)]	= __cfg80211_wext_giwrate,
   1612	[IW_IOCTL_IDX(SIOCSIWRTS)]	= __cfg80211_wext_siwrts,
   1613	[IW_IOCTL_IDX(SIOCGIWRTS)]	= __cfg80211_wext_giwrts,
   1614	[IW_IOCTL_IDX(SIOCSIWFRAG)]	= __cfg80211_wext_siwfrag,
   1615	[IW_IOCTL_IDX(SIOCGIWFRAG)]	= __cfg80211_wext_giwfrag,
   1616	[IW_IOCTL_IDX(SIOCSIWTXPOW)]	= cfg80211_wext_siwtxpower,
   1617	[IW_IOCTL_IDX(SIOCGIWTXPOW)]	= cfg80211_wext_giwtxpower,
   1618	[IW_IOCTL_IDX(SIOCSIWRETRY)]	= __cfg80211_wext_siwretry,
   1619	[IW_IOCTL_IDX(SIOCGIWRETRY)]	= __cfg80211_wext_giwretry,
   1620	[IW_IOCTL_IDX(SIOCSIWENCODE)]	= __cfg80211_wext_siwencode,
   1621	[IW_IOCTL_IDX(SIOCGIWENCODE)]	= __cfg80211_wext_giwencode,
   1622	[IW_IOCTL_IDX(SIOCSIWPOWER)]	= __cfg80211_wext_siwpower,
   1623	[IW_IOCTL_IDX(SIOCGIWPOWER)]	= __cfg80211_wext_giwpower,
   1624	[IW_IOCTL_IDX(SIOCSIWGENIE)]	= __cfg80211_wext_siwgenie,
   1625	[IW_IOCTL_IDX(SIOCSIWAUTH)]	= __cfg80211_wext_siwauth,
   1626	[IW_IOCTL_IDX(SIOCGIWAUTH)]	= __cfg80211_wext_giwauth,
   1627	[IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= __cfg80211_wext_siwencodeext,
   1628	[IW_IOCTL_IDX(SIOCSIWPMKSA)]	= __cfg80211_wext_siwpmksa,
   1629};
   1630
   1631const struct iw_handler_def cfg80211_wext_handler = {
   1632	.num_standard		= ARRAY_SIZE(cfg80211_handlers),
   1633	.standard		= cfg80211_handlers,
   1634	.get_wireless_stats = cfg80211_wireless_stats,
   1635};