xref: /haiku/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c (revision a5061ecec55353a5f394759473f1fd6df04890da)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2001 Atsushi Onoe
5  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: releng/12.0/sys/net80211/ieee80211_ioctl.c 331797 2018-03-30 18:50:13Z brooks $");
31 
32 /*
33  * IEEE 802.11 ioctl support (FreeBSD-specific)
34  */
35 
36 #include "opt_inet.h"
37 #include "opt_wlan.h"
38 
39 #include <sys/endian.h>
40 #include <sys/param.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/socket.h>
44 #include <sys/sockio.h>
45 #include <sys/systm.h>
46 
47 #include <net/if.h>
48 #include <net/if_var.h>
49 #include <net/if_dl.h>
50 #include <net/if_media.h>
51 #include <net/ethernet.h>
52 
53 #ifdef INET
54 #include <netinet/in.h>
55 #include <netinet/if_ether.h>
56 #endif
57 
58 #include <net80211/ieee80211_var.h>
59 #include <net80211/ieee80211_ioctl.h>
60 #include <net80211/ieee80211_regdomain.h>
61 #include <net80211/ieee80211_input.h>
62 
63 #define	IS_UP_AUTO(_vap) \
64 	(IFNET_IS_UP_RUNNING((_vap)->iv_ifp) && \
65 	 (_vap)->iv_roaming == IEEE80211_ROAMING_AUTO)
66 
67 static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
68 static struct ieee80211_channel *findchannel(struct ieee80211com *,
69 		int ieee, int mode);
70 static int ieee80211_scanreq(struct ieee80211vap *,
71 		struct ieee80211_scan_req *);
72 
73 static int
74 ieee80211_ioctl_getkey(u_long cmd, struct ieee80211vap *vap,
75     struct ieee80211req *ireq)
76 {
77 	struct ieee80211com *ic = vap->iv_ic;
78 	struct ieee80211_node *ni;
79 	struct ieee80211req_key ik;
80 	struct ieee80211_key *wk;
81 	const struct ieee80211_cipher *cip;
82 	u_int kid;
83 	int error;
84 
85 	if (ireq->i_len != sizeof(ik))
86 		return EINVAL;
87 	error = copyin(ireq->i_data, &ik, sizeof(ik));
88 	if (error)
89 		return error;
90 	kid = ik.ik_keyix;
91 	if (kid == IEEE80211_KEYIX_NONE) {
92 		ni = ieee80211_find_vap_node(&ic->ic_sta, vap, ik.ik_macaddr);
93 		if (ni == NULL)
94 			return ENOENT;
95 		wk = &ni->ni_ucastkey;
96 	} else {
97 		if (kid >= IEEE80211_WEP_NKID)
98 			return EINVAL;
99 		wk = &vap->iv_nw_keys[kid];
100 		IEEE80211_ADDR_COPY(&ik.ik_macaddr, vap->iv_bss->ni_macaddr);
101 		ni = NULL;
102 	}
103 	cip = wk->wk_cipher;
104 	ik.ik_type = cip->ic_cipher;
105 	ik.ik_keylen = wk->wk_keylen;
106 	ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV);
107 	if (wk->wk_keyix == vap->iv_def_txkey)
108 		ik.ik_flags |= IEEE80211_KEY_DEFAULT;
109 	if (ieee80211_priv_check_vap_getkey(cmd, vap, NULL) == 0) {
110 		/* NB: only root can read key data */
111 		ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID];
112 		ik.ik_keytsc = wk->wk_keytsc;
113 		memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen);
114 		if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) {
115 			memcpy(ik.ik_keydata+wk->wk_keylen,
116 				wk->wk_key + IEEE80211_KEYBUF_SIZE,
117 				IEEE80211_MICBUF_SIZE);
118 			ik.ik_keylen += IEEE80211_MICBUF_SIZE;
119 		}
120 	} else {
121 		ik.ik_keyrsc = 0;
122 		ik.ik_keytsc = 0;
123 		memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata));
124 	}
125 	if (ni != NULL)
126 		ieee80211_free_node(ni);
127 	return copyout(&ik, ireq->i_data, sizeof(ik));
128 }
129 
130 static int
131 ieee80211_ioctl_getchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
132 {
133 	struct ieee80211com *ic = vap->iv_ic;
134 
135 	if (sizeof(ic->ic_chan_active) < ireq->i_len)
136 		ireq->i_len = sizeof(ic->ic_chan_active);
137 	return copyout(&ic->ic_chan_active, ireq->i_data, ireq->i_len);
138 }
139 
140 static int
141 ieee80211_ioctl_getchaninfo(struct ieee80211vap *vap, struct ieee80211req *ireq)
142 {
143 	struct ieee80211com *ic = vap->iv_ic;
144 	uint32_t space;
145 
146 	space = __offsetof(struct ieee80211req_chaninfo,
147 			ic_chans[ic->ic_nchans]);
148 	if (space > ireq->i_len)
149 		space = ireq->i_len;
150 	/* XXX assumes compatible layout */
151 	return copyout(&ic->ic_nchans, ireq->i_data, space);
152 }
153 
154 static int
155 ieee80211_ioctl_getwpaie(struct ieee80211vap *vap,
156 	struct ieee80211req *ireq, int req)
157 {
158 	struct ieee80211_node *ni;
159 	struct ieee80211req_wpaie2 *wpaie;
160 	int error;
161 
162 	if (ireq->i_len < IEEE80211_ADDR_LEN)
163 		return EINVAL;
164 	wpaie = IEEE80211_MALLOC(sizeof(*wpaie), M_TEMP,
165 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
166 	if (wpaie == NULL)
167 		return ENOMEM;
168 	error = copyin(ireq->i_data, wpaie->wpa_macaddr, IEEE80211_ADDR_LEN);
169 	if (error != 0)
170 		goto bad;
171 	ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, wpaie->wpa_macaddr);
172 	if (ni == NULL) {
173 		error = ENOENT;
174 		goto bad;
175 	}
176 	if (ni->ni_ies.wpa_ie != NULL) {
177 		int ielen = ni->ni_ies.wpa_ie[1] + 2;
178 		if (ielen > sizeof(wpaie->wpa_ie))
179 			ielen = sizeof(wpaie->wpa_ie);
180 		memcpy(wpaie->wpa_ie, ni->ni_ies.wpa_ie, ielen);
181 	}
182 	if (req == IEEE80211_IOC_WPAIE2) {
183 		if (ni->ni_ies.rsn_ie != NULL) {
184 			int ielen = ni->ni_ies.rsn_ie[1] + 2;
185 			if (ielen > sizeof(wpaie->rsn_ie))
186 				ielen = sizeof(wpaie->rsn_ie);
187 			memcpy(wpaie->rsn_ie, ni->ni_ies.rsn_ie, ielen);
188 		}
189 		if (ireq->i_len > sizeof(struct ieee80211req_wpaie2))
190 			ireq->i_len = sizeof(struct ieee80211req_wpaie2);
191 	} else {
192 		/* compatibility op, may overwrite wpa ie */
193 		/* XXX check ic_flags? */
194 		if (ni->ni_ies.rsn_ie != NULL) {
195 			int ielen = ni->ni_ies.rsn_ie[1] + 2;
196 			if (ielen > sizeof(wpaie->wpa_ie))
197 				ielen = sizeof(wpaie->wpa_ie);
198 			memcpy(wpaie->wpa_ie, ni->ni_ies.rsn_ie, ielen);
199 		}
200 		if (ireq->i_len > sizeof(struct ieee80211req_wpaie))
201 			ireq->i_len = sizeof(struct ieee80211req_wpaie);
202 	}
203 	ieee80211_free_node(ni);
204 	error = copyout(wpaie, ireq->i_data, ireq->i_len);
205 bad:
206 	IEEE80211_FREE(wpaie, M_TEMP);
207 	return error;
208 }
209 
210 static int
211 ieee80211_ioctl_getstastats(struct ieee80211vap *vap, struct ieee80211req *ireq)
212 {
213 	struct ieee80211_node *ni;
214 	uint8_t macaddr[IEEE80211_ADDR_LEN];
215 	const size_t off = __offsetof(struct ieee80211req_sta_stats, is_stats);
216 	int error;
217 
218 	if (ireq->i_len < off)
219 		return EINVAL;
220 	error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
221 	if (error != 0)
222 		return error;
223 	ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr);
224 	if (ni == NULL)
225 		return ENOENT;
226 	if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
227 		ireq->i_len = sizeof(struct ieee80211req_sta_stats);
228 	/* NB: copy out only the statistics */
229 	error = copyout(&ni->ni_stats, (uint8_t *) ireq->i_data + off,
230 			ireq->i_len - off);
231 	ieee80211_free_node(ni);
232 	return error;
233 }
234 
235 struct scanreq {
236 	struct ieee80211req_scan_result *sr;
237 	size_t space;
238 };
239 
240 static size_t
241 scan_space(const struct ieee80211_scan_entry *se, int *ielen)
242 {
243 	size_t len;
244 
245 	*ielen = se->se_ies.len;
246 	/*
247 	 * NB: ie's can be no more than 255 bytes and the max 802.11
248 	 * packet is <3Kbytes so we are sure this doesn't overflow
249 	 * 16-bits; if this is a concern we can drop the ie's.
250 	 */
251 	len = sizeof(struct ieee80211req_scan_result) + se->se_ssid[1] +
252 	    se->se_meshid[1] + *ielen;
253 	return roundup(len, sizeof(uint32_t));
254 }
255 
256 static void
257 get_scan_space(void *arg, const struct ieee80211_scan_entry *se)
258 {
259 	struct scanreq *req = arg;
260 	int ielen;
261 
262 	req->space += scan_space(se, &ielen);
263 }
264 
265 static void
266 get_scan_result(void *arg, const struct ieee80211_scan_entry *se)
267 {
268 	struct scanreq *req = arg;
269 	struct ieee80211req_scan_result *sr;
270 	int ielen, len, nr, nxr;
271 	uint8_t *cp;
272 
273 	len = scan_space(se, &ielen);
274 	if (len > req->space)
275 		return;
276 
277 	sr = req->sr;
278 	KASSERT(len <= 65535 && ielen <= 65535,
279 	    ("len %u ssid %u ie %u", len, se->se_ssid[1], ielen));
280 	sr->isr_len = len;
281 	sr->isr_ie_off = sizeof(struct ieee80211req_scan_result);
282 	sr->isr_ie_len = ielen;
283 	sr->isr_freq = se->se_chan->ic_freq;
284 	sr->isr_flags = se->se_chan->ic_flags;
285 	sr->isr_rssi = se->se_rssi;
286 	sr->isr_noise = se->se_noise;
287 	sr->isr_intval = se->se_intval;
288 	sr->isr_capinfo = se->se_capinfo;
289 	sr->isr_erp = se->se_erp;
290 	IEEE80211_ADDR_COPY(sr->isr_bssid, se->se_bssid);
291 	nr = min(se->se_rates[1], IEEE80211_RATE_MAXSIZE);
292 	memcpy(sr->isr_rates, se->se_rates+2, nr);
293 	nxr = min(se->se_xrates[1], IEEE80211_RATE_MAXSIZE - nr);
294 	memcpy(sr->isr_rates+nr, se->se_xrates+2, nxr);
295 	sr->isr_nrates = nr + nxr;
296 
297 	/* copy SSID */
298 	sr->isr_ssid_len = se->se_ssid[1];
299 	cp = ((uint8_t *)sr) + sr->isr_ie_off;
300 	memcpy(cp, se->se_ssid+2, sr->isr_ssid_len);
301 
302 	/* copy mesh id */
303 	cp += sr->isr_ssid_len;
304 	sr->isr_meshid_len = se->se_meshid[1];
305 	memcpy(cp, se->se_meshid+2, sr->isr_meshid_len);
306 	cp += sr->isr_meshid_len;
307 
308 	if (ielen)
309 		memcpy(cp, se->se_ies.data, ielen);
310 
311 	req->space -= len;
312 	req->sr = (struct ieee80211req_scan_result *)(((uint8_t *)sr) + len);
313 }
314 
315 static int
316 ieee80211_ioctl_getscanresults(struct ieee80211vap *vap,
317 	struct ieee80211req *ireq)
318 {
319 	struct scanreq req;
320 	int error;
321 
322 	if (ireq->i_len < sizeof(struct scanreq))
323 		return EFAULT;
324 
325 	error = 0;
326 	req.space = 0;
327 	ieee80211_scan_iterate(vap, get_scan_space, &req);
328 	if (req.space > ireq->i_len)
329 		req.space = ireq->i_len;
330 	if (req.space > 0) {
331 		uint32_t space;
332 		void *p;
333 
334 		space = req.space;
335 		/* XXX M_WAITOK after driver lock released */
336 		p = IEEE80211_MALLOC(space, M_TEMP,
337 		    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
338 		if (p == NULL)
339 			return ENOMEM;
340 		req.sr = p;
341 		ieee80211_scan_iterate(vap, get_scan_result, &req);
342 		ireq->i_len = space - req.space;
343 		error = copyout(p, ireq->i_data, ireq->i_len);
344 		IEEE80211_FREE(p, M_TEMP);
345 	} else
346 		ireq->i_len = 0;
347 
348 	return error;
349 }
350 
351 struct stainforeq {
352 	struct ieee80211req_sta_info *si;
353 	size_t	space;
354 };
355 
356 static size_t
357 sta_space(const struct ieee80211_node *ni, size_t *ielen)
358 {
359 	*ielen = ni->ni_ies.len;
360 	return roundup(sizeof(struct ieee80211req_sta_info) + *ielen,
361 		      sizeof(uint32_t));
362 }
363 
364 static void
365 get_sta_space(void *arg, struct ieee80211_node *ni)
366 {
367 	struct stainforeq *req = arg;
368 	size_t ielen;
369 
370 	if (ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP &&
371 	    ni->ni_associd == 0)	/* only associated stations */
372 		return;
373 	req->space += sta_space(ni, &ielen);
374 }
375 
376 static void
377 get_sta_info(void *arg, struct ieee80211_node *ni)
378 {
379 	struct stainforeq *req = arg;
380 	struct ieee80211vap *vap = ni->ni_vap;
381 	struct ieee80211req_sta_info *si;
382 	size_t ielen, len;
383 	uint8_t *cp;
384 
385 	if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
386 	    ni->ni_associd == 0)	/* only associated stations */
387 		return;
388 	if (ni->ni_chan == IEEE80211_CHAN_ANYC)	/* XXX bogus entry */
389 		return;
390 	len = sta_space(ni, &ielen);
391 	if (len > req->space)
392 		return;
393 	si = req->si;
394 	si->isi_len = len;
395 	si->isi_ie_off = sizeof(struct ieee80211req_sta_info);
396 	si->isi_ie_len = ielen;
397 	si->isi_freq = ni->ni_chan->ic_freq;
398 	si->isi_flags = ni->ni_chan->ic_flags;
399 	si->isi_state = ni->ni_flags;
400 	si->isi_authmode = ni->ni_authmode;
401 	vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise);
402 	vap->iv_ic->ic_node_getmimoinfo(ni, &si->isi_mimo);
403 	si->isi_capinfo = ni->ni_capinfo;
404 	si->isi_erp = ni->ni_erp;
405 	IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr);
406 	si->isi_nrates = ni->ni_rates.rs_nrates;
407 	if (si->isi_nrates > 15)
408 		si->isi_nrates = 15;
409 	memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates);
410 	si->isi_txrate = ni->ni_txrate;
411 	if (si->isi_txrate & IEEE80211_RATE_MCS) {
412 		const struct ieee80211_mcs_rates *mcs =
413 		    &ieee80211_htrates[ni->ni_txrate &~ IEEE80211_RATE_MCS];
414 		if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
415 			if (ni->ni_flags & IEEE80211_NODE_SGI40)
416 				si->isi_txmbps = mcs->ht40_rate_800ns;
417 			else
418 				si->isi_txmbps = mcs->ht40_rate_400ns;
419 		} else {
420 			if (ni->ni_flags & IEEE80211_NODE_SGI20)
421 				si->isi_txmbps = mcs->ht20_rate_800ns;
422 			else
423 				si->isi_txmbps = mcs->ht20_rate_400ns;
424 		}
425 	} else
426 		si->isi_txmbps = si->isi_txrate;
427 	si->isi_associd = ni->ni_associd;
428 	si->isi_txpower = ni->ni_txpower;
429 	si->isi_vlan = ni->ni_vlan;
430 	if (ni->ni_flags & IEEE80211_NODE_QOS) {
431 		memcpy(si->isi_txseqs, ni->ni_txseqs, sizeof(ni->ni_txseqs));
432 		memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs));
433 	} else {
434 		si->isi_txseqs[0] = ni->ni_txseqs[IEEE80211_NONQOS_TID];
435 		si->isi_rxseqs[0] = ni->ni_rxseqs[IEEE80211_NONQOS_TID];
436 	}
437 	/* NB: leave all cases in case we relax ni_associd == 0 check */
438 	if (ieee80211_node_is_authorized(ni))
439 		si->isi_inact = vap->iv_inact_run;
440 	else if (ni->ni_associd != 0 ||
441 	    (vap->iv_opmode == IEEE80211_M_WDS &&
442 	     (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)))
443 		si->isi_inact = vap->iv_inact_auth;
444 	else
445 		si->isi_inact = vap->iv_inact_init;
446 	si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT;
447 	si->isi_localid = ni->ni_mllid;
448 	si->isi_peerid = ni->ni_mlpid;
449 	si->isi_peerstate = ni->ni_mlstate;
450 
451 	if (ielen) {
452 		cp = ((uint8_t *)si) + si->isi_ie_off;
453 		memcpy(cp, ni->ni_ies.data, ielen);
454 	}
455 
456 	req->si = (struct ieee80211req_sta_info *)(((uint8_t *)si) + len);
457 	req->space -= len;
458 }
459 
460 static int
461 getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq,
462 	struct ieee80211_node *ni, size_t off)
463 {
464 	struct ieee80211com *ic = vap->iv_ic;
465 	struct stainforeq req;
466 	size_t space;
467 	void *p;
468 	int error;
469 
470 	error = 0;
471 	req.space = 0;
472 	if (ni == NULL) {
473 		ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, get_sta_space,
474 		    &req);
475 	} else
476 		get_sta_space(&req, ni);
477 	if (req.space > ireq->i_len)
478 		req.space = ireq->i_len;
479 	if (req.space > 0) {
480 		space = req.space;
481 		/* XXX M_WAITOK after driver lock released */
482 		p = IEEE80211_MALLOC(space, M_TEMP,
483 		    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
484 		if (p == NULL) {
485 			error = ENOMEM;
486 			goto bad;
487 		}
488 		req.si = p;
489 		if (ni == NULL) {
490 			ieee80211_iterate_nodes_vap(&ic->ic_sta, vap,
491 			    get_sta_info, &req);
492 		} else
493 			get_sta_info(&req, ni);
494 		ireq->i_len = space - req.space;
495 		error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len);
496 		IEEE80211_FREE(p, M_TEMP);
497 	} else
498 		ireq->i_len = 0;
499 bad:
500 	if (ni != NULL)
501 		ieee80211_free_node(ni);
502 	return error;
503 }
504 
505 static int
506 ieee80211_ioctl_getstainfo(struct ieee80211vap *vap, struct ieee80211req *ireq)
507 {
508 	uint8_t macaddr[IEEE80211_ADDR_LEN];
509 	const size_t off = __offsetof(struct ieee80211req_sta_req, info);
510 	struct ieee80211_node *ni;
511 	int error;
512 
513 	if (ireq->i_len < sizeof(struct ieee80211req_sta_req))
514 		return EFAULT;
515 	error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
516 	if (error != 0)
517 		return error;
518 	if (IEEE80211_ADDR_EQ(macaddr, vap->iv_ifp->if_broadcastaddr)) {
519 		ni = NULL;
520 	} else {
521 		ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr);
522 		if (ni == NULL)
523 			return ENOENT;
524 	}
525 	return getstainfo_common(vap, ireq, ni, off);
526 }
527 
528 static int
529 ieee80211_ioctl_getstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq)
530 {
531 	struct ieee80211_node *ni;
532 	struct ieee80211req_sta_txpow txpow;
533 	int error;
534 
535 	if (ireq->i_len != sizeof(txpow))
536 		return EINVAL;
537 	error = copyin(ireq->i_data, &txpow, sizeof(txpow));
538 	if (error != 0)
539 		return error;
540 	ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr);
541 	if (ni == NULL)
542 		return ENOENT;
543 	txpow.it_txpow = ni->ni_txpower;
544 	error = copyout(&txpow, ireq->i_data, sizeof(txpow));
545 	ieee80211_free_node(ni);
546 	return error;
547 }
548 
549 static int
550 ieee80211_ioctl_getwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq)
551 {
552 	struct ieee80211com *ic = vap->iv_ic;
553 	struct ieee80211_wme_state *wme = &ic->ic_wme;
554 	struct wmeParams *wmep;
555 	int ac;
556 
557 	if ((ic->ic_caps & IEEE80211_C_WME) == 0)
558 		return EINVAL;
559 
560 	ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL);
561 	if (ac >= WME_NUM_AC)
562 		ac = WME_AC_BE;
563 	if (ireq->i_len & IEEE80211_WMEPARAM_BSS)
564 		wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac];
565 	else
566 		wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac];
567 	switch (ireq->i_type) {
568 	case IEEE80211_IOC_WME_CWMIN:		/* WME: CWmin */
569 		ireq->i_val = wmep->wmep_logcwmin;
570 		break;
571 	case IEEE80211_IOC_WME_CWMAX:		/* WME: CWmax */
572 		ireq->i_val = wmep->wmep_logcwmax;
573 		break;
574 	case IEEE80211_IOC_WME_AIFS:		/* WME: AIFS */
575 		ireq->i_val = wmep->wmep_aifsn;
576 		break;
577 	case IEEE80211_IOC_WME_TXOPLIMIT:	/* WME: txops limit */
578 		ireq->i_val = wmep->wmep_txopLimit;
579 		break;
580 	case IEEE80211_IOC_WME_ACM:		/* WME: ACM (bss only) */
581 		wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac];
582 		ireq->i_val = wmep->wmep_acm;
583 		break;
584 	case IEEE80211_IOC_WME_ACKPOLICY:	/* WME: ACK policy (!bss only)*/
585 		wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac];
586 		ireq->i_val = !wmep->wmep_noackPolicy;
587 		break;
588 	}
589 	return 0;
590 }
591 
592 static int
593 ieee80211_ioctl_getmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq)
594 {
595 	const struct ieee80211_aclator *acl = vap->iv_acl;
596 
597 	return (acl == NULL ? EINVAL : acl->iac_getioctl(vap, ireq));
598 }
599 
600 static int
601 ieee80211_ioctl_getcurchan(struct ieee80211vap *vap, struct ieee80211req *ireq)
602 {
603 	struct ieee80211com *ic = vap->iv_ic;
604 	struct ieee80211_channel *c;
605 
606 	if (ireq->i_len != sizeof(struct ieee80211_channel))
607 		return EINVAL;
608 	/*
609 	 * vap's may have different operating channels when HT is
610 	 * in use.  When in RUN state report the vap-specific channel.
611 	 * Otherwise return curchan.
612 	 */
613 	if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)
614 		c = vap->iv_bss->ni_chan;
615 	else
616 		c = ic->ic_curchan;
617 	return copyout(c, ireq->i_data, sizeof(*c));
618 }
619 
620 static int
621 getappie(const struct ieee80211_appie *aie, struct ieee80211req *ireq)
622 {
623 	if (aie == NULL)
624 		return EINVAL;
625 	/* NB: truncate, caller can check length */
626 	if (ireq->i_len > aie->ie_len)
627 		ireq->i_len = aie->ie_len;
628 	return copyout(aie->ie_data, ireq->i_data, ireq->i_len);
629 }
630 
631 static int
632 ieee80211_ioctl_getappie(struct ieee80211vap *vap, struct ieee80211req *ireq)
633 {
634 	uint8_t fc0;
635 
636 	fc0 = ireq->i_val & 0xff;
637 	if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
638 		return EINVAL;
639 	/* NB: could check iv_opmode and reject but hardly worth the effort */
640 	switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) {
641 	case IEEE80211_FC0_SUBTYPE_BEACON:
642 		return getappie(vap->iv_appie_beacon, ireq);
643 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
644 		return getappie(vap->iv_appie_proberesp, ireq);
645 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
646 		return getappie(vap->iv_appie_assocresp, ireq);
647 	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
648 		return getappie(vap->iv_appie_probereq, ireq);
649 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
650 		return getappie(vap->iv_appie_assocreq, ireq);
651 	case IEEE80211_FC0_SUBTYPE_BEACON|IEEE80211_FC0_SUBTYPE_PROBE_RESP:
652 		return getappie(vap->iv_appie_wpa, ireq);
653 	}
654 	return EINVAL;
655 }
656 
657 static int
658 ieee80211_ioctl_getregdomain(struct ieee80211vap *vap,
659 	const struct ieee80211req *ireq)
660 {
661 	struct ieee80211com *ic = vap->iv_ic;
662 
663 	if (ireq->i_len != sizeof(ic->ic_regdomain))
664 		return EINVAL;
665 	return copyout(&ic->ic_regdomain, ireq->i_data,
666 	    sizeof(ic->ic_regdomain));
667 }
668 
669 static int
670 ieee80211_ioctl_getroam(struct ieee80211vap *vap,
671 	const struct ieee80211req *ireq)
672 {
673 	size_t len = ireq->i_len;
674 	/* NB: accept short requests for backwards compat */
675 	if (len > sizeof(vap->iv_roamparms))
676 		len = sizeof(vap->iv_roamparms);
677 	return copyout(vap->iv_roamparms, ireq->i_data, len);
678 }
679 
680 static int
681 ieee80211_ioctl_gettxparams(struct ieee80211vap *vap,
682 	const struct ieee80211req *ireq)
683 {
684 	size_t len = ireq->i_len;
685 	/* NB: accept short requests for backwards compat */
686 	if (len > sizeof(vap->iv_txparms))
687 		len = sizeof(vap->iv_txparms);
688 	return copyout(vap->iv_txparms, ireq->i_data, len);
689 }
690 
691 static int
692 ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
693 	const struct ieee80211req *ireq)
694 {
695 	struct ieee80211_devcaps_req *dc;
696 	struct ieee80211req_chaninfo *ci;
697 	int maxchans, error;
698 
699 	maxchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_devcaps_req)) /
700 	    sizeof(struct ieee80211_channel));
701 	/* NB: require 1 so we know ic_nchans is accessible */
702 	if (maxchans < 1)
703 		return EINVAL;
704 	/* constrain max request size, 2K channels is ~24Kbytes */
705 	if (maxchans > 2048)
706 		maxchans = 2048;
707 	dc = (struct ieee80211_devcaps_req *)
708 	    IEEE80211_MALLOC(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP,
709 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
710 	if (dc == NULL)
711 		return ENOMEM;
712 	dc->dc_drivercaps = ic->ic_caps;
713 	dc->dc_cryptocaps = ic->ic_cryptocaps;
714 	dc->dc_htcaps = ic->ic_htcaps;
715 	dc->dc_vhtcaps = ic->ic_vhtcaps;
716 	ci = &dc->dc_chaninfo;
717 	ic->ic_getradiocaps(ic, maxchans, &ci->ic_nchans, ci->ic_chans);
718 	KASSERT(ci->ic_nchans <= maxchans,
719 	    ("nchans %d maxchans %d", ci->ic_nchans, maxchans));
720 	ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans);
721 	error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS_SPACE(dc));
722 	IEEE80211_FREE(dc, M_TEMP);
723 	return error;
724 }
725 
726 static int
727 ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq)
728 {
729 	struct ieee80211_node *ni;
730 	struct ieee80211req_sta_vlan vlan;
731 	int error;
732 
733 	if (ireq->i_len != sizeof(vlan))
734 		return EINVAL;
735 	error = copyin(ireq->i_data, &vlan, sizeof(vlan));
736 	if (error != 0)
737 		return error;
738 	if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) {
739 		ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap,
740 		    vlan.sv_macaddr);
741 		if (ni == NULL)
742 			return ENOENT;
743 	} else
744 		ni = ieee80211_ref_node(vap->iv_bss);
745 	vlan.sv_vlan = ni->ni_vlan;
746 	error = copyout(&vlan, ireq->i_data, sizeof(vlan));
747 	ieee80211_free_node(ni);
748 	return error;
749 }
750 
751 /*
752  * Dummy ioctl get handler so the linker set is defined.
753  */
754 static int
755 dummy_ioctl_get(struct ieee80211vap *vap, struct ieee80211req *ireq)
756 {
757 	return ENOSYS;
758 }
759 IEEE80211_IOCTL_GET(dummy, dummy_ioctl_get);
760 
761 static int
762 ieee80211_ioctl_getdefault(struct ieee80211vap *vap, struct ieee80211req *ireq)
763 {
764 	ieee80211_ioctl_getfunc * const *get;
765 	int error;
766 
767 	SET_FOREACH(get, ieee80211_ioctl_getset) {
768 		error = (*get)(vap, ireq);
769 		if (error != ENOSYS)
770 			return error;
771 	}
772 	return EINVAL;
773 }
774 
775 static int
776 ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
777     struct ieee80211req *ireq)
778 {
779 	struct ieee80211com *ic = vap->iv_ic;
780 	u_int kid, len;
781 	uint8_t tmpkey[IEEE80211_KEYBUF_SIZE];
782 	char tmpssid[IEEE80211_NWID_LEN];
783 	int error = 0;
784 
785 	switch (ireq->i_type) {
786 	case IEEE80211_IOC_IC_NAME:
787 		len = strlen(ic->ic_name) + 1;
788 		if (len > ireq->i_len)
789 			return (EINVAL);
790 		ireq->i_len = len;
791 		error = copyout(ic->ic_name, ireq->i_data, ireq->i_len);
792 		break;
793 	case IEEE80211_IOC_SSID:
794 		switch (vap->iv_state) {
795 		case IEEE80211_S_INIT:
796 		case IEEE80211_S_SCAN:
797 			ireq->i_len = vap->iv_des_ssid[0].len;
798 			memcpy(tmpssid, vap->iv_des_ssid[0].ssid, ireq->i_len);
799 			break;
800 		default:
801 			ireq->i_len = vap->iv_bss->ni_esslen;
802 			memcpy(tmpssid, vap->iv_bss->ni_essid, ireq->i_len);
803 			break;
804 		}
805 		error = copyout(tmpssid, ireq->i_data, ireq->i_len);
806 		break;
807 	case IEEE80211_IOC_NUMSSIDS:
808 		ireq->i_val = 1;
809 		break;
810 	case IEEE80211_IOC_WEP:
811 		if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0)
812 			ireq->i_val = IEEE80211_WEP_OFF;
813 		else if (vap->iv_flags & IEEE80211_F_DROPUNENC)
814 			ireq->i_val = IEEE80211_WEP_ON;
815 		else
816 			ireq->i_val = IEEE80211_WEP_MIXED;
817 		break;
818 	case IEEE80211_IOC_WEPKEY:
819 		kid = (u_int) ireq->i_val;
820 		if (kid >= IEEE80211_WEP_NKID)
821 			return EINVAL;
822 		len = (u_int) vap->iv_nw_keys[kid].wk_keylen;
823 		/* NB: only root can read WEP keys */
824 		if (ieee80211_priv_check_vap_getkey(cmd, vap, NULL) == 0) {
825 			bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len);
826 		} else {
827 			bzero(tmpkey, len);
828 		}
829 		ireq->i_len = len;
830 		error = copyout(tmpkey, ireq->i_data, len);
831 		break;
832 	case IEEE80211_IOC_NUMWEPKEYS:
833 		ireq->i_val = IEEE80211_WEP_NKID;
834 		break;
835 	case IEEE80211_IOC_WEPTXKEY:
836 		ireq->i_val = vap->iv_def_txkey;
837 		break;
838 	case IEEE80211_IOC_AUTHMODE:
839 		if (vap->iv_flags & IEEE80211_F_WPA)
840 			ireq->i_val = IEEE80211_AUTH_WPA;
841 		else
842 			ireq->i_val = vap->iv_bss->ni_authmode;
843 		break;
844 	case IEEE80211_IOC_CHANNEL:
845 		ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan);
846 		break;
847 	case IEEE80211_IOC_POWERSAVE:
848 		if (vap->iv_flags & IEEE80211_F_PMGTON)
849 			ireq->i_val = IEEE80211_POWERSAVE_ON;
850 		else
851 			ireq->i_val = IEEE80211_POWERSAVE_OFF;
852 		break;
853 	case IEEE80211_IOC_POWERSAVESLEEP:
854 		ireq->i_val = ic->ic_lintval;
855 		break;
856 	case IEEE80211_IOC_RTSTHRESHOLD:
857 		ireq->i_val = vap->iv_rtsthreshold;
858 		break;
859 	case IEEE80211_IOC_PROTMODE:
860 		ireq->i_val = vap->iv_protmode;
861 		break;
862 	case IEEE80211_IOC_TXPOWER:
863 		/*
864 		 * Tx power limit is the min of max regulatory
865 		 * power, any user-set limit, and the max the
866 		 * radio can do.
867 		 *
868 		 * TODO: methodize this
869 		 */
870 		ireq->i_val = 2*ic->ic_curchan->ic_maxregpower;
871 		if (ireq->i_val > ic->ic_txpowlimit)
872 			ireq->i_val = ic->ic_txpowlimit;
873 		if (ireq->i_val > ic->ic_curchan->ic_maxpower)
874 			ireq->i_val = ic->ic_curchan->ic_maxpower;
875 		break;
876 	case IEEE80211_IOC_WPA:
877 		switch (vap->iv_flags & IEEE80211_F_WPA) {
878 		case IEEE80211_F_WPA1:
879 			ireq->i_val = 1;
880 			break;
881 		case IEEE80211_F_WPA2:
882 			ireq->i_val = 2;
883 			break;
884 		case IEEE80211_F_WPA1 | IEEE80211_F_WPA2:
885 			ireq->i_val = 3;
886 			break;
887 		default:
888 			ireq->i_val = 0;
889 			break;
890 		}
891 		break;
892 	case IEEE80211_IOC_CHANLIST:
893 		error = ieee80211_ioctl_getchanlist(vap, ireq);
894 		break;
895 	case IEEE80211_IOC_ROAMING:
896 		ireq->i_val = vap->iv_roaming;
897 		break;
898 	case IEEE80211_IOC_PRIVACY:
899 		ireq->i_val = (vap->iv_flags & IEEE80211_F_PRIVACY) != 0;
900 		break;
901 	case IEEE80211_IOC_DROPUNENCRYPTED:
902 		ireq->i_val = (vap->iv_flags & IEEE80211_F_DROPUNENC) != 0;
903 		break;
904 	case IEEE80211_IOC_COUNTERMEASURES:
905 		ireq->i_val = (vap->iv_flags & IEEE80211_F_COUNTERM) != 0;
906 		break;
907 	case IEEE80211_IOC_WME:
908 		ireq->i_val = (vap->iv_flags & IEEE80211_F_WME) != 0;
909 		break;
910 	case IEEE80211_IOC_HIDESSID:
911 		ireq->i_val = (vap->iv_flags & IEEE80211_F_HIDESSID) != 0;
912 		break;
913 	case IEEE80211_IOC_APBRIDGE:
914 		ireq->i_val = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0;
915 		break;
916 	case IEEE80211_IOC_WPAKEY:
917 		error = ieee80211_ioctl_getkey(cmd, vap, ireq);
918 		break;
919 	case IEEE80211_IOC_CHANINFO:
920 		error = ieee80211_ioctl_getchaninfo(vap, ireq);
921 		break;
922 	case IEEE80211_IOC_BSSID:
923 		if (ireq->i_len != IEEE80211_ADDR_LEN)
924 			return EINVAL;
925 		if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP) {
926 			error = copyout(vap->iv_opmode == IEEE80211_M_WDS ?
927 			    vap->iv_bss->ni_macaddr : vap->iv_bss->ni_bssid,
928 			    ireq->i_data, ireq->i_len);
929 		} else
930 			error = copyout(vap->iv_des_bssid, ireq->i_data,
931 			    ireq->i_len);
932 		break;
933 	case IEEE80211_IOC_WPAIE:
934 	case IEEE80211_IOC_WPAIE2:
935 		error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type);
936 		break;
937 	case IEEE80211_IOC_SCAN_RESULTS:
938 		error = ieee80211_ioctl_getscanresults(vap, ireq);
939 		break;
940 	case IEEE80211_IOC_STA_STATS:
941 		error = ieee80211_ioctl_getstastats(vap, ireq);
942 		break;
943 	case IEEE80211_IOC_TXPOWMAX:
944 		ireq->i_val = vap->iv_bss->ni_txpower;
945 		break;
946 	case IEEE80211_IOC_STA_TXPOW:
947 		error = ieee80211_ioctl_getstatxpow(vap, ireq);
948 		break;
949 	case IEEE80211_IOC_STA_INFO:
950 		error = ieee80211_ioctl_getstainfo(vap, ireq);
951 		break;
952 	case IEEE80211_IOC_WME_CWMIN:		/* WME: CWmin */
953 	case IEEE80211_IOC_WME_CWMAX:		/* WME: CWmax */
954 	case IEEE80211_IOC_WME_AIFS:		/* WME: AIFS */
955 	case IEEE80211_IOC_WME_TXOPLIMIT:	/* WME: txops limit */
956 	case IEEE80211_IOC_WME_ACM:		/* WME: ACM (bss only) */
957 	case IEEE80211_IOC_WME_ACKPOLICY:	/* WME: ACK policy (!bss only) */
958 		error = ieee80211_ioctl_getwmeparam(vap, ireq);
959 		break;
960 	case IEEE80211_IOC_DTIM_PERIOD:
961 		ireq->i_val = vap->iv_dtim_period;
962 		break;
963 	case IEEE80211_IOC_BEACON_INTERVAL:
964 		/* NB: get from ic_bss for station mode */
965 		ireq->i_val = vap->iv_bss->ni_intval;
966 		break;
967 	case IEEE80211_IOC_PUREG:
968 		ireq->i_val = (vap->iv_flags & IEEE80211_F_PUREG) != 0;
969 		break;
970 	case IEEE80211_IOC_QUIET:
971 		ireq->i_val = vap->iv_quiet;
972 		break;
973 	case IEEE80211_IOC_QUIET_COUNT:
974 		ireq->i_val = vap->iv_quiet_count;
975 		break;
976 	case IEEE80211_IOC_QUIET_PERIOD:
977 		ireq->i_val = vap->iv_quiet_period;
978 		break;
979 	case IEEE80211_IOC_QUIET_DUR:
980 		ireq->i_val = vap->iv_quiet_duration;
981 		break;
982 	case IEEE80211_IOC_QUIET_OFFSET:
983 		ireq->i_val = vap->iv_quiet_offset;
984 		break;
985 	case IEEE80211_IOC_BGSCAN:
986 		ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0;
987 		break;
988 	case IEEE80211_IOC_BGSCAN_IDLE:
989 		ireq->i_val = vap->iv_bgscanidle*hz/1000;	/* ms */
990 		break;
991 	case IEEE80211_IOC_BGSCAN_INTERVAL:
992 		ireq->i_val = vap->iv_bgscanintvl/hz;		/* seconds */
993 		break;
994 	case IEEE80211_IOC_SCANVALID:
995 		ireq->i_val = vap->iv_scanvalid/hz;		/* seconds */
996 		break;
997 	case IEEE80211_IOC_FRAGTHRESHOLD:
998 		ireq->i_val = vap->iv_fragthreshold;
999 		break;
1000 	case IEEE80211_IOC_MACCMD:
1001 		error = ieee80211_ioctl_getmaccmd(vap, ireq);
1002 		break;
1003 	case IEEE80211_IOC_BURST:
1004 		ireq->i_val = (vap->iv_flags & IEEE80211_F_BURST) != 0;
1005 		break;
1006 	case IEEE80211_IOC_BMISSTHRESHOLD:
1007 		ireq->i_val = vap->iv_bmissthreshold;
1008 		break;
1009 	case IEEE80211_IOC_CURCHAN:
1010 		error = ieee80211_ioctl_getcurchan(vap, ireq);
1011 		break;
1012 	case IEEE80211_IOC_SHORTGI:
1013 		ireq->i_val = 0;
1014 		if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)
1015 			ireq->i_val |= IEEE80211_HTCAP_SHORTGI20;
1016 		if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)
1017 			ireq->i_val |= IEEE80211_HTCAP_SHORTGI40;
1018 		break;
1019 	case IEEE80211_IOC_AMPDU:
1020 		ireq->i_val = 0;
1021 		if (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX)
1022 			ireq->i_val |= 1;
1023 		if (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)
1024 			ireq->i_val |= 2;
1025 		break;
1026 	case IEEE80211_IOC_AMPDU_LIMIT:
1027 		/* XXX TODO: make this a per-node thing; and leave this as global */
1028 		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
1029 			ireq->i_val = vap->iv_ampdu_rxmax;
1030 		else if (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)
1031 			/*
1032 			 * XXX TODO: this isn't completely correct, as we've
1033 			 * negotiated the higher of the two.
1034 			 */
1035 			ireq->i_val = _IEEE80211_MASKSHIFT( vap->iv_bss->ni_htparam,
1036 			    IEEE80211_HTCAP_MAXRXAMPDU);
1037 		else
1038 			ireq->i_val = vap->iv_ampdu_limit;
1039 		break;
1040 	case IEEE80211_IOC_AMPDU_DENSITY:
1041 		/* XXX TODO: make this a per-node thing; and leave this as global */
1042 		if (vap->iv_opmode == IEEE80211_M_STA &&
1043 		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP))
1044 			/*
1045 			 * XXX TODO: this isn't completely correct, as we've
1046 			 * negotiated the higher of the two.
1047 			 */
1048 			ireq->i_val = _IEEE80211_MASKSHIFT(vap->iv_bss->ni_htparam,
1049 			    IEEE80211_HTCAP_MPDUDENSITY);
1050 		else
1051 			ireq->i_val = vap->iv_ampdu_density;
1052 		break;
1053 	case IEEE80211_IOC_AMSDU:
1054 		ireq->i_val = 0;
1055 		if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX)
1056 			ireq->i_val |= 1;
1057 		if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_RX)
1058 			ireq->i_val |= 2;
1059 		break;
1060 	case IEEE80211_IOC_AMSDU_LIMIT:
1061 		ireq->i_val = vap->iv_amsdu_limit;	/* XXX truncation? */
1062 		break;
1063 	case IEEE80211_IOC_PUREN:
1064 		ireq->i_val = (vap->iv_flags_ht & IEEE80211_FHT_PUREN) != 0;
1065 		break;
1066 	case IEEE80211_IOC_DOTH:
1067 		ireq->i_val = (vap->iv_flags & IEEE80211_F_DOTH) != 0;
1068 		break;
1069 	case IEEE80211_IOC_REGDOMAIN:
1070 		error = ieee80211_ioctl_getregdomain(vap, ireq);
1071 		break;
1072 	case IEEE80211_IOC_ROAM:
1073 		error = ieee80211_ioctl_getroam(vap, ireq);
1074 		break;
1075 	case IEEE80211_IOC_TXPARAMS:
1076 		error = ieee80211_ioctl_gettxparams(vap, ireq);
1077 		break;
1078 	case IEEE80211_IOC_HTCOMPAT:
1079 		ireq->i_val = (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) != 0;
1080 		break;
1081 	case IEEE80211_IOC_DWDS:
1082 		ireq->i_val = (vap->iv_flags & IEEE80211_F_DWDS) != 0;
1083 		break;
1084 	case IEEE80211_IOC_INACTIVITY:
1085 		ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_INACT) != 0;
1086 		break;
1087 	case IEEE80211_IOC_APPIE:
1088 		error = ieee80211_ioctl_getappie(vap, ireq);
1089 		break;
1090 	case IEEE80211_IOC_WPS:
1091 		ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_WPS) != 0;
1092 		break;
1093 	case IEEE80211_IOC_TSN:
1094 		ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_TSN) != 0;
1095 		break;
1096 	case IEEE80211_IOC_DFS:
1097 		ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DFS) != 0;
1098 		break;
1099 	case IEEE80211_IOC_DOTD:
1100 		ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DOTD) != 0;
1101 		break;
1102 	case IEEE80211_IOC_DEVCAPS:
1103 		error = ieee80211_ioctl_getdevcaps(ic, ireq);
1104 		break;
1105 	case IEEE80211_IOC_HTPROTMODE:
1106 		ireq->i_val = vap->iv_htprotmode;
1107 		break;
1108 	case IEEE80211_IOC_HTCONF:
1109 		if (vap->iv_flags_ht & IEEE80211_FHT_HT) {
1110 			ireq->i_val = 1;
1111 			if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)
1112 				ireq->i_val |= 2;
1113 		} else
1114 			ireq->i_val = 0;
1115 		break;
1116 	case IEEE80211_IOC_STA_VLAN:
1117 		error = ieee80211_ioctl_getstavlan(vap, ireq);
1118 		break;
1119 	case IEEE80211_IOC_SMPS:
1120 		if (vap->iv_opmode == IEEE80211_M_STA &&
1121 		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
1122 			if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS)
1123 				ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC;
1124 			else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS)
1125 				ireq->i_val = IEEE80211_HTCAP_SMPS_ENA;
1126 			else
1127 				ireq->i_val = IEEE80211_HTCAP_SMPS_OFF;
1128 		} else
1129 			ireq->i_val = vap->iv_htcaps & IEEE80211_HTCAP_SMPS;
1130 		break;
1131 	case IEEE80211_IOC_RIFS:
1132 		if (vap->iv_opmode == IEEE80211_M_STA &&
1133 		    (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP))
1134 			ireq->i_val =
1135 			    (vap->iv_bss->ni_flags & IEEE80211_NODE_RIFS) != 0;
1136 		else
1137 			ireq->i_val =
1138 			    (vap->iv_flags_ht & IEEE80211_FHT_RIFS) != 0;
1139 		break;
1140 	case IEEE80211_IOC_STBC:
1141 		ireq->i_val = 0;
1142 		if (vap->iv_flags_ht & IEEE80211_FHT_STBC_TX)
1143 			ireq->i_val |= 1;
1144 		if (vap->iv_flags_ht & IEEE80211_FHT_STBC_RX)
1145 			ireq->i_val |= 2;
1146 		break;
1147 	case IEEE80211_IOC_LDPC:
1148 		ireq->i_val = 0;
1149 		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX)
1150 			ireq->i_val |= 1;
1151 		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX)
1152 			ireq->i_val |= 2;
1153 		break;
1154 	case IEEE80211_IOC_UAPSD:
1155 		ireq->i_val = 0;
1156 		if (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD)
1157 			ireq->i_val = 1;
1158 		break;
1159 	case IEEE80211_IOC_VHTCONF:
1160 		ireq->i_val = vap->iv_flags_vht & IEEE80211_FVHT_MASK;
1161 		break;
1162 	default:
1163 		error = ieee80211_ioctl_getdefault(vap, ireq);
1164 		break;
1165 	}
1166 	return error;
1167 }
1168 
1169 static int
1170 ieee80211_ioctl_setkey(struct ieee80211vap *vap, struct ieee80211req *ireq)
1171 {
1172 	struct ieee80211req_key ik;
1173 	struct ieee80211_node *ni;
1174 	struct ieee80211_key *wk;
1175 	uint16_t kid;
1176 	int error, i;
1177 
1178 	if (ireq->i_len != sizeof(ik))
1179 		return EINVAL;
1180 	error = copyin(ireq->i_data, &ik, sizeof(ik));
1181 	if (error)
1182 		return error;
1183 	/* NB: cipher support is verified by ieee80211_crypt_newkey */
1184 	/* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */
1185 	if (ik.ik_keylen > sizeof(ik.ik_keydata))
1186 		return E2BIG;
1187 	kid = ik.ik_keyix;
1188 	if (kid == IEEE80211_KEYIX_NONE) {
1189 		/* XXX unicast keys currently must be tx/rx */
1190 		if (ik.ik_flags != (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))
1191 			return EINVAL;
1192 		if (vap->iv_opmode == IEEE80211_M_STA) {
1193 			ni = ieee80211_ref_node(vap->iv_bss);
1194 			if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid)) {
1195 				ieee80211_free_node(ni);
1196 				return EADDRNOTAVAIL;
1197 			}
1198 		} else {
1199 			ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap,
1200 				ik.ik_macaddr);
1201 			if (ni == NULL)
1202 				return ENOENT;
1203 		}
1204 		wk = &ni->ni_ucastkey;
1205 	} else {
1206 		if (kid >= IEEE80211_WEP_NKID)
1207 			return EINVAL;
1208 		wk = &vap->iv_nw_keys[kid];
1209 		/*
1210 		 * Global slots start off w/o any assigned key index.
1211 		 * Force one here for consistency with IEEE80211_IOC_WEPKEY.
1212 		 */
1213 		if (wk->wk_keyix == IEEE80211_KEYIX_NONE)
1214 			wk->wk_keyix = kid;
1215 		ni = NULL;
1216 	}
1217 	error = 0;
1218 	ieee80211_key_update_begin(vap);
1219 	if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) {
1220 		wk->wk_keylen = ik.ik_keylen;
1221 		/* NB: MIC presence is implied by cipher type */
1222 		if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE)
1223 			wk->wk_keylen = IEEE80211_KEYBUF_SIZE;
1224 		for (i = 0; i < IEEE80211_TID_SIZE; i++)
1225 			wk->wk_keyrsc[i] = ik.ik_keyrsc;
1226 		wk->wk_keytsc = 0;			/* new key, reset */
1227 		memset(wk->wk_key, 0, sizeof(wk->wk_key));
1228 		memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen);
1229 		IEEE80211_ADDR_COPY(wk->wk_macaddr,
1230 		    ni != NULL ?  ni->ni_macaddr : ik.ik_macaddr);
1231 		if (!ieee80211_crypto_setkey(vap, wk))
1232 			error = EIO;
1233 		else if ((ik.ik_flags & IEEE80211_KEY_DEFAULT))
1234 			/*
1235 			 * Inform the driver that this is the default
1236 			 * transmit key.  Now, ideally we'd just set
1237 			 * a flag in the key update that would
1238 			 * say "yes, we're the default key", but
1239 			 * that currently isn't the way the ioctl ->
1240 			 * key interface works.
1241 			 */
1242 			ieee80211_crypto_set_deftxkey(vap, kid);
1243 	} else
1244 		error = ENXIO;
1245 	ieee80211_key_update_end(vap);
1246 	if (ni != NULL)
1247 		ieee80211_free_node(ni);
1248 	return error;
1249 }
1250 
1251 static int
1252 ieee80211_ioctl_delkey(struct ieee80211vap *vap, struct ieee80211req *ireq)
1253 {
1254 	struct ieee80211req_del_key dk;
1255 	int kid, error;
1256 
1257 	if (ireq->i_len != sizeof(dk))
1258 		return EINVAL;
1259 	error = copyin(ireq->i_data, &dk, sizeof(dk));
1260 	if (error)
1261 		return error;
1262 	kid = dk.idk_keyix;
1263 	/* XXX uint8_t -> uint16_t */
1264 	if (dk.idk_keyix == (uint8_t) IEEE80211_KEYIX_NONE) {
1265 		struct ieee80211_node *ni;
1266 
1267 		if (vap->iv_opmode == IEEE80211_M_STA) {
1268 			ni = ieee80211_ref_node(vap->iv_bss);
1269 			if (!IEEE80211_ADDR_EQ(dk.idk_macaddr, ni->ni_bssid)) {
1270 				ieee80211_free_node(ni);
1271 				return EADDRNOTAVAIL;
1272 			}
1273 		} else {
1274 			ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap,
1275 				dk.idk_macaddr);
1276 			if (ni == NULL)
1277 				return ENOENT;
1278 		}
1279 		/* XXX error return */
1280 		ieee80211_node_delucastkey(ni);
1281 		ieee80211_free_node(ni);
1282 	} else {
1283 		if (kid >= IEEE80211_WEP_NKID)
1284 			return EINVAL;
1285 		/* XXX error return */
1286 		ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[kid]);
1287 	}
1288 	return 0;
1289 }
1290 
1291 struct mlmeop {
1292 	struct ieee80211vap *vap;
1293 	int	op;
1294 	int	reason;
1295 };
1296 
1297 static void
1298 mlmedebug(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
1299 	int op, int reason)
1300 {
1301 #ifdef IEEE80211_DEBUG
1302 	static const struct {
1303 		int mask;
1304 		const char *opstr;
1305 	} ops[] = {
1306 		{ 0, "op#0" },
1307 		{ IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE |
1308 		  IEEE80211_MSG_ASSOC, "assoc" },
1309 		{ IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE |
1310 		  IEEE80211_MSG_ASSOC, "disassoc" },
1311 		{ IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE |
1312 		  IEEE80211_MSG_AUTH, "deauth" },
1313 		{ IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE |
1314 		  IEEE80211_MSG_AUTH, "authorize" },
1315 		{ IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE |
1316 		  IEEE80211_MSG_AUTH, "unauthorize" },
1317 	};
1318 
1319 	if (op == IEEE80211_MLME_AUTH) {
1320 		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_IOCTL |
1321 		    IEEE80211_MSG_STATE | IEEE80211_MSG_AUTH, mac,
1322 		    "station authenticate %s via MLME (reason: %d (%s))",
1323 		    reason == IEEE80211_STATUS_SUCCESS ? "ACCEPT" : "REJECT",
1324 		    reason, ieee80211_reason_to_string(reason));
1325 	} else if (!(IEEE80211_MLME_ASSOC <= op && op <= IEEE80211_MLME_AUTH)) {
1326 		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, mac,
1327 		    "unknown MLME request %d (reason: %d (%s))", op, reason,
1328 		    ieee80211_reason_to_string(reason));
1329 	} else if (reason == IEEE80211_STATUS_SUCCESS) {
1330 		IEEE80211_NOTE_MAC(vap, ops[op].mask, mac,
1331 		    "station %s via MLME", ops[op].opstr);
1332 	} else {
1333 		IEEE80211_NOTE_MAC(vap, ops[op].mask, mac,
1334 		    "station %s via MLME (reason: %d (%s))", ops[op].opstr,
1335 		    reason, ieee80211_reason_to_string(reason));
1336 	}
1337 #endif /* IEEE80211_DEBUG */
1338 }
1339 
1340 static void
1341 domlme(void *arg, struct ieee80211_node *ni)
1342 {
1343 	struct mlmeop *mop = arg;
1344 	struct ieee80211vap *vap = ni->ni_vap;
1345 
1346 	if (vap != mop->vap)
1347 		return;
1348 	/*
1349 	 * NB: if ni_associd is zero then the node is already cleaned
1350 	 * up and we don't need to do this (we're safely holding a
1351 	 * reference but should otherwise not modify it's state).
1352 	 */
1353 	if (ni->ni_associd == 0)
1354 		return;
1355 	mlmedebug(vap, ni->ni_macaddr, mop->op, mop->reason);
1356 	if (mop->op == IEEE80211_MLME_DEAUTH) {
1357 		IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
1358 		    mop->reason);
1359 	} else {
1360 		IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC,
1361 		    mop->reason);
1362 	}
1363 	ieee80211_node_leave(ni);
1364 }
1365 
1366 static int
1367 setmlme_dropsta(struct ieee80211vap *vap,
1368 	const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop)
1369 {
1370 	struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;
1371 	struct ieee80211_node *ni;
1372 	int error = 0;
1373 
1374 	/* NB: the broadcast address means do 'em all */
1375 	if (!IEEE80211_ADDR_EQ(mac, vap->iv_ifp->if_broadcastaddr)) {
1376 		IEEE80211_NODE_LOCK(nt);
1377 		ni = ieee80211_find_node_locked(nt, mac);
1378 		IEEE80211_NODE_UNLOCK(nt);
1379 		/*
1380 		 * Don't do the node update inside the node
1381 		 * table lock.  This unfortunately causes LORs
1382 		 * with drivers and their TX paths.
1383 		 */
1384 		if (ni != NULL) {
1385 			domlme(mlmeop, ni);
1386 			ieee80211_free_node(ni);
1387 		} else
1388 			error = ENOENT;
1389 	} else {
1390 		ieee80211_iterate_nodes(nt, domlme, mlmeop);
1391 	}
1392 	return error;
1393 }
1394 
1395 static int
1396 setmlme_common(struct ieee80211vap *vap, int op,
1397 	const uint8_t mac[IEEE80211_ADDR_LEN], int reason)
1398 {
1399 	struct ieee80211com *ic = vap->iv_ic;
1400 	struct ieee80211_node_table *nt = &ic->ic_sta;
1401 	struct ieee80211_node *ni;
1402 	struct mlmeop mlmeop;
1403 	int error;
1404 
1405 	error = 0;
1406 	switch (op) {
1407 	case IEEE80211_MLME_DISASSOC:
1408 	case IEEE80211_MLME_DEAUTH:
1409 		switch (vap->iv_opmode) {
1410 		case IEEE80211_M_STA:
1411 			mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason);
1412 			/* XXX not quite right */
1413 			ieee80211_new_state(vap, IEEE80211_S_INIT, reason);
1414 			break;
1415 		case IEEE80211_M_HOSTAP:
1416 			mlmeop.vap = vap;
1417 			mlmeop.op = op;
1418 			mlmeop.reason = reason;
1419 			error = setmlme_dropsta(vap, mac, &mlmeop);
1420 			break;
1421 		case IEEE80211_M_WDS:
1422 			/* XXX user app should send raw frame? */
1423 			if (op != IEEE80211_MLME_DEAUTH) {
1424 				error = EINVAL;
1425 				break;
1426 			}
1427 #if 0
1428 			/* XXX accept any address, simplifies user code */
1429 			if (!IEEE80211_ADDR_EQ(mac, vap->iv_bss->ni_macaddr)) {
1430 				error = EINVAL;
1431 				break;
1432 			}
1433 #endif
1434 			mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason);
1435 			ni = ieee80211_ref_node(vap->iv_bss);
1436 			IEEE80211_SEND_MGMT(ni,
1437 			    IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
1438 			ieee80211_free_node(ni);
1439 			break;
1440 		case IEEE80211_M_MBSS:
1441 			IEEE80211_NODE_LOCK(nt);
1442 			ni = ieee80211_find_node_locked(nt, mac);
1443 			/*
1444 			 * Don't do the node update inside the node
1445 			 * table lock.  This unfortunately causes LORs
1446 			 * with drivers and their TX paths.
1447 			 */
1448 			IEEE80211_NODE_UNLOCK(nt);
1449 			if (ni != NULL) {
1450 				ieee80211_node_leave(ni);
1451 				ieee80211_free_node(ni);
1452 			} else {
1453 				error = ENOENT;
1454 			}
1455 			break;
1456 		default:
1457 			error = EINVAL;
1458 			break;
1459 		}
1460 		break;
1461 	case IEEE80211_MLME_AUTHORIZE:
1462 	case IEEE80211_MLME_UNAUTHORIZE:
1463 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
1464 		    vap->iv_opmode != IEEE80211_M_WDS) {
1465 			error = EINVAL;
1466 			break;
1467 		}
1468 		IEEE80211_NODE_LOCK(nt);
1469 		ni = ieee80211_find_vap_node_locked(nt, vap, mac);
1470 		/*
1471 		 * Don't do the node update inside the node
1472 		 * table lock.  This unfortunately causes LORs
1473 		 * with drivers and their TX paths.
1474 		 */
1475 		IEEE80211_NODE_UNLOCK(nt);
1476 		if (ni != NULL) {
1477 			mlmedebug(vap, mac, op, reason);
1478 			if (op == IEEE80211_MLME_AUTHORIZE)
1479 				ieee80211_node_authorize(ni);
1480 			else
1481 				ieee80211_node_unauthorize(ni);
1482 			ieee80211_free_node(ni);
1483 		} else
1484 			error = ENOENT;
1485 		break;
1486 	case IEEE80211_MLME_AUTH:
1487 		if (vap->iv_opmode != IEEE80211_M_HOSTAP) {
1488 			error = EINVAL;
1489 			break;
1490 		}
1491 		IEEE80211_NODE_LOCK(nt);
1492 		ni = ieee80211_find_vap_node_locked(nt, vap, mac);
1493 		/*
1494 		 * Don't do the node update inside the node
1495 		 * table lock.  This unfortunately causes LORs
1496 		 * with drivers and their TX paths.
1497 		 */
1498 		IEEE80211_NODE_UNLOCK(nt);
1499 		if (ni != NULL) {
1500 			mlmedebug(vap, mac, op, reason);
1501 			if (reason == IEEE80211_STATUS_SUCCESS) {
1502 				IEEE80211_SEND_MGMT(ni,
1503 				    IEEE80211_FC0_SUBTYPE_AUTH, 2);
1504 				/*
1505 				 * For shared key auth, just continue the
1506 				 * exchange.  Otherwise when 802.1x is not in
1507 				 * use mark the port authorized at this point
1508 				 * so traffic can flow.
1509 				 */
1510 				if (ni->ni_authmode != IEEE80211_AUTH_8021X &&
1511 				    ni->ni_challenge == NULL)
1512 				      ieee80211_node_authorize(ni);
1513 			} else {
1514 				vap->iv_stats.is_rx_acl++;
1515 				ieee80211_send_error(ni, ni->ni_macaddr,
1516 				    IEEE80211_FC0_SUBTYPE_AUTH, 2|(reason<<16));
1517 				ieee80211_node_leave(ni);
1518 			}
1519 			ieee80211_free_node(ni);
1520 		} else
1521 			error = ENOENT;
1522 		break;
1523 	default:
1524 		error = EINVAL;
1525 		break;
1526 	}
1527 	return error;
1528 }
1529 
1530 struct scanlookup {
1531 	const uint8_t *mac;
1532 	int esslen;
1533 	const uint8_t *essid;
1534 	const struct ieee80211_scan_entry *se;
1535 };
1536 
1537 /*
1538  * Match mac address and any ssid.
1539  */
1540 static void
1541 mlmelookup(void *arg, const struct ieee80211_scan_entry *se)
1542 {
1543 	struct scanlookup *look = arg;
1544 
1545 	if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr))
1546 		return;
1547 	if (look->esslen != 0) {
1548 		if (se->se_ssid[1] != look->esslen)
1549 			return;
1550 		if (memcmp(look->essid, se->se_ssid+2, look->esslen))
1551 			return;
1552 	}
1553 	look->se = se;
1554 }
1555 
1556 static int
1557 setmlme_assoc_sta(struct ieee80211vap *vap,
1558 	const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len,
1559 	const uint8_t ssid[IEEE80211_NWID_LEN])
1560 {
1561 	struct scanlookup lookup;
1562 
1563 	KASSERT(vap->iv_opmode == IEEE80211_M_STA,
1564 	    ("expected opmode STA not %s",
1565 	    ieee80211_opmode_name[vap->iv_opmode]));
1566 
1567 	/* NB: this is racey if roaming is !manual */
1568 	lookup.se = NULL;
1569 	lookup.mac = mac;
1570 	lookup.esslen = ssid_len;
1571 	lookup.essid = ssid;
1572 	ieee80211_scan_iterate(vap, mlmelookup, &lookup);
1573 	if (lookup.se == NULL)
1574 		return ENOENT;
1575 	mlmedebug(vap, mac, IEEE80211_MLME_ASSOC, 0);
1576 	if (!ieee80211_sta_join(vap, lookup.se->se_chan, lookup.se))
1577 		return EIO;		/* XXX unique but could be better */
1578 	return 0;
1579 }
1580 
1581 static int
1582 setmlme_assoc_adhoc(struct ieee80211vap *vap,
1583 	const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len,
1584 	const uint8_t ssid[IEEE80211_NWID_LEN])
1585 {
1586 	struct ieee80211_scan_req *sr;
1587 	int error;
1588 
1589 	KASSERT(vap->iv_opmode == IEEE80211_M_IBSS ||
1590 	    vap->iv_opmode == IEEE80211_M_AHDEMO,
1591 	    ("expected opmode IBSS or AHDEMO not %s",
1592 	    ieee80211_opmode_name[vap->iv_opmode]));
1593 
1594 	if (ssid_len == 0)
1595 		return EINVAL;
1596 
1597 	sr = IEEE80211_MALLOC(sizeof(*sr), M_TEMP,
1598 	     IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
1599 	if (sr == NULL)
1600 		return ENOMEM;
1601 
1602 	/* NB: IEEE80211_IOC_SSID call missing for ap_scan=2. */
1603 	memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN);
1604 	vap->iv_des_ssid[0].len = ssid_len;
1605 	memcpy(vap->iv_des_ssid[0].ssid, ssid, ssid_len);
1606 	vap->iv_des_nssid = 1;
1607 
1608 	sr->sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE;
1609 	sr->sr_duration = IEEE80211_IOC_SCAN_FOREVER;
1610 	memcpy(sr->sr_ssid[0].ssid, ssid, ssid_len);
1611 	sr->sr_ssid[0].len = ssid_len;
1612 	sr->sr_nssid = 1;
1613 
1614 	error = ieee80211_scanreq(vap, sr);
1615 
1616 	IEEE80211_FREE(sr, M_TEMP);
1617 	return error;
1618 }
1619 
1620 static int
1621 ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq)
1622 {
1623 	struct ieee80211req_mlme mlme;
1624 	int error;
1625 
1626 	if (ireq->i_len != sizeof(mlme))
1627 		return EINVAL;
1628 	error = copyin(ireq->i_data, &mlme, sizeof(mlme));
1629 	if (error)
1630 		return error;
1631 	if  (vap->iv_opmode == IEEE80211_M_STA &&
1632 	    mlme.im_op == IEEE80211_MLME_ASSOC)
1633 #ifndef __HAIKU__
1634 		   return setmlme_assoc_sta(vap, mlme.im_macaddr,
1635 				   vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid);
1636 #else
1637 	   /* The wpa_supplicant (rightfully) supplies the SSID with this request.
1638 		  However, with the code above it gets ignored and the desired SSID,
1639 		  as set by IEEE80211_IOC_SSID is used instead. This still works if
1640 		  the wpa_supplicant is the only client in use and IEEE80211_IOC_SSID
1641 		  is never used, as then the mlme.im_macaddr is used as the only
1642 		  identifying element. If we used IEEE80211_IOC_SSID before though,
1643 		  for example because we joined an open network from the net_server
1644 		  directly, there will always be a mismatch between the desired SSID
1645 		  and the one the wpa_supplicant tries to associate with using this
1646 		  MLME request. No association is then possible. As there is no
1647 		  obvious reason why the request supplied SSID shouldn't be used, we
1648 		  simply do so. */
1649 		return setmlme_assoc_sta(vap, mlme.im_macaddr,
1650 			mlme.im_ssid_len, mlme.im_ssid);
1651 #endif
1652 	else if ((vap->iv_opmode == IEEE80211_M_IBSS ||
1653 	    vap->iv_opmode == IEEE80211_M_AHDEMO) &&
1654 	    mlme.im_op == IEEE80211_MLME_ASSOC)
1655 		return setmlme_assoc_adhoc(vap, mlme.im_macaddr,
1656 		    mlme.im_ssid_len, mlme.im_ssid);
1657 	else
1658 		return setmlme_common(vap, mlme.im_op,
1659 		    mlme.im_macaddr, mlme.im_reason);
1660 }
1661 
1662 static int
1663 ieee80211_ioctl_macmac(struct ieee80211vap *vap, struct ieee80211req *ireq)
1664 {
1665 	uint8_t mac[IEEE80211_ADDR_LEN];
1666 	const struct ieee80211_aclator *acl = vap->iv_acl;
1667 	int error;
1668 
1669 	if (ireq->i_len != sizeof(mac))
1670 		return EINVAL;
1671 	error = copyin(ireq->i_data, mac, ireq->i_len);
1672 	if (error)
1673 		return error;
1674 	if (acl == NULL) {
1675 		acl = ieee80211_aclator_get("mac");
1676 		if (acl == NULL || !acl->iac_attach(vap))
1677 			return EINVAL;
1678 		vap->iv_acl = acl;
1679 	}
1680 	if (ireq->i_type == IEEE80211_IOC_ADDMAC)
1681 		acl->iac_add(vap, mac);
1682 	else
1683 		acl->iac_remove(vap, mac);
1684 	return 0;
1685 }
1686 
1687 static int
1688 ieee80211_ioctl_setmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq)
1689 {
1690 	const struct ieee80211_aclator *acl = vap->iv_acl;
1691 
1692 	switch (ireq->i_val) {
1693 	case IEEE80211_MACCMD_POLICY_OPEN:
1694 	case IEEE80211_MACCMD_POLICY_ALLOW:
1695 	case IEEE80211_MACCMD_POLICY_DENY:
1696 	case IEEE80211_MACCMD_POLICY_RADIUS:
1697 		if (acl == NULL) {
1698 			acl = ieee80211_aclator_get("mac");
1699 			if (acl == NULL || !acl->iac_attach(vap))
1700 				return EINVAL;
1701 			vap->iv_acl = acl;
1702 		}
1703 		acl->iac_setpolicy(vap, ireq->i_val);
1704 		break;
1705 	case IEEE80211_MACCMD_FLUSH:
1706 		if (acl != NULL)
1707 			acl->iac_flush(vap);
1708 		/* NB: silently ignore when not in use */
1709 		break;
1710 	case IEEE80211_MACCMD_DETACH:
1711 		if (acl != NULL) {
1712 			vap->iv_acl = NULL;
1713 			acl->iac_detach(vap);
1714 		}
1715 		break;
1716 	default:
1717 		if (acl == NULL)
1718 			return EINVAL;
1719 		else
1720 			return acl->iac_setioctl(vap, ireq);
1721 	}
1722 	return 0;
1723 }
1724 
1725 static int
1726 ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
1727 {
1728 	struct ieee80211com *ic = vap->iv_ic;
1729 	uint8_t *chanlist, *list;
1730 	int i, nchan, maxchan, error;
1731 
1732 	if (ireq->i_len > sizeof(ic->ic_chan_active))
1733 		ireq->i_len = sizeof(ic->ic_chan_active);
1734 	list = IEEE80211_MALLOC(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
1735 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
1736 	if (list == NULL)
1737 		return ENOMEM;
1738 	error = copyin(ireq->i_data, list, ireq->i_len);
1739 	if (error) {
1740 		IEEE80211_FREE(list, M_TEMP);
1741 		return error;
1742 	}
1743 	nchan = 0;
1744 	chanlist = list + ireq->i_len;		/* NB: zero'd already */
1745 	maxchan = ireq->i_len * NBBY;
1746 	for (i = 0; i < ic->ic_nchans; i++) {
1747 		const struct ieee80211_channel *c = &ic->ic_channels[i];
1748 		/*
1749 		 * Calculate the intersection of the user list and the
1750 		 * available channels so users can do things like specify
1751 		 * 1-255 to get all available channels.
1752 		 */
1753 		if (c->ic_ieee < maxchan && isset(list, c->ic_ieee)) {
1754 			setbit(chanlist, c->ic_ieee);
1755 			nchan++;
1756 		}
1757 	}
1758 	if (nchan == 0) {
1759 		IEEE80211_FREE(list, M_TEMP);
1760 		return EINVAL;
1761 	}
1762 	if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&	/* XXX */
1763 	    isclr(chanlist, ic->ic_bsschan->ic_ieee))
1764 		ic->ic_bsschan = IEEE80211_CHAN_ANYC;
1765 	memcpy(ic->ic_chan_active, chanlist, IEEE80211_CHAN_BYTES);
1766 	ieee80211_scan_flush(vap);
1767 	IEEE80211_FREE(list, M_TEMP);
1768 	return ENETRESET;
1769 }
1770 
1771 static int
1772 ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq)
1773 {
1774 	struct ieee80211_node *ni;
1775 	uint8_t macaddr[IEEE80211_ADDR_LEN];
1776 	int error;
1777 
1778 	/*
1779 	 * NB: we could copyin ieee80211req_sta_stats so apps
1780 	 *     could make selective changes but that's overkill;
1781 	 *     just clear all stats for now.
1782 	 */
1783 	if (ireq->i_len < IEEE80211_ADDR_LEN)
1784 		return EINVAL;
1785 	error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
1786 	if (error != 0)
1787 		return error;
1788 	ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr);
1789 	if (ni == NULL)
1790 		return ENOENT;
1791 	/* XXX require ni_vap == vap? */
1792 	memset(&ni->ni_stats, 0, sizeof(ni->ni_stats));
1793 	ieee80211_free_node(ni);
1794 	return 0;
1795 }
1796 
1797 static int
1798 ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq)
1799 {
1800 	struct ieee80211_node *ni;
1801 	struct ieee80211req_sta_txpow txpow;
1802 	int error;
1803 
1804 	if (ireq->i_len != sizeof(txpow))
1805 		return EINVAL;
1806 	error = copyin(ireq->i_data, &txpow, sizeof(txpow));
1807 	if (error != 0)
1808 		return error;
1809 	ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr);
1810 	if (ni == NULL)
1811 		return ENOENT;
1812 	ni->ni_txpower = txpow.it_txpow;
1813 	ieee80211_free_node(ni);
1814 	return error;
1815 }
1816 
1817 static int
1818 ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq)
1819 {
1820 	struct ieee80211com *ic = vap->iv_ic;
1821 	struct ieee80211_wme_state *wme = &ic->ic_wme;
1822 	struct wmeParams *wmep, *chanp;
1823 	int isbss, ac, aggrmode;
1824 
1825 	if ((ic->ic_caps & IEEE80211_C_WME) == 0)
1826 		return EOPNOTSUPP;
1827 
1828 	isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS);
1829 	ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL);
1830 	aggrmode = (wme->wme_flags & WME_F_AGGRMODE);
1831 	if (ac >= WME_NUM_AC)
1832 		ac = WME_AC_BE;
1833 	if (isbss) {
1834 		chanp = &wme->wme_bssChanParams.cap_wmeParams[ac];
1835 		wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac];
1836 	} else {
1837 		chanp = &wme->wme_chanParams.cap_wmeParams[ac];
1838 		wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac];
1839 	}
1840 	switch (ireq->i_type) {
1841 	case IEEE80211_IOC_WME_CWMIN:		/* WME: CWmin */
1842 		wmep->wmep_logcwmin = ireq->i_val;
1843 		if (!isbss || !aggrmode)
1844 			chanp->wmep_logcwmin = ireq->i_val;
1845 		break;
1846 	case IEEE80211_IOC_WME_CWMAX:		/* WME: CWmax */
1847 		wmep->wmep_logcwmax = ireq->i_val;
1848 		if (!isbss || !aggrmode)
1849 			chanp->wmep_logcwmax = ireq->i_val;
1850 		break;
1851 	case IEEE80211_IOC_WME_AIFS:		/* WME: AIFS */
1852 		wmep->wmep_aifsn = ireq->i_val;
1853 		if (!isbss || !aggrmode)
1854 			chanp->wmep_aifsn = ireq->i_val;
1855 		break;
1856 	case IEEE80211_IOC_WME_TXOPLIMIT:	/* WME: txops limit */
1857 		wmep->wmep_txopLimit = ireq->i_val;
1858 		if (!isbss || !aggrmode)
1859 			chanp->wmep_txopLimit = ireq->i_val;
1860 		break;
1861 	case IEEE80211_IOC_WME_ACM:		/* WME: ACM (bss only) */
1862 		wmep->wmep_acm = ireq->i_val;
1863 		if (!aggrmode)
1864 			chanp->wmep_acm = ireq->i_val;
1865 		break;
1866 	case IEEE80211_IOC_WME_ACKPOLICY:	/* WME: ACK policy (!bss only)*/
1867 		wmep->wmep_noackPolicy = chanp->wmep_noackPolicy =
1868 			(ireq->i_val) == 0;
1869 		break;
1870 	}
1871 	ieee80211_wme_updateparams(vap);
1872 	return 0;
1873 }
1874 
1875 static int
1876 find11gchannel(struct ieee80211com *ic, int start, int freq)
1877 {
1878 	const struct ieee80211_channel *c;
1879 	int i;
1880 
1881 	for (i = start+1; i < ic->ic_nchans; i++) {
1882 		c = &ic->ic_channels[i];
1883 		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
1884 			return 1;
1885 	}
1886 	/* NB: should not be needed but in case things are mis-sorted */
1887 	for (i = 0; i < start; i++) {
1888 		c = &ic->ic_channels[i];
1889 		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
1890 			return 1;
1891 	}
1892 	return 0;
1893 }
1894 
1895 static struct ieee80211_channel *
1896 findchannel(struct ieee80211com *ic, int ieee, int mode)
1897 {
1898 	static const u_int chanflags[IEEE80211_MODE_MAX] = {
1899 	    [IEEE80211_MODE_AUTO]	= 0,
1900 	    [IEEE80211_MODE_11A]	= IEEE80211_CHAN_A,
1901 	    [IEEE80211_MODE_11B]	= IEEE80211_CHAN_B,
1902 	    [IEEE80211_MODE_11G]	= IEEE80211_CHAN_G,
1903 	    [IEEE80211_MODE_FH]		= IEEE80211_CHAN_FHSS,
1904 	    [IEEE80211_MODE_TURBO_A]	= IEEE80211_CHAN_108A,
1905 	    [IEEE80211_MODE_TURBO_G]	= IEEE80211_CHAN_108G,
1906 	    [IEEE80211_MODE_STURBO_A]	= IEEE80211_CHAN_STURBO,
1907 	    [IEEE80211_MODE_HALF]	= IEEE80211_CHAN_HALF,
1908 	    [IEEE80211_MODE_QUARTER]	= IEEE80211_CHAN_QUARTER,
1909 	    /* NB: handled specially below */
1910 	    [IEEE80211_MODE_11NA]	= IEEE80211_CHAN_A,
1911 	    [IEEE80211_MODE_11NG]	= IEEE80211_CHAN_G,
1912 	    [IEEE80211_MODE_VHT_5GHZ]	= IEEE80211_CHAN_A,
1913 	    [IEEE80211_MODE_VHT_2GHZ]	= IEEE80211_CHAN_G,
1914 	};
1915 	u_int modeflags;
1916 	int i;
1917 
1918 	modeflags = chanflags[mode];
1919 	for (i = 0; i < ic->ic_nchans; i++) {
1920 		struct ieee80211_channel *c = &ic->ic_channels[i];
1921 
1922 		if (c->ic_ieee != ieee)
1923 			continue;
1924 		if (mode == IEEE80211_MODE_AUTO) {
1925 			/* ignore turbo channels for autoselect */
1926 			if (IEEE80211_IS_CHAN_TURBO(c))
1927 				continue;
1928 			/*
1929 			 * XXX special-case 11b/g channels so we
1930 			 *     always select the g channel if both
1931 			 *     are present.
1932 			 * XXX prefer HT to non-HT?
1933 			 */
1934 			if (!IEEE80211_IS_CHAN_B(c) ||
1935 			    !find11gchannel(ic, i, c->ic_freq))
1936 				return c;
1937 		} else {
1938 			/* must check VHT specifically */
1939 			if ((mode == IEEE80211_MODE_VHT_5GHZ ||
1940 			    mode == IEEE80211_MODE_VHT_2GHZ) &&
1941 			    !IEEE80211_IS_CHAN_VHT(c))
1942 				continue;
1943 
1944 			/*
1945 			 * Must check HT specially - only match on HT,
1946 			 * not HT+VHT channels
1947 			 */
1948 			if ((mode == IEEE80211_MODE_11NA ||
1949 			    mode == IEEE80211_MODE_11NG) &&
1950 			    !IEEE80211_IS_CHAN_HT(c))
1951 				continue;
1952 
1953 			if ((mode == IEEE80211_MODE_11NA ||
1954 			    mode == IEEE80211_MODE_11NG) &&
1955 			    IEEE80211_IS_CHAN_VHT(c))
1956 				continue;
1957 
1958 			/* Check that the modeflags above match */
1959 			if ((c->ic_flags & modeflags) == modeflags)
1960 				return c;
1961 		}
1962 	}
1963 	return NULL;
1964 }
1965 
1966 /*
1967  * Check the specified against any desired mode (aka netband).
1968  * This is only used (presently) when operating in hostap mode
1969  * to enforce consistency.
1970  */
1971 static int
1972 check_mode_consistency(const struct ieee80211_channel *c, int mode)
1973 {
1974 	KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel"));
1975 
1976 	switch (mode) {
1977 	case IEEE80211_MODE_11B:
1978 		return (IEEE80211_IS_CHAN_B(c));
1979 	case IEEE80211_MODE_11G:
1980 		return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c));
1981 	case IEEE80211_MODE_11A:
1982 		return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c));
1983 	case IEEE80211_MODE_STURBO_A:
1984 		return (IEEE80211_IS_CHAN_STURBO(c));
1985 	case IEEE80211_MODE_11NA:
1986 		return (IEEE80211_IS_CHAN_HTA(c));
1987 	case IEEE80211_MODE_11NG:
1988 		return (IEEE80211_IS_CHAN_HTG(c));
1989 	}
1990 	return 1;
1991 
1992 }
1993 
1994 /*
1995  * Common code to set the current channel.  If the device
1996  * is up and running this may result in an immediate channel
1997  * change or a kick of the state machine.
1998  */
1999 static int
2000 setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c)
2001 {
2002 	struct ieee80211com *ic = vap->iv_ic;
2003 	int error;
2004 
2005 	if (c != IEEE80211_CHAN_ANYC) {
2006 		if (IEEE80211_IS_CHAN_RADAR(c))
2007 			return EBUSY;	/* XXX better code? */
2008 		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
2009 			if (IEEE80211_IS_CHAN_NOHOSTAP(c))
2010 				return EINVAL;
2011 			if (!check_mode_consistency(c, vap->iv_des_mode))
2012 				return EINVAL;
2013 		} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
2014 			if (IEEE80211_IS_CHAN_NOADHOC(c))
2015 				return EINVAL;
2016 		}
2017 		if ((vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP) &&
2018 		    vap->iv_bss->ni_chan == c)
2019 			return 0;	/* NB: nothing to do */
2020 	}
2021 	vap->iv_des_chan = c;
2022 
2023 	error = 0;
2024 	if (vap->iv_opmode == IEEE80211_M_MONITOR &&
2025 	    vap->iv_des_chan != IEEE80211_CHAN_ANYC) {
2026 		/*
2027 		 * Monitor mode can switch directly.
2028 		 */
2029 		if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) {
2030 			/* XXX need state machine for other vap's to follow */
2031 			ieee80211_setcurchan(ic, vap->iv_des_chan);
2032 			vap->iv_bss->ni_chan = ic->ic_curchan;
2033 		} else {
2034 			ic->ic_curchan = vap->iv_des_chan;
2035 			ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
2036 		}
2037 	} else {
2038 		/*
2039 		 * Need to go through the state machine in case we
2040 		 * need to reassociate or the like.  The state machine
2041 		 * will pickup the desired channel and avoid scanning.
2042 		 */
2043 		if (IS_UP_AUTO(vap))
2044 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
2045 		else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) {
2046 			/*
2047 			 * When not up+running and a real channel has
2048 			 * been specified fix the current channel so
2049 			 * there is immediate feedback; e.g. via ifconfig.
2050 			 */
2051 			ic->ic_curchan = vap->iv_des_chan;
2052 			ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
2053 		}
2054 	}
2055 	return error;
2056 }
2057 
2058 /*
2059  * Old api for setting the current channel; this is
2060  * deprecated because channel numbers are ambiguous.
2061  */
2062 static int
2063 ieee80211_ioctl_setchannel(struct ieee80211vap *vap,
2064 	const struct ieee80211req *ireq)
2065 {
2066 	struct ieee80211com *ic = vap->iv_ic;
2067 	struct ieee80211_channel *c;
2068 
2069 	/* XXX 0xffff overflows 16-bit signed */
2070 	if (ireq->i_val == 0 ||
2071 	    ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) {
2072 		c = IEEE80211_CHAN_ANYC;
2073 	} else {
2074 		struct ieee80211_channel *c2;
2075 
2076 		c = findchannel(ic, ireq->i_val, vap->iv_des_mode);
2077 		if (c == NULL) {
2078 			c = findchannel(ic, ireq->i_val,
2079 				IEEE80211_MODE_AUTO);
2080 			if (c == NULL)
2081 				return EINVAL;
2082 		}
2083 
2084 		/*
2085 		 * Fine tune channel selection based on desired mode:
2086 		 *   if 11b is requested, find the 11b version of any
2087 		 *      11g channel returned,
2088 		 *   if static turbo, find the turbo version of any
2089 		 *	11a channel return,
2090 		 *   if 11na is requested, find the ht version of any
2091 		 *      11a channel returned,
2092 		 *   if 11ng is requested, find the ht version of any
2093 		 *      11g channel returned,
2094 		 *   if 11ac is requested, find the 11ac version
2095 		 *      of any 11a/11na channel returned,
2096 		 *   (TBD) 11acg (2GHz VHT)
2097 		 *   otherwise we should be ok with what we've got.
2098 		 */
2099 		switch (vap->iv_des_mode) {
2100 		case IEEE80211_MODE_11B:
2101 			if (IEEE80211_IS_CHAN_ANYG(c)) {
2102 				c2 = findchannel(ic, ireq->i_val,
2103 					IEEE80211_MODE_11B);
2104 				/* NB: should not happen, =>'s 11g w/o 11b */
2105 				if (c2 != NULL)
2106 					c = c2;
2107 			}
2108 			break;
2109 		case IEEE80211_MODE_TURBO_A:
2110 			if (IEEE80211_IS_CHAN_A(c)) {
2111 				c2 = findchannel(ic, ireq->i_val,
2112 					IEEE80211_MODE_TURBO_A);
2113 				if (c2 != NULL)
2114 					c = c2;
2115 			}
2116 			break;
2117 		case IEEE80211_MODE_11NA:
2118 			if (IEEE80211_IS_CHAN_A(c)) {
2119 				c2 = findchannel(ic, ireq->i_val,
2120 					IEEE80211_MODE_11NA);
2121 				if (c2 != NULL)
2122 					c = c2;
2123 			}
2124 			break;
2125 		case IEEE80211_MODE_11NG:
2126 			if (IEEE80211_IS_CHAN_ANYG(c)) {
2127 				c2 = findchannel(ic, ireq->i_val,
2128 					IEEE80211_MODE_11NG);
2129 				if (c2 != NULL)
2130 					c = c2;
2131 			}
2132 			break;
2133 		case IEEE80211_MODE_VHT_2GHZ:
2134 			printf("%s: TBD\n", __func__);
2135 			break;
2136 		case IEEE80211_MODE_VHT_5GHZ:
2137 			if (IEEE80211_IS_CHAN_A(c)) {
2138 				c2 = findchannel(ic, ireq->i_val,
2139 					IEEE80211_MODE_VHT_5GHZ);
2140 				if (c2 != NULL)
2141 					c = c2;
2142 			}
2143 			break;
2144 		default:		/* NB: no static turboG */
2145 			break;
2146 		}
2147 	}
2148 	return setcurchan(vap, c);
2149 }
2150 
2151 /*
2152  * New/current api for setting the current channel; a complete
2153  * channel description is provide so there is no ambiguity in
2154  * identifying the channel.
2155  */
2156 static int
2157 ieee80211_ioctl_setcurchan(struct ieee80211vap *vap,
2158 	const struct ieee80211req *ireq)
2159 {
2160 	struct ieee80211com *ic = vap->iv_ic;
2161 	struct ieee80211_channel chan, *c;
2162 	int error;
2163 
2164 	if (ireq->i_len != sizeof(chan))
2165 		return EINVAL;
2166 	error = copyin(ireq->i_data, &chan, sizeof(chan));
2167 	if (error != 0)
2168 		return error;
2169 
2170 	/* XXX 0xffff overflows 16-bit signed */
2171 	if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) {
2172 		c = IEEE80211_CHAN_ANYC;
2173 	} else {
2174 		c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags);
2175 		if (c == NULL)
2176 			return EINVAL;
2177 	}
2178 	return setcurchan(vap, c);
2179 }
2180 
2181 static int
2182 ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
2183 	const struct ieee80211req *ireq)
2184 {
2185 	struct ieee80211_regdomain_req *reg;
2186 	int nchans, error;
2187 
2188 	nchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_regdomain_req)) /
2189 	    sizeof(struct ieee80211_channel));
2190 	if (!(1 <= nchans && nchans <= IEEE80211_CHAN_MAX)) {
2191 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
2192 		    "%s: bad # chans, i_len %d nchans %d\n", __func__,
2193 		    ireq->i_len, nchans);
2194 		return EINVAL;
2195 	}
2196 	reg = (struct ieee80211_regdomain_req *)
2197 	    IEEE80211_MALLOC(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP,
2198 	      IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
2199 	if (reg == NULL) {
2200 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
2201 		    "%s: no memory, nchans %d\n", __func__, nchans);
2202 		return ENOMEM;
2203 	}
2204 	error = copyin(ireq->i_data, reg, IEEE80211_REGDOMAIN_SIZE(nchans));
2205 	if (error == 0) {
2206 		/* NB: validate inline channel count against storage size */
2207 		if (reg->chaninfo.ic_nchans != nchans) {
2208 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
2209 			    "%s: chan cnt mismatch, %d != %d\n", __func__,
2210 				reg->chaninfo.ic_nchans, nchans);
2211 			error = EINVAL;
2212 		} else
2213 			error = ieee80211_setregdomain(vap, reg);
2214 	}
2215 	IEEE80211_FREE(reg, M_TEMP);
2216 
2217 	return (error == 0 ? ENETRESET : error);
2218 }
2219 
2220 static int
2221 checkrate(const struct ieee80211_rateset *rs, int rate)
2222 {
2223 	int i;
2224 
2225 	if (rate == IEEE80211_FIXED_RATE_NONE)
2226 		return 1;
2227 	for (i = 0; i < rs->rs_nrates; i++)
2228 		if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate)
2229 			return 1;
2230 	return 0;
2231 }
2232 
2233 static int
2234 checkmcs(const struct ieee80211_htrateset *rs, int mcs)
2235 {
2236 	int rate_val = IEEE80211_RV(mcs);
2237 	int i;
2238 
2239 	if (mcs == IEEE80211_FIXED_RATE_NONE)
2240 		return 1;
2241 	if ((mcs & IEEE80211_RATE_MCS) == 0)	/* MCS always have 0x80 set */
2242 		return 0;
2243 	for (i = 0; i < rs->rs_nrates; i++)
2244 		if (IEEE80211_RV(rs->rs_rates[i]) == rate_val)
2245 			return 1;
2246 	return 0;
2247 }
2248 
2249 static int
2250 ieee80211_ioctl_setroam(struct ieee80211vap *vap,
2251         const struct ieee80211req *ireq)
2252 {
2253 	struct ieee80211com *ic = vap->iv_ic;
2254 	struct ieee80211_roamparams_req *parms;
2255 	struct ieee80211_roamparam *src, *dst;
2256 	const struct ieee80211_htrateset *rs_ht;
2257 	const struct ieee80211_rateset *rs;
2258 	int changed, error, mode, is11n, nmodes;
2259 
2260 	if (ireq->i_len != sizeof(vap->iv_roamparms))
2261 		return EINVAL;
2262 
2263 	parms = IEEE80211_MALLOC(sizeof(*parms), M_TEMP,
2264 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
2265 	if (parms == NULL)
2266 		return ENOMEM;
2267 
2268 	error = copyin(ireq->i_data, parms, ireq->i_len);
2269 	if (error != 0)
2270 		goto fail;
2271 
2272 	changed = 0;
2273 	nmodes = IEEE80211_MODE_MAX;
2274 
2275 	/* validate parameters and check if anything changed */
2276 	for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
2277 		if (isclr(ic->ic_modecaps, mode))
2278 			continue;
2279 		src = &parms->params[mode];
2280 		dst = &vap->iv_roamparms[mode];
2281 		rs = &ic->ic_sup_rates[mode];	/* NB: 11n maps to legacy */
2282 		rs_ht = &ic->ic_sup_htrates;
2283 		is11n = (mode == IEEE80211_MODE_11NA ||
2284 			 mode == IEEE80211_MODE_11NG);
2285 		/* XXX TODO: 11ac */
2286 		if (src->rate != dst->rate) {
2287 			if (!checkrate(rs, src->rate) &&
2288 			    (!is11n || !checkmcs(rs_ht, src->rate))) {
2289 				error = EINVAL;
2290 				goto fail;
2291 			}
2292 			changed++;
2293 		}
2294 		if (src->rssi != dst->rssi)
2295 			changed++;
2296 	}
2297 	if (changed) {
2298 		/*
2299 		 * Copy new parameters in place and notify the
2300 		 * driver so it can push state to the device.
2301 		 */
2302 		/* XXX locking? */
2303 		for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
2304 			if (isset(ic->ic_modecaps, mode))
2305 				vap->iv_roamparms[mode] = parms->params[mode];
2306 		}
2307 
2308 		if (vap->iv_roaming == IEEE80211_ROAMING_DEVICE)
2309 			error = ERESTART;
2310 	}
2311 
2312 fail:	IEEE80211_FREE(parms, M_TEMP);
2313 	return error;
2314 }
2315 
2316 static int
2317 ieee80211_ioctl_settxparams(struct ieee80211vap *vap,
2318 	const struct ieee80211req *ireq)
2319 {
2320 	struct ieee80211com *ic = vap->iv_ic;
2321 	struct ieee80211_txparams_req parms;	/* XXX stack use? */
2322 	struct ieee80211_txparam *src, *dst;
2323 	const struct ieee80211_htrateset *rs_ht;
2324 	const struct ieee80211_rateset *rs;
2325 	int error, mode, changed, is11n, nmodes;
2326 
2327 	/* NB: accept short requests for backwards compat */
2328 	if (ireq->i_len > sizeof(parms))
2329 		return EINVAL;
2330 	error = copyin(ireq->i_data, &parms, ireq->i_len);
2331 	if (error != 0)
2332 		return error;
2333 	nmodes = ireq->i_len / sizeof(struct ieee80211_txparam);
2334 	changed = 0;
2335 	/* validate parameters and check if anything changed */
2336 	for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
2337 		if (isclr(ic->ic_modecaps, mode))
2338 			continue;
2339 		src = &parms.params[mode];
2340 		dst = &vap->iv_txparms[mode];
2341 		rs = &ic->ic_sup_rates[mode];	/* NB: 11n maps to legacy */
2342 		rs_ht = &ic->ic_sup_htrates;
2343 		is11n = (mode == IEEE80211_MODE_11NA ||
2344 			 mode == IEEE80211_MODE_11NG);
2345 		if (src->ucastrate != dst->ucastrate) {
2346 			if (!checkrate(rs, src->ucastrate) &&
2347 			    (!is11n || !checkmcs(rs_ht, src->ucastrate)))
2348 				return EINVAL;
2349 			changed++;
2350 		}
2351 		if (src->mcastrate != dst->mcastrate) {
2352 			if (!checkrate(rs, src->mcastrate) &&
2353 			    (!is11n || !checkmcs(rs_ht, src->mcastrate)))
2354 				return EINVAL;
2355 			changed++;
2356 		}
2357 		if (src->mgmtrate != dst->mgmtrate) {
2358 			if (!checkrate(rs, src->mgmtrate) &&
2359 			    (!is11n || !checkmcs(rs_ht, src->mgmtrate)))
2360 				return EINVAL;
2361 			changed++;
2362 		}
2363 		if (src->maxretry != dst->maxretry)	/* NB: no bounds */
2364 			changed++;
2365 	}
2366 	if (changed) {
2367 		/*
2368 		 * Copy new parameters in place and notify the
2369 		 * driver so it can push state to the device.
2370 		 */
2371 		for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
2372 			if (isset(ic->ic_modecaps, mode))
2373 				vap->iv_txparms[mode] = parms.params[mode];
2374 		}
2375 		/* XXX could be more intelligent,
2376 		   e.g. don't reset if setting not being used */
2377 		return ENETRESET;
2378 	}
2379 	return 0;
2380 }
2381 
2382 /*
2383  * Application Information Element support.
2384  */
2385 static int
2386 setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq)
2387 {
2388 	struct ieee80211_appie *app = *aie;
2389 	struct ieee80211_appie *napp;
2390 	int error;
2391 
2392 	if (ireq->i_len == 0) {		/* delete any existing ie */
2393 		if (app != NULL) {
2394 			*aie = NULL;	/* XXX racey */
2395 			IEEE80211_FREE(app, M_80211_NODE_IE);
2396 		}
2397 		return 0;
2398 	}
2399 	if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE))
2400 		return EINVAL;
2401 	/*
2402 	 * Allocate a new appie structure and copy in the user data.
2403 	 * When done swap in the new structure.  Note that we do not
2404 	 * guard against users holding a ref to the old structure;
2405 	 * this must be handled outside this code.
2406 	 *
2407 	 * XXX bad bad bad
2408 	 */
2409 	napp = (struct ieee80211_appie *) IEEE80211_MALLOC(
2410 	    sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE,
2411 	    IEEE80211_M_NOWAIT);
2412 	if (napp == NULL)
2413 		return ENOMEM;
2414 	/* XXX holding ic lock */
2415 	error = copyin(ireq->i_data, napp->ie_data, ireq->i_len);
2416 	if (error) {
2417 		IEEE80211_FREE(napp, M_80211_NODE_IE);
2418 		return error;
2419 	}
2420 	napp->ie_len = ireq->i_len;
2421 	*aie = napp;
2422 	if (app != NULL)
2423 		IEEE80211_FREE(app, M_80211_NODE_IE);
2424 	return 0;
2425 }
2426 
2427 static void
2428 setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space)
2429 {
2430 	/* validate data is present as best we can */
2431 	if (space == 0 || 2+ie[1] > space)
2432 		return;
2433 	if (ie[0] == IEEE80211_ELEMID_VENDOR)
2434 		vap->iv_wpa_ie = ie;
2435 	else if (ie[0] == IEEE80211_ELEMID_RSN)
2436 		vap->iv_rsn_ie = ie;
2437 }
2438 
2439 static int
2440 ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap,
2441 	const struct ieee80211req *ireq, int fc0)
2442 {
2443 	int error;
2444 
2445 	IEEE80211_LOCK_ASSERT(vap->iv_ic);
2446 
2447 	switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) {
2448 	case IEEE80211_FC0_SUBTYPE_BEACON:
2449 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
2450 		    vap->iv_opmode != IEEE80211_M_IBSS) {
2451 			error = EINVAL;
2452 			break;
2453 		}
2454 		error = setappie(&vap->iv_appie_beacon, ireq);
2455 		if (error == 0)
2456 			ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE);
2457 		break;
2458 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2459 		error = setappie(&vap->iv_appie_proberesp, ireq);
2460 		break;
2461 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2462 		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
2463 			error = setappie(&vap->iv_appie_assocresp, ireq);
2464 		else
2465 			error = EINVAL;
2466 		break;
2467 	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2468 		error = setappie(&vap->iv_appie_probereq, ireq);
2469 		break;
2470 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2471 		if (vap->iv_opmode == IEEE80211_M_STA)
2472 			error = setappie(&vap->iv_appie_assocreq, ireq);
2473 		else
2474 			error = EINVAL;
2475 		break;
2476 	case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK):
2477 		error = setappie(&vap->iv_appie_wpa, ireq);
2478 		if (error == 0) {
2479 			/*
2480 			 * Must split single blob of data into separate
2481 			 * WPA and RSN ie's because they go in different
2482 			 * locations in the mgt frames.
2483 			 * XXX use IEEE80211_IOC_WPA2 so user code does split
2484 			 */
2485 			vap->iv_wpa_ie = NULL;
2486 			vap->iv_rsn_ie = NULL;
2487 			if (vap->iv_appie_wpa != NULL) {
2488 				struct ieee80211_appie *appie =
2489 				    vap->iv_appie_wpa;
2490 				uint8_t *data = appie->ie_data;
2491 
2492 				/* XXX ie length validate is painful, cheat */
2493 				setwparsnie(vap, data, appie->ie_len);
2494 				setwparsnie(vap, data + 2 + data[1],
2495 				    appie->ie_len - (2 + data[1]));
2496 			}
2497 			if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
2498 			    vap->iv_opmode == IEEE80211_M_IBSS) {
2499 				/*
2500 				 * Must rebuild beacon frame as the update
2501 				 * mechanism doesn't handle WPA/RSN ie's.
2502 				 * Could extend it but it doesn't normally
2503 				 * change; this is just to deal with hostapd
2504 				 * plumbing the ie after the interface is up.
2505 				 */
2506 				error = ENETRESET;
2507 			}
2508 		}
2509 		break;
2510 	default:
2511 		error = EINVAL;
2512 		break;
2513 	}
2514 	return error;
2515 }
2516 
2517 static int
2518 ieee80211_ioctl_setappie(struct ieee80211vap *vap,
2519 	const struct ieee80211req *ireq)
2520 {
2521 	struct ieee80211com *ic = vap->iv_ic;
2522 	int error;
2523 	uint8_t fc0;
2524 
2525 	fc0 = ireq->i_val & 0xff;
2526 	if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
2527 		return EINVAL;
2528 	/* NB: could check iv_opmode and reject but hardly worth the effort */
2529 	IEEE80211_LOCK(ic);
2530 	error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0);
2531 	IEEE80211_UNLOCK(ic);
2532 	return error;
2533 }
2534 
2535 static int
2536 ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq)
2537 {
2538 	struct ieee80211com *ic = vap->iv_ic;
2539 	struct ieee80211_chanswitch_req csr;
2540 	struct ieee80211_channel *c;
2541 	int error;
2542 
2543 	if (ireq->i_len != sizeof(csr))
2544 		return EINVAL;
2545 	error = copyin(ireq->i_data, &csr, sizeof(csr));
2546 	if (error != 0)
2547 		return error;
2548 	/* XXX adhoc mode not supported */
2549 	if (vap->iv_opmode != IEEE80211_M_HOSTAP ||
2550 	    (vap->iv_flags & IEEE80211_F_DOTH) == 0)
2551 		return EOPNOTSUPP;
2552 	c = ieee80211_find_channel(ic,
2553 	    csr.csa_chan.ic_freq, csr.csa_chan.ic_flags);
2554 	if (c == NULL)
2555 		return ENOENT;
2556 	IEEE80211_LOCK(ic);
2557 	if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0)
2558 		ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count);
2559 	else if (csr.csa_count == 0)
2560 		ieee80211_csa_cancelswitch(ic);
2561 	else
2562 		error = EBUSY;
2563 	IEEE80211_UNLOCK(ic);
2564 	return error;
2565 }
2566 
2567 static int
2568 ieee80211_scanreq(struct ieee80211vap *vap, struct ieee80211_scan_req *sr)
2569 {
2570 #define	IEEE80211_IOC_SCAN_FLAGS \
2571 	(IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \
2572 	 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \
2573 	 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \
2574 	 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \
2575 	 IEEE80211_IOC_SCAN_CHECK)
2576 	struct ieee80211com *ic = vap->iv_ic;
2577 	int error, i;
2578 
2579 	/* convert duration */
2580 	if (sr->sr_duration == IEEE80211_IOC_SCAN_FOREVER)
2581 		sr->sr_duration = IEEE80211_SCAN_FOREVER;
2582 	else {
2583 		if (sr->sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN ||
2584 		    sr->sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX)
2585 			return EINVAL;
2586 		sr->sr_duration = msecs_to_ticks(sr->sr_duration);
2587 	}
2588 	/* convert min/max channel dwell */
2589 	if (sr->sr_mindwell != 0)
2590 		sr->sr_mindwell = msecs_to_ticks(sr->sr_mindwell);
2591 	if (sr->sr_maxdwell != 0)
2592 		sr->sr_maxdwell = msecs_to_ticks(sr->sr_maxdwell);
2593 	/* NB: silently reduce ssid count to what is supported */
2594 	if (sr->sr_nssid > IEEE80211_SCAN_MAX_SSID)
2595 		sr->sr_nssid = IEEE80211_SCAN_MAX_SSID;
2596 	for (i = 0; i < sr->sr_nssid; i++)
2597 		if (sr->sr_ssid[i].len > IEEE80211_NWID_LEN)
2598 			return EINVAL;
2599 	/* cleanse flags just in case, could reject if invalid flags */
2600 	sr->sr_flags &= IEEE80211_IOC_SCAN_FLAGS;
2601 	/*
2602 	 * Add an implicit NOPICK if the vap is not marked UP.  This
2603 	 * allows applications to scan without joining a bss (or picking
2604 	 * a channel and setting up a bss) and without forcing manual
2605 	 * roaming mode--you just need to mark the parent device UP.
2606 	 */
2607 	if ((vap->iv_ifp->if_flags & IFF_UP) == 0)
2608 		sr->sr_flags |= IEEE80211_IOC_SCAN_NOPICK;
2609 
2610 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
2611 	    "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n",
2612 	    __func__, sr->sr_flags,
2613 	    (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "",
2614 	    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, sr->sr_nssid);
2615 	/*
2616 	 * If we are in INIT state then the driver has never had a chance
2617 	 * to setup hardware state to do a scan; we must use the state
2618 	 * machine to get us up to the SCAN state but once we reach SCAN
2619 	 * state we then want to use the supplied params.  Stash the
2620 	 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the
2621 	 * state machines will recognize this and use the stashed params
2622 	 * to issue the scan request.
2623 	 *
2624 	 * Otherwise just invoke the scan machinery directly.
2625 	 */
2626 	IEEE80211_LOCK(ic);
2627 	if (ic->ic_nrunning == 0) {
2628 		IEEE80211_UNLOCK(ic);
2629 		return ENXIO;
2630 	}
2631 
2632 	if (vap->iv_state == IEEE80211_S_INIT) {
2633 		/* NB: clobbers previous settings */
2634 		vap->iv_scanreq_flags = sr->sr_flags;
2635 		vap->iv_scanreq_duration = sr->sr_duration;
2636 		vap->iv_scanreq_nssid = sr->sr_nssid;
2637 		for (i = 0; i < sr->sr_nssid; i++) {
2638 			vap->iv_scanreq_ssid[i].len = sr->sr_ssid[i].len;
2639 			memcpy(vap->iv_scanreq_ssid[i].ssid,
2640 			    sr->sr_ssid[i].ssid, sr->sr_ssid[i].len);
2641 		}
2642 		vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ;
2643 		IEEE80211_UNLOCK(ic);
2644 		ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
2645 	} else {
2646 		vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
2647 		IEEE80211_UNLOCK(ic);
2648 		if (sr->sr_flags & IEEE80211_IOC_SCAN_CHECK) {
2649 			error = ieee80211_check_scan(vap, sr->sr_flags,
2650 			    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
2651 			    sr->sr_nssid,
2652 			    /* NB: cheat, we assume structures are compatible */
2653 			    (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
2654 		} else {
2655 			error = ieee80211_start_scan(vap, sr->sr_flags,
2656 			    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
2657 			    sr->sr_nssid,
2658 			    /* NB: cheat, we assume structures are compatible */
2659 			    (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
2660 		}
2661 		if (error == 0)
2662 			return EINPROGRESS;
2663 	}
2664 	return 0;
2665 #undef IEEE80211_IOC_SCAN_FLAGS
2666 }
2667 
2668 static int
2669 ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
2670 {
2671 	struct ieee80211_scan_req *sr;
2672 	int error;
2673 
2674 	if (ireq->i_len != sizeof(*sr))
2675 		return EINVAL;
2676 	sr = IEEE80211_MALLOC(sizeof(*sr), M_TEMP,
2677 	     IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
2678 	if (sr == NULL)
2679 		return ENOMEM;
2680 	error = copyin(ireq->i_data, sr, sizeof(*sr));
2681 	if (error != 0)
2682 		goto bad;
2683 	error = ieee80211_scanreq(vap, sr);
2684 bad:
2685 	IEEE80211_FREE(sr, M_TEMP);
2686 	return error;
2687 }
2688 
2689 static int
2690 ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq)
2691 {
2692 	struct ieee80211_node *ni;
2693 	struct ieee80211req_sta_vlan vlan;
2694 	int error;
2695 
2696 	if (ireq->i_len != sizeof(vlan))
2697 		return EINVAL;
2698 	error = copyin(ireq->i_data, &vlan, sizeof(vlan));
2699 	if (error != 0)
2700 		return error;
2701 	if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) {
2702 		ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap,
2703 		    vlan.sv_macaddr);
2704 		if (ni == NULL)
2705 			return ENOENT;
2706 	} else
2707 		ni = ieee80211_ref_node(vap->iv_bss);
2708 	ni->ni_vlan = vlan.sv_vlan;
2709 	ieee80211_free_node(ni);
2710 	return error;
2711 }
2712 
2713 static int
2714 isvap11g(const struct ieee80211vap *vap)
2715 {
2716 	const struct ieee80211_node *bss = vap->iv_bss;
2717 	return bss->ni_chan != IEEE80211_CHAN_ANYC &&
2718 	    IEEE80211_IS_CHAN_ANYG(bss->ni_chan);
2719 }
2720 
2721 static int
2722 isvapht(const struct ieee80211vap *vap)
2723 {
2724 	const struct ieee80211_node *bss = vap->iv_bss;
2725 	return bss->ni_chan != IEEE80211_CHAN_ANYC &&
2726 	    IEEE80211_IS_CHAN_HT(bss->ni_chan);
2727 }
2728 
2729 /*
2730  * Dummy ioctl set handler so the linker set is defined.
2731  */
2732 static int
2733 dummy_ioctl_set(struct ieee80211vap *vap, struct ieee80211req *ireq)
2734 {
2735 	return ENOSYS;
2736 }
2737 IEEE80211_IOCTL_SET(dummy, dummy_ioctl_set);
2738 
2739 static int
2740 ieee80211_ioctl_setdefault(struct ieee80211vap *vap, struct ieee80211req *ireq)
2741 {
2742 	ieee80211_ioctl_setfunc * const *set;
2743 	int error;
2744 
2745 	SET_FOREACH(set, ieee80211_ioctl_setset) {
2746 		error = (*set)(vap, ireq);
2747 		if (error != ENOSYS)
2748 			return error;
2749 	}
2750 	return EINVAL;
2751 }
2752 
2753 static int
2754 ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq)
2755 {
2756 	struct ieee80211com *ic = vap->iv_ic;
2757 	int error;
2758 	const struct ieee80211_authenticator *auth;
2759 	uint8_t tmpkey[IEEE80211_KEYBUF_SIZE];
2760 	char tmpssid[IEEE80211_NWID_LEN];
2761 	uint8_t tmpbssid[IEEE80211_ADDR_LEN];
2762 	struct ieee80211_key *k;
2763 	u_int kid;
2764 	uint32_t flags;
2765 
2766 	error = 0;
2767 	switch (ireq->i_type) {
2768 	case IEEE80211_IOC_SSID:
2769 		if (ireq->i_val != 0 ||
2770 		    ireq->i_len > IEEE80211_NWID_LEN)
2771 			return EINVAL;
2772 		error = copyin(ireq->i_data, tmpssid, ireq->i_len);
2773 		if (error)
2774 			break;
2775 		memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN);
2776 		vap->iv_des_ssid[0].len = ireq->i_len;
2777 		memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len);
2778 		vap->iv_des_nssid = (ireq->i_len > 0);
2779 		error = ENETRESET;
2780 		break;
2781 	case IEEE80211_IOC_WEP:
2782 		switch (ireq->i_val) {
2783 		case IEEE80211_WEP_OFF:
2784 			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
2785 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2786 			break;
2787 		case IEEE80211_WEP_ON:
2788 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2789 			vap->iv_flags |= IEEE80211_F_DROPUNENC;
2790 			break;
2791 		case IEEE80211_WEP_MIXED:
2792 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2793 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2794 			break;
2795 		}
2796 		error = ENETRESET;
2797 		break;
2798 	case IEEE80211_IOC_WEPKEY:
2799 		kid = (u_int) ireq->i_val;
2800 		if (kid >= IEEE80211_WEP_NKID)
2801 			return EINVAL;
2802 		k = &vap->iv_nw_keys[kid];
2803 		if (ireq->i_len == 0) {
2804 			/* zero-len =>'s delete any existing key */
2805 			(void) ieee80211_crypto_delkey(vap, k);
2806 			break;
2807 		}
2808 		if (ireq->i_len > sizeof(tmpkey))
2809 			return EINVAL;
2810 		memset(tmpkey, 0, sizeof(tmpkey));
2811 		error = copyin(ireq->i_data, tmpkey, ireq->i_len);
2812 		if (error)
2813 			break;
2814 		ieee80211_key_update_begin(vap);
2815 		k->wk_keyix = kid;	/* NB: force fixed key id */
2816 		if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP,
2817 		    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) {
2818 			k->wk_keylen = ireq->i_len;
2819 			memcpy(k->wk_key, tmpkey, sizeof(tmpkey));
2820 			IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr);
2821 			if  (!ieee80211_crypto_setkey(vap, k))
2822 				error = EINVAL;
2823 		} else
2824 			error = EINVAL;
2825 		ieee80211_key_update_end(vap);
2826 		break;
2827 	case IEEE80211_IOC_WEPTXKEY:
2828 		kid = (u_int) ireq->i_val;
2829 		if (kid >= IEEE80211_WEP_NKID &&
2830 		    (uint16_t) kid != IEEE80211_KEYIX_NONE)
2831 			return EINVAL;
2832 		/*
2833 		 * Firmware devices may need to be told about an explicit
2834 		 * key index here, versus just inferring it from the
2835 		 * key set / change.  Since we may also need to pause
2836 		 * things like transmit before the key is updated,
2837 		 * give the driver a chance to flush things by tying
2838 		 * into key update begin/end.
2839 		 */
2840 		ieee80211_key_update_begin(vap);
2841 		ieee80211_crypto_set_deftxkey(vap, kid);
2842 		ieee80211_key_update_end(vap);
2843 		break;
2844 	case IEEE80211_IOC_AUTHMODE:
2845 		switch (ireq->i_val) {
2846 		case IEEE80211_AUTH_WPA:
2847 		case IEEE80211_AUTH_8021X:	/* 802.1x */
2848 		case IEEE80211_AUTH_OPEN:	/* open */
2849 		case IEEE80211_AUTH_SHARED:	/* shared-key */
2850 		case IEEE80211_AUTH_AUTO:	/* auto */
2851 			auth = ieee80211_authenticator_get(ireq->i_val);
2852 			if (auth == NULL)
2853 				return EINVAL;
2854 			break;
2855 		default:
2856 			return EINVAL;
2857 		}
2858 		switch (ireq->i_val) {
2859 		case IEEE80211_AUTH_WPA:	/* WPA w/ 802.1x */
2860 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2861 			ireq->i_val = IEEE80211_AUTH_8021X;
2862 			break;
2863 		case IEEE80211_AUTH_OPEN:	/* open */
2864 			vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY);
2865 			break;
2866 		case IEEE80211_AUTH_SHARED:	/* shared-key */
2867 		case IEEE80211_AUTH_8021X:	/* 802.1x */
2868 			vap->iv_flags &= ~IEEE80211_F_WPA;
2869 			/* both require a key so mark the PRIVACY capability */
2870 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2871 			break;
2872 		case IEEE80211_AUTH_AUTO:	/* auto */
2873 			vap->iv_flags &= ~IEEE80211_F_WPA;
2874 			/* XXX PRIVACY handling? */
2875 			/* XXX what's the right way to do this? */
2876 			break;
2877 		}
2878 		/* NB: authenticator attach/detach happens on state change */
2879 		vap->iv_bss->ni_authmode = ireq->i_val;
2880 		/* XXX mixed/mode/usage? */
2881 		vap->iv_auth = auth;
2882 		error = ENETRESET;
2883 		break;
2884 	case IEEE80211_IOC_CHANNEL:
2885 		error = ieee80211_ioctl_setchannel(vap, ireq);
2886 		break;
2887 	case IEEE80211_IOC_POWERSAVE:
2888 		switch (ireq->i_val) {
2889 		case IEEE80211_POWERSAVE_OFF:
2890 			if (vap->iv_flags & IEEE80211_F_PMGTON) {
2891 				ieee80211_syncflag(vap, -IEEE80211_F_PMGTON);
2892 				error = ERESTART;
2893 			}
2894 			break;
2895 		case IEEE80211_POWERSAVE_ON:
2896 			if ((vap->iv_caps & IEEE80211_C_PMGT) == 0)
2897 				error = EOPNOTSUPP;
2898 			else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) {
2899 				ieee80211_syncflag(vap, IEEE80211_F_PMGTON);
2900 				error = ERESTART;
2901 			}
2902 			break;
2903 		default:
2904 			error = EINVAL;
2905 			break;
2906 		}
2907 		break;
2908 	case IEEE80211_IOC_POWERSAVESLEEP:
2909 		if (ireq->i_val < 0)
2910 			return EINVAL;
2911 		ic->ic_lintval = ireq->i_val;
2912 		error = ERESTART;
2913 		break;
2914 	case IEEE80211_IOC_RTSTHRESHOLD:
2915 		if (!(IEEE80211_RTS_MIN <= ireq->i_val &&
2916 		      ireq->i_val <= IEEE80211_RTS_MAX))
2917 			return EINVAL;
2918 		vap->iv_rtsthreshold = ireq->i_val;
2919 		error = ERESTART;
2920 		break;
2921 	case IEEE80211_IOC_PROTMODE:
2922 		if (ireq->i_val > IEEE80211_PROT_RTSCTS)
2923 			return EINVAL;
2924 		vap->iv_protmode = (enum ieee80211_protmode)ireq->i_val;
2925 		/* NB: if not operating in 11g this can wait */
2926 		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
2927 		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
2928 			error = ERESTART;
2929 		/* driver callback for protection mode update */
2930 		ieee80211_vap_update_erp_protmode(vap);
2931 		break;
2932 	case IEEE80211_IOC_TXPOWER:
2933 		if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
2934 			return EOPNOTSUPP;
2935 		if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val &&
2936 		      ireq->i_val <= IEEE80211_TXPOWER_MAX))
2937 			return EINVAL;
2938 		ic->ic_txpowlimit = ireq->i_val;
2939 		error = ERESTART;
2940 		break;
2941 	case IEEE80211_IOC_ROAMING:
2942 		if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val &&
2943 		    ireq->i_val <= IEEE80211_ROAMING_MANUAL))
2944 			return EINVAL;
2945 		vap->iv_roaming = (enum ieee80211_roamingmode)ireq->i_val;
2946 		/* XXXX reset? */
2947 		break;
2948 	case IEEE80211_IOC_PRIVACY:
2949 		if (ireq->i_val) {
2950 			/* XXX check for key state? */
2951 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2952 		} else
2953 			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
2954 		/* XXX ERESTART? */
2955 		break;
2956 	case IEEE80211_IOC_DROPUNENCRYPTED:
2957 		if (ireq->i_val)
2958 			vap->iv_flags |= IEEE80211_F_DROPUNENC;
2959 		else
2960 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2961 		/* XXX ERESTART? */
2962 		break;
2963 	case IEEE80211_IOC_WPAKEY:
2964 		error = ieee80211_ioctl_setkey(vap, ireq);
2965 		break;
2966 	case IEEE80211_IOC_DELKEY:
2967 		error = ieee80211_ioctl_delkey(vap, ireq);
2968 		break;
2969 	case IEEE80211_IOC_MLME:
2970 		error = ieee80211_ioctl_setmlme(vap, ireq);
2971 		break;
2972 	case IEEE80211_IOC_COUNTERMEASURES:
2973 		if (ireq->i_val) {
2974 			if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
2975 				return EOPNOTSUPP;
2976 			vap->iv_flags |= IEEE80211_F_COUNTERM;
2977 		} else
2978 			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
2979 		/* XXX ERESTART? */
2980 		break;
2981 	case IEEE80211_IOC_WPA:
2982 		if (ireq->i_val > 3)
2983 			return EINVAL;
2984 		/* XXX verify ciphers available */
2985 		flags = vap->iv_flags & ~IEEE80211_F_WPA;
2986 		switch (ireq->i_val) {
2987 		case 0:
2988 			/* wpa_supplicant calls this to clear the WPA config */
2989 			break;
2990 		case 1:
2991 			if (!(vap->iv_caps & IEEE80211_C_WPA1))
2992 				return EOPNOTSUPP;
2993 			flags |= IEEE80211_F_WPA1;
2994 			break;
2995 		case 2:
2996 			if (!(vap->iv_caps & IEEE80211_C_WPA2))
2997 				return EOPNOTSUPP;
2998 			flags |= IEEE80211_F_WPA2;
2999 			break;
3000 		case 3:
3001 			if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA)
3002 				return EOPNOTSUPP;
3003 			flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
3004 			break;
3005 		default:	/*  Can't set any -> error */
3006 			return EOPNOTSUPP;
3007 		}
3008 		vap->iv_flags = flags;
3009 		error = ERESTART;	/* NB: can change beacon frame */
3010 		break;
3011 	case IEEE80211_IOC_WME:
3012 		if (ireq->i_val) {
3013 			if ((vap->iv_caps & IEEE80211_C_WME) == 0)
3014 				return EOPNOTSUPP;
3015 			ieee80211_syncflag(vap, IEEE80211_F_WME);
3016 		} else
3017 			ieee80211_syncflag(vap, -IEEE80211_F_WME);
3018 		error = ERESTART;	/* NB: can change beacon frame */
3019 		break;
3020 	case IEEE80211_IOC_HIDESSID:
3021 		if (ireq->i_val)
3022 			vap->iv_flags |= IEEE80211_F_HIDESSID;
3023 		else
3024 			vap->iv_flags &= ~IEEE80211_F_HIDESSID;
3025 		error = ERESTART;		/* XXX ENETRESET? */
3026 		break;
3027 	case IEEE80211_IOC_APBRIDGE:
3028 		if (ireq->i_val == 0)
3029 			vap->iv_flags |= IEEE80211_F_NOBRIDGE;
3030 		else
3031 			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
3032 		break;
3033 	case IEEE80211_IOC_BSSID:
3034 		if (ireq->i_len != sizeof(tmpbssid))
3035 			return EINVAL;
3036 		error = copyin(ireq->i_data, tmpbssid, ireq->i_len);
3037 		if (error)
3038 			break;
3039 		IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid);
3040 		if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid))
3041 			vap->iv_flags &= ~IEEE80211_F_DESBSSID;
3042 		else
3043 			vap->iv_flags |= IEEE80211_F_DESBSSID;
3044 		error = ENETRESET;
3045 		break;
3046 	case IEEE80211_IOC_CHANLIST:
3047 		error = ieee80211_ioctl_setchanlist(vap, ireq);
3048 		break;
3049 #define	OLD_IEEE80211_IOC_SCAN_REQ	23
3050 #ifdef OLD_IEEE80211_IOC_SCAN_REQ
3051 	case OLD_IEEE80211_IOC_SCAN_REQ:
3052 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
3053 			"%s: active scan request\n", __func__);
3054 		/*
3055 		 * If we are in INIT state then the driver has never
3056 		 * had a chance to setup hardware state to do a scan;
3057 		 * use the state machine to get us up the SCAN state.
3058 		 * Otherwise just invoke the scan machinery to start
3059 		 * a one-time scan.
3060 		 */
3061 		if (vap->iv_state == IEEE80211_S_INIT)
3062 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
3063 		else
3064 			(void) ieee80211_start_scan(vap,
3065 				IEEE80211_SCAN_ACTIVE |
3066 				IEEE80211_SCAN_NOPICK |
3067 				IEEE80211_SCAN_ONCE,
3068 				IEEE80211_SCAN_FOREVER, 0, 0,
3069 				/* XXX use ioctl params */
3070 				vap->iv_des_nssid, vap->iv_des_ssid);
3071 		break;
3072 #endif /* OLD_IEEE80211_IOC_SCAN_REQ */
3073 	case IEEE80211_IOC_SCAN_REQ:
3074 		error = ieee80211_ioctl_scanreq(vap, ireq);
3075 		break;
3076 	case IEEE80211_IOC_SCAN_CANCEL:
3077 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
3078 		    "%s: cancel scan\n", __func__);
3079 		ieee80211_cancel_scan(vap);
3080 		break;
3081 	case IEEE80211_IOC_HTCONF:
3082 		if (ireq->i_val & 1)
3083 			ieee80211_syncflag_ht(vap, IEEE80211_FHT_HT);
3084 		else
3085 			ieee80211_syncflag_ht(vap, -IEEE80211_FHT_HT);
3086 		if (ireq->i_val & 2)
3087 			ieee80211_syncflag_ht(vap, IEEE80211_FHT_USEHT40);
3088 		else
3089 			ieee80211_syncflag_ht(vap, -IEEE80211_FHT_USEHT40);
3090 		error = ENETRESET;
3091 		break;
3092 	case IEEE80211_IOC_ADDMAC:
3093 	case IEEE80211_IOC_DELMAC:
3094 		error = ieee80211_ioctl_macmac(vap, ireq);
3095 		break;
3096 	case IEEE80211_IOC_MACCMD:
3097 		error = ieee80211_ioctl_setmaccmd(vap, ireq);
3098 		break;
3099 	case IEEE80211_IOC_STA_STATS:
3100 		error = ieee80211_ioctl_setstastats(vap, ireq);
3101 		break;
3102 	case IEEE80211_IOC_STA_TXPOW:
3103 		error = ieee80211_ioctl_setstatxpow(vap, ireq);
3104 		break;
3105 	case IEEE80211_IOC_WME_CWMIN:		/* WME: CWmin */
3106 	case IEEE80211_IOC_WME_CWMAX:		/* WME: CWmax */
3107 	case IEEE80211_IOC_WME_AIFS:		/* WME: AIFS */
3108 	case IEEE80211_IOC_WME_TXOPLIMIT:	/* WME: txops limit */
3109 	case IEEE80211_IOC_WME_ACM:		/* WME: ACM (bss only) */
3110 	case IEEE80211_IOC_WME_ACKPOLICY:	/* WME: ACK policy (!bss only) */
3111 		error = ieee80211_ioctl_setwmeparam(vap, ireq);
3112 		break;
3113 	case IEEE80211_IOC_DTIM_PERIOD:
3114 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3115 		    vap->iv_opmode != IEEE80211_M_MBSS &&
3116 		    vap->iv_opmode != IEEE80211_M_IBSS)
3117 			return EINVAL;
3118 		if (IEEE80211_DTIM_MIN <= ireq->i_val &&
3119 		    ireq->i_val <= IEEE80211_DTIM_MAX) {
3120 			vap->iv_dtim_period = ireq->i_val;
3121 			error = ENETRESET;		/* requires restart */
3122 		} else
3123 			error = EINVAL;
3124 		break;
3125 	case IEEE80211_IOC_BEACON_INTERVAL:
3126 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3127 		    vap->iv_opmode != IEEE80211_M_MBSS &&
3128 		    vap->iv_opmode != IEEE80211_M_IBSS)
3129 			return EINVAL;
3130 		if (IEEE80211_BINTVAL_MIN <= ireq->i_val &&
3131 		    ireq->i_val <= IEEE80211_BINTVAL_MAX) {
3132 			ic->ic_bintval = ireq->i_val;
3133 			error = ENETRESET;		/* requires restart */
3134 		} else
3135 			error = EINVAL;
3136 		break;
3137 	case IEEE80211_IOC_PUREG:
3138 		if (ireq->i_val)
3139 			vap->iv_flags |= IEEE80211_F_PUREG;
3140 		else
3141 			vap->iv_flags &= ~IEEE80211_F_PUREG;
3142 		/* NB: reset only if we're operating on an 11g channel */
3143 		if (isvap11g(vap))
3144 			error = ENETRESET;
3145 		break;
3146 	case IEEE80211_IOC_QUIET:
3147 		vap->iv_quiet= ireq->i_val;
3148 		break;
3149 	case IEEE80211_IOC_QUIET_COUNT:
3150 		vap->iv_quiet_count=ireq->i_val;
3151 		break;
3152 	case IEEE80211_IOC_QUIET_PERIOD:
3153 		vap->iv_quiet_period=ireq->i_val;
3154 		break;
3155 	case IEEE80211_IOC_QUIET_OFFSET:
3156 		vap->iv_quiet_offset=ireq->i_val;
3157 		break;
3158 	case IEEE80211_IOC_QUIET_DUR:
3159 		if(ireq->i_val < vap->iv_bss->ni_intval)
3160 			vap->iv_quiet_duration = ireq->i_val;
3161 		else
3162 			error = EINVAL;
3163 		break;
3164 	case IEEE80211_IOC_BGSCAN:
3165 		if (ireq->i_val) {
3166 			if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
3167 				return EOPNOTSUPP;
3168 			vap->iv_flags |= IEEE80211_F_BGSCAN;
3169 		} else
3170 			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
3171 		break;
3172 	case IEEE80211_IOC_BGSCAN_IDLE:
3173 		if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN)
3174 			vap->iv_bgscanidle = ireq->i_val*hz/1000;
3175 		else
3176 			error = EINVAL;
3177 		break;
3178 	case IEEE80211_IOC_BGSCAN_INTERVAL:
3179 		if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN)
3180 			vap->iv_bgscanintvl = ireq->i_val*hz;
3181 		else
3182 			error = EINVAL;
3183 		break;
3184 	case IEEE80211_IOC_SCANVALID:
3185 		if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN)
3186 			vap->iv_scanvalid = ireq->i_val*hz;
3187 		else
3188 			error = EINVAL;
3189 		break;
3190 	case IEEE80211_IOC_FRAGTHRESHOLD:
3191 		if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 &&
3192 		    ireq->i_val != IEEE80211_FRAG_MAX)
3193 			return EOPNOTSUPP;
3194 		if (!(IEEE80211_FRAG_MIN <= ireq->i_val &&
3195 		      ireq->i_val <= IEEE80211_FRAG_MAX))
3196 			return EINVAL;
3197 		vap->iv_fragthreshold = ireq->i_val;
3198 		error = ERESTART;
3199 		break;
3200 	case IEEE80211_IOC_BURST:
3201 		if (ireq->i_val) {
3202 			if ((vap->iv_caps & IEEE80211_C_BURST) == 0)
3203 				return EOPNOTSUPP;
3204 			ieee80211_syncflag(vap, IEEE80211_F_BURST);
3205 		} else
3206 			ieee80211_syncflag(vap, -IEEE80211_F_BURST);
3207 		error = ERESTART;
3208 		break;
3209 	case IEEE80211_IOC_BMISSTHRESHOLD:
3210 		if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val &&
3211 		      ireq->i_val <= IEEE80211_HWBMISS_MAX))
3212 			return EINVAL;
3213 		vap->iv_bmissthreshold = ireq->i_val;
3214 		error = ERESTART;
3215 		break;
3216 	case IEEE80211_IOC_CURCHAN:
3217 		error = ieee80211_ioctl_setcurchan(vap, ireq);
3218 		break;
3219 	case IEEE80211_IOC_SHORTGI:
3220 		if (ireq->i_val) {
3221 #define	IEEE80211_HTCAP_SHORTGI \
3222 	(IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40)
3223 			if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0)
3224 				return EINVAL;
3225 			if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20)
3226 				vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20;
3227 			if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40)
3228 				vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40;
3229 #undef IEEE80211_HTCAP_SHORTGI
3230 		} else
3231 			vap->iv_flags_ht &=
3232 			    ~(IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40);
3233 		error = ERESTART;
3234 		break;
3235 	case IEEE80211_IOC_AMPDU:
3236 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0)
3237 			return EINVAL;
3238 		if (ireq->i_val & 1)
3239 			vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX;
3240 		else
3241 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_TX;
3242 		if (ireq->i_val & 2)
3243 			vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX;
3244 		else
3245 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX;
3246 		/* NB: reset only if we're operating on an 11n channel */
3247 		if (isvapht(vap))
3248 			error = ERESTART;
3249 		break;
3250 	case IEEE80211_IOC_AMPDU_LIMIT:
3251 		/* XXX TODO: figure out ampdu_limit versus ampdu_rxmax */
3252 		if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val &&
3253 		      ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K))
3254 			return EINVAL;
3255 		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
3256 			vap->iv_ampdu_rxmax = ireq->i_val;
3257 		else
3258 			vap->iv_ampdu_limit = ireq->i_val;
3259 		error = ERESTART;
3260 		break;
3261 	case IEEE80211_IOC_AMPDU_DENSITY:
3262 		if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val &&
3263 		      ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16))
3264 			return EINVAL;
3265 		vap->iv_ampdu_density = ireq->i_val;
3266 		error = ERESTART;
3267 		break;
3268 	case IEEE80211_IOC_AMSDU:
3269 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0)
3270 			return EINVAL;
3271 		if (ireq->i_val & 1)
3272 			vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX;
3273 		else
3274 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_TX;
3275 		if (ireq->i_val & 2)
3276 			vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX;
3277 		else
3278 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_RX;
3279 		/* NB: reset only if we're operating on an 11n channel */
3280 		if (isvapht(vap))
3281 			error = ERESTART;
3282 		break;
3283 	case IEEE80211_IOC_AMSDU_LIMIT:
3284 		/* XXX validate */
3285 		vap->iv_amsdu_limit = ireq->i_val;	/* XXX truncation? */
3286 		break;
3287 	case IEEE80211_IOC_PUREN:
3288 		if (ireq->i_val) {
3289 			if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0)
3290 				return EINVAL;
3291 			vap->iv_flags_ht |= IEEE80211_FHT_PUREN;
3292 		} else
3293 			vap->iv_flags_ht &= ~IEEE80211_FHT_PUREN;
3294 		/* NB: reset only if we're operating on an 11n channel */
3295 		if (isvapht(vap))
3296 			error = ERESTART;
3297 		break;
3298 	case IEEE80211_IOC_DOTH:
3299 		if (ireq->i_val) {
3300 #if 0
3301 			/* XXX no capability */
3302 			if ((vap->iv_caps & IEEE80211_C_DOTH) == 0)
3303 				return EOPNOTSUPP;
3304 #endif
3305 			vap->iv_flags |= IEEE80211_F_DOTH;
3306 		} else
3307 			vap->iv_flags &= ~IEEE80211_F_DOTH;
3308 		error = ENETRESET;
3309 		break;
3310 	case IEEE80211_IOC_REGDOMAIN:
3311 		error = ieee80211_ioctl_setregdomain(vap, ireq);
3312 		break;
3313 	case IEEE80211_IOC_ROAM:
3314 		error = ieee80211_ioctl_setroam(vap, ireq);
3315 		break;
3316 	case IEEE80211_IOC_TXPARAMS:
3317 		error = ieee80211_ioctl_settxparams(vap, ireq);
3318 		break;
3319 	case IEEE80211_IOC_HTCOMPAT:
3320 		if (ireq->i_val) {
3321 			if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0)
3322 				return EOPNOTSUPP;
3323 			vap->iv_flags_ht |= IEEE80211_FHT_HTCOMPAT;
3324 		} else
3325 			vap->iv_flags_ht &= ~IEEE80211_FHT_HTCOMPAT;
3326 		/* NB: reset only if we're operating on an 11n channel */
3327 		if (isvapht(vap))
3328 			error = ERESTART;
3329 		break;
3330 	case IEEE80211_IOC_DWDS:
3331 		if (ireq->i_val) {
3332 			/* NB: DWDS only makes sense for WDS-capable devices */
3333 			if ((ic->ic_caps & IEEE80211_C_WDS) == 0)
3334 				return EOPNOTSUPP;
3335 			/* NB: DWDS is used only with ap+sta vaps */
3336 			if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3337 			    vap->iv_opmode != IEEE80211_M_STA)
3338 				return EINVAL;
3339 			vap->iv_flags |= IEEE80211_F_DWDS;
3340 			if (vap->iv_opmode == IEEE80211_M_STA)
3341 				vap->iv_flags_ext |= IEEE80211_FEXT_4ADDR;
3342 		} else {
3343 			vap->iv_flags &= ~IEEE80211_F_DWDS;
3344 			if (vap->iv_opmode == IEEE80211_M_STA)
3345 				vap->iv_flags_ext &= ~IEEE80211_FEXT_4ADDR;
3346 		}
3347 		break;
3348 	case IEEE80211_IOC_INACTIVITY:
3349 		if (ireq->i_val)
3350 			vap->iv_flags_ext |= IEEE80211_FEXT_INACT;
3351 		else
3352 			vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT;
3353 		break;
3354 	case IEEE80211_IOC_APPIE:
3355 		error = ieee80211_ioctl_setappie(vap, ireq);
3356 		break;
3357 	case IEEE80211_IOC_WPS:
3358 		if (ireq->i_val) {
3359 			if ((vap->iv_caps & IEEE80211_C_WPA) == 0)
3360 				return EOPNOTSUPP;
3361 			vap->iv_flags_ext |= IEEE80211_FEXT_WPS;
3362 		} else
3363 			vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS;
3364 		break;
3365 	case IEEE80211_IOC_TSN:
3366 		if (ireq->i_val) {
3367 			if ((vap->iv_caps & IEEE80211_C_WPA) == 0)
3368 				return EOPNOTSUPP;
3369 			vap->iv_flags_ext |= IEEE80211_FEXT_TSN;
3370 		} else
3371 			vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN;
3372 		break;
3373 	case IEEE80211_IOC_CHANSWITCH:
3374 		error = ieee80211_ioctl_chanswitch(vap, ireq);
3375 		break;
3376 	case IEEE80211_IOC_DFS:
3377 		if (ireq->i_val) {
3378 			if ((vap->iv_caps & IEEE80211_C_DFS) == 0)
3379 				return EOPNOTSUPP;
3380 			/* NB: DFS requires 11h support */
3381 			if ((vap->iv_flags & IEEE80211_F_DOTH) == 0)
3382 				return EINVAL;
3383 			vap->iv_flags_ext |= IEEE80211_FEXT_DFS;
3384 		} else
3385 			vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS;
3386 		break;
3387 	case IEEE80211_IOC_DOTD:
3388 		if (ireq->i_val)
3389 			vap->iv_flags_ext |= IEEE80211_FEXT_DOTD;
3390 		else
3391 			vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD;
3392 		if (vap->iv_opmode == IEEE80211_M_STA)
3393 			error = ENETRESET;
3394 		break;
3395 	case IEEE80211_IOC_HTPROTMODE:
3396 		if (ireq->i_val > IEEE80211_PROT_RTSCTS)
3397 			return EINVAL;
3398 		vap->iv_htprotmode = ireq->i_val ?
3399 		    IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE;
3400 		/* NB: if not operating in 11n this can wait */
3401 		if (isvapht(vap))
3402 			error = ERESTART;
3403 		/* Notify driver layer of HT protmode changes */
3404 		ieee80211_vap_update_ht_protmode(vap);
3405 		break;
3406 	case IEEE80211_IOC_STA_VLAN:
3407 		error = ieee80211_ioctl_setstavlan(vap, ireq);
3408 		break;
3409 	case IEEE80211_IOC_SMPS:
3410 		if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 ||
3411 		    ireq->i_val == 0x0008)	/* value of 2 is reserved */
3412 			return EINVAL;
3413 		if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF &&
3414 		    (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0)
3415 			return EOPNOTSUPP;
3416 		vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) |
3417 			ireq->i_val;
3418 		/* NB: if not operating in 11n this can wait */
3419 		if (isvapht(vap))
3420 			error = ERESTART;
3421 		break;
3422 	case IEEE80211_IOC_RIFS:
3423 		if (ireq->i_val != 0) {
3424 			if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0)
3425 				return EOPNOTSUPP;
3426 			vap->iv_flags_ht |= IEEE80211_FHT_RIFS;
3427 		} else
3428 			vap->iv_flags_ht &= ~IEEE80211_FHT_RIFS;
3429 		/* NB: if not operating in 11n this can wait */
3430 		if (isvapht(vap))
3431 			error = ERESTART;
3432 		break;
3433 	case IEEE80211_IOC_STBC:
3434 		/* Check if we can do STBC TX/RX before changing the setting */
3435 		if ((ireq->i_val & 1) &&
3436 		    ((vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) == 0))
3437 			return EOPNOTSUPP;
3438 		if ((ireq->i_val & 2) &&
3439 		    ((vap->iv_htcaps & IEEE80211_HTCAP_RXSTBC) == 0))
3440 			return EOPNOTSUPP;
3441 
3442 		/* TX */
3443 		if (ireq->i_val & 1)
3444 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_TX;
3445 		else
3446 			vap->iv_flags_ht &= ~IEEE80211_FHT_STBC_TX;
3447 
3448 		/* RX */
3449 		if (ireq->i_val & 2)
3450 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_RX;
3451 		else
3452 			vap->iv_flags_ht &= ~IEEE80211_FHT_STBC_RX;
3453 
3454 		/* NB: reset only if we're operating on an 11n channel */
3455 		if (isvapht(vap))
3456 			error = ERESTART;
3457 		break;
3458 	case IEEE80211_IOC_LDPC:
3459 		/* Check if we can do LDPC TX/RX before changing the setting */
3460 		if ((ireq->i_val & 1) &&
3461 		    (vap->iv_htcaps & IEEE80211_HTC_TXLDPC) == 0)
3462 			return EOPNOTSUPP;
3463 		if ((ireq->i_val & 2) &&
3464 		    (vap->iv_htcaps & IEEE80211_HTCAP_LDPC) == 0)
3465 			return EOPNOTSUPP;
3466 
3467 		/* TX */
3468 		if (ireq->i_val & 1)
3469 			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
3470 		else
3471 			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_TX;
3472 
3473 		/* RX */
3474 		if (ireq->i_val & 2)
3475 			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
3476 		else
3477 			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_RX;
3478 
3479 		/* NB: reset only if we're operating on an 11n channel */
3480 		if (isvapht(vap))
3481 			error = ERESTART;
3482 		break;
3483 	case IEEE80211_IOC_UAPSD:
3484 		if ((vap->iv_caps & IEEE80211_C_UAPSD) == 0)
3485 			return EOPNOTSUPP;
3486 		if (ireq->i_val == 0)
3487 			vap->iv_flags_ext &= ~IEEE80211_FEXT_UAPSD;
3488 		else if (ireq->i_val == 1)
3489 			vap->iv_flags_ext |= IEEE80211_FEXT_UAPSD;
3490 		else
3491 			return EINVAL;
3492 		break;
3493 
3494 	/* VHT */
3495 	case IEEE80211_IOC_VHTCONF:
3496 		if (ireq->i_val & IEEE80211_FVHT_VHT)
3497 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_VHT);
3498 		else
3499 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_VHT);
3500 
3501 		if (ireq->i_val & IEEE80211_FVHT_USEVHT40)
3502 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT40);
3503 		else
3504 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT40);
3505 
3506 		if (ireq->i_val & IEEE80211_FVHT_USEVHT80)
3507 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80);
3508 		else
3509 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80);
3510 
3511 		if (ireq->i_val & IEEE80211_FVHT_USEVHT160)
3512 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT160);
3513 		else
3514 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT160);
3515 
3516 		if (ireq->i_val & IEEE80211_FVHT_USEVHT80P80)
3517 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80P80);
3518 		else
3519 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80P80);
3520 
3521 		error = ENETRESET;
3522 		break;
3523 
3524 	default:
3525 		error = ieee80211_ioctl_setdefault(vap, ireq);
3526 		break;
3527 	}
3528 	/*
3529 	 * The convention is that ENETRESET means an operation
3530 	 * requires a complete re-initialization of the device (e.g.
3531 	 * changing something that affects the association state).
3532 	 * ERESTART means the request may be handled with only a
3533 	 * reload of the hardware state.  We hand ERESTART requests
3534 	 * to the iv_reset callback so the driver can decide.  If
3535 	 * a device does not fillin iv_reset then it defaults to one
3536 	 * that returns ENETRESET.  Otherwise a driver may return
3537 	 * ENETRESET (in which case a full reset will be done) or
3538 	 * 0 to mean there's no need to do anything (e.g. when the
3539 	 * change has no effect on the driver/device).
3540 	 */
3541 	if (error == ERESTART)
3542 		error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ?
3543 		    vap->iv_reset(vap, ireq->i_type) : 0;
3544 	if (error == ENETRESET) {
3545 		/* XXX need to re-think AUTO handling */
3546 		if (IS_UP_AUTO(vap))
3547 			ieee80211_init(vap);
3548 		error = 0;
3549 	}
3550 	return error;
3551 }
3552 
3553 int
3554 ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
3555 {
3556 	struct ieee80211vap *vap = ifp->if_softc;
3557 	struct ieee80211com *ic = vap->iv_ic;
3558 	int error = 0, wait = 0, ic_used;
3559 	struct ifreq *ifr;
3560 	struct ifaddr *ifa;			/* XXX */
3561 
3562 	ic_used = (cmd != SIOCSIFMTU && cmd != SIOCG80211STATS);
3563 	if (ic_used && (error = ieee80211_com_vincref(vap)) != 0)
3564 		return (error);
3565 
3566 	switch (cmd) {
3567 	case SIOCSIFFLAGS:
3568 		IEEE80211_LOCK(ic);
3569 		if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC) {
3570 			/*
3571 			 * Enable promiscuous mode when:
3572 			 * 1. Interface is not a member of bridge, or
3573 			 * 2. Requested by user, or
3574 			 * 3. In monitor (or adhoc-demo) mode.
3575 			 */
3576 			if (ifp->if_bridge == NULL ||
3577 			    (ifp->if_flags & IFF_PPROMISC) != 0 ||
3578 			    vap->iv_opmode == IEEE80211_M_MONITOR ||
3579 			    (vap->iv_opmode == IEEE80211_M_AHDEMO &&
3580 			    (vap->iv_caps & IEEE80211_C_TDMA) == 0)) {
3581 				ieee80211_promisc(vap,
3582 				    ifp->if_flags & IFF_PROMISC);
3583 				vap->iv_ifflags ^= IFF_PROMISC;
3584 			}
3585 		}
3586 		if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI) {
3587 			ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI);
3588 			vap->iv_ifflags ^= IFF_ALLMULTI;
3589 		}
3590 		if (ifp->if_flags & IFF_UP) {
3591 			/*
3592 			 * Bring ourself up unless we're already operational.
3593 			 * If we're the first vap and the parent is not up
3594 			 * then it will automatically be brought up as a
3595 			 * side-effect of bringing ourself up.
3596 			 */
3597 			if (vap->iv_state == IEEE80211_S_INIT) {
3598 				if (ic->ic_nrunning == 0)
3599 					wait = 1;
3600 				ieee80211_start_locked(vap);
3601 			}
3602 		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3603 			/*
3604 			 * Stop ourself.  If we are the last vap to be
3605 			 * marked down the parent will also be taken down.
3606 			 */
3607 			if (ic->ic_nrunning == 1)
3608 				wait = 1;
3609 			ieee80211_stop_locked(vap);
3610 		}
3611 		IEEE80211_UNLOCK(ic);
3612 		/* Wait for parent ioctl handler if it was queued */
3613 		if (wait) {
3614 			ieee80211_waitfor_parent(ic);
3615 
3616 			/*
3617 			 * Check if the MAC address was changed
3618 			 * via SIOCSIFLLADDR ioctl.
3619 			 *
3620 			 * NB: device may be detached during initialization;
3621 			 * use if_ioctl for existence check.
3622 			 */
3623 			if_addr_rlock(ifp);
3624 			if (ifp->if_ioctl == ieee80211_ioctl &&
3625 			    (ifp->if_flags & IFF_UP) == 0 &&
3626 			    !IEEE80211_ADDR_EQ(vap->iv_myaddr, IF_LLADDR(ifp)))
3627 				IEEE80211_ADDR_COPY(vap->iv_myaddr,
3628 				    IF_LLADDR(ifp));
3629 			if_addr_runlock(ifp);
3630 		}
3631 		break;
3632 	case SIOCADDMULTI:
3633 	case SIOCDELMULTI:
3634 		ieee80211_runtask(ic, &ic->ic_mcast_task);
3635 		break;
3636 	case SIOCSIFMEDIA:
3637 	case SIOCGIFMEDIA:
3638 		ifr = (struct ifreq *)data;
3639 		error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd);
3640 		break;
3641 	case SIOCG80211:
3642 		error = ieee80211_ioctl_get80211(vap, cmd,
3643 				(struct ieee80211req *) data);
3644 		break;
3645 	case SIOCS80211:
3646 		error = ieee80211_priv_check_vap_manage(cmd, vap, ifp);
3647 		if (error == 0)
3648 			error = ieee80211_ioctl_set80211(vap, cmd,
3649 					(struct ieee80211req *) data);
3650 		break;
3651 	case SIOCG80211STATS:
3652 		ifr = (struct ifreq *)data;
3653 		copyout(&vap->iv_stats, ifr_data_get_ptr(ifr),
3654 		    sizeof (vap->iv_stats));
3655 		break;
3656 	case SIOCSIFMTU:
3657 		ifr = (struct ifreq *)data;
3658 		if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu &&
3659 		    ifr->ifr_mtu <= IEEE80211_MTU_MAX))
3660 			error = EINVAL;
3661 		else
3662 			ifp->if_mtu = ifr->ifr_mtu;
3663 		break;
3664 	case SIOCSIFADDR:
3665 		/*
3666 		 * XXX Handle this directly so we can suppress if_init calls.
3667 		 * XXX This should be done in ether_ioctl but for the moment
3668 		 * XXX there are too many other parts of the system that
3669 		 * XXX set IFF_UP and so suppress if_init being called when
3670 		 * XXX it should be.
3671 		 */
3672 		ifa = (struct ifaddr *) data;
3673 		switch (ifa->ifa_addr->sa_family) {
3674 #ifdef INET
3675 		case AF_INET:
3676 			if ((ifp->if_flags & IFF_UP) == 0) {
3677 				ifp->if_flags |= IFF_UP;
3678 				ifp->if_init(ifp->if_softc);
3679 			}
3680 			arp_ifinit(ifp, ifa);
3681 			break;
3682 #endif
3683 		default:
3684 			if ((ifp->if_flags & IFF_UP) == 0) {
3685 				ifp->if_flags |= IFF_UP;
3686 				ifp->if_init(ifp->if_softc);
3687 			}
3688 			break;
3689 		}
3690 		break;
3691 	case SIOCSIFLLADDR:
3692 		error = ieee80211_priv_check_vap_setmac(cmd, vap, ifp);
3693 		if (error == 0)
3694 			break;
3695 		/* Fallthrough */
3696 	default:
3697 		/*
3698 		 * Pass unknown ioctls first to the driver, and if it
3699 		 * returns ENOTTY, then to the generic Ethernet handler.
3700 		 */
3701 		if (ic->ic_ioctl != NULL &&
3702 		    (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY)
3703 			break;
3704 		error = ether_ioctl(ifp, cmd, data);
3705 		break;
3706 	}
3707 
3708 	if (ic_used)
3709 		ieee80211_com_vdecref(vap);
3710 
3711 	return (error);
3712 }
3713