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