xref: /haiku/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c (revision b8a45b3a2df2379b4301bf3bd5949b9a105be4ba)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 /*
31  * IEEE 802.11 ioctl support (FreeBSD-specific)
32  */
33 
34 #include "opt_inet.h"
35 #include "opt_wlan.h"
36 
37 #include <sys/endian.h>
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
43 #include <sys/systm.h>
44 #include <sys/epoch.h>
45 
46 #include <net/if.h>
47 #include <net/if_var.h>
48 #include <net/if_dl.h>
49 #include <net/if_media.h>
50 #include <net/if_private.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 IEEE80211_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 IEEE80211_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_vht_cap.vht_cap_info;
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_vht_flags & 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 || ssid_len > IEEE80211_NWID_LEN)
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: vap %p iv_state %#x (%s) flags 0x%x%s "
2612 	    "duration 0x%x mindwell %u maxdwell %u nssid %d\n",
2613 	    __func__, vap, vap->iv_state, ieee80211_state_name[vap->iv_state],
2614 	    sr->sr_flags,
2615 	    (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "",
2616 	    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, sr->sr_nssid);
2617 	/*
2618 	 * If we are in INIT state then the driver has never had a chance
2619 	 * to setup hardware state to do a scan; we must use the state
2620 	 * machine to get us up to the SCAN state but once we reach SCAN
2621 	 * state we then want to use the supplied params.  Stash the
2622 	 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the
2623 	 * state machines will recognize this and use the stashed params
2624 	 * to issue the scan request.
2625 	 *
2626 	 * Otherwise just invoke the scan machinery directly.
2627 	 */
2628 	IEEE80211_LOCK(ic);
2629 	if (ic->ic_nrunning == 0) {
2630 		IEEE80211_UNLOCK(ic);
2631 		return ENXIO;
2632 	}
2633 
2634 	if (vap->iv_state == IEEE80211_S_INIT) {
2635 		/* NB: clobbers previous settings */
2636 		vap->iv_scanreq_flags = sr->sr_flags;
2637 		vap->iv_scanreq_duration = sr->sr_duration;
2638 		vap->iv_scanreq_nssid = sr->sr_nssid;
2639 		for (i = 0; i < sr->sr_nssid; i++) {
2640 			vap->iv_scanreq_ssid[i].len = sr->sr_ssid[i].len;
2641 			memcpy(vap->iv_scanreq_ssid[i].ssid,
2642 			    sr->sr_ssid[i].ssid, sr->sr_ssid[i].len);
2643 		}
2644 		vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ;
2645 		IEEE80211_UNLOCK(ic);
2646 		ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
2647 	} else {
2648 		vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
2649 		IEEE80211_UNLOCK(ic);
2650 		if (sr->sr_flags & IEEE80211_IOC_SCAN_CHECK) {
2651 			error = ieee80211_check_scan(vap, sr->sr_flags,
2652 			    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
2653 			    sr->sr_nssid,
2654 			    /* NB: cheat, we assume structures are compatible */
2655 			    (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
2656 		} else {
2657 			error = ieee80211_start_scan(vap, sr->sr_flags,
2658 			    sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
2659 			    sr->sr_nssid,
2660 			    /* NB: cheat, we assume structures are compatible */
2661 			    (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
2662 		}
2663 		if (error == 0)
2664 			return EINPROGRESS;
2665 	}
2666 	return 0;
2667 #undef IEEE80211_IOC_SCAN_FLAGS
2668 }
2669 
2670 static int
2671 ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
2672 {
2673 	struct ieee80211_scan_req *sr;
2674 	int error;
2675 
2676 	if (ireq->i_len != sizeof(*sr))
2677 		return EINVAL;
2678 	sr = IEEE80211_MALLOC(sizeof(*sr), M_TEMP,
2679 	     IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
2680 	if (sr == NULL)
2681 		return ENOMEM;
2682 	error = copyin(ireq->i_data, sr, sizeof(*sr));
2683 	if (error != 0)
2684 		goto bad;
2685 	error = ieee80211_scanreq(vap, sr);
2686 bad:
2687 	IEEE80211_FREE(sr, M_TEMP);
2688 	return error;
2689 }
2690 
2691 static int
2692 ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq)
2693 {
2694 	struct ieee80211_node *ni;
2695 	struct ieee80211req_sta_vlan vlan;
2696 	int error;
2697 
2698 	if (ireq->i_len != sizeof(vlan))
2699 		return EINVAL;
2700 	error = copyin(ireq->i_data, &vlan, sizeof(vlan));
2701 	if (error != 0)
2702 		return error;
2703 	if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) {
2704 		ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap,
2705 		    vlan.sv_macaddr);
2706 		if (ni == NULL)
2707 			return ENOENT;
2708 	} else
2709 		ni = ieee80211_ref_node(vap->iv_bss);
2710 	ni->ni_vlan = vlan.sv_vlan;
2711 	ieee80211_free_node(ni);
2712 	return error;
2713 }
2714 
2715 static int
2716 isvap11g(const struct ieee80211vap *vap)
2717 {
2718 	const struct ieee80211_node *bss = vap->iv_bss;
2719 	return bss->ni_chan != IEEE80211_CHAN_ANYC &&
2720 	    IEEE80211_IS_CHAN_ANYG(bss->ni_chan);
2721 }
2722 
2723 static int
2724 isvapht(const struct ieee80211vap *vap)
2725 {
2726 	const struct ieee80211_node *bss = vap->iv_bss;
2727 	return bss->ni_chan != IEEE80211_CHAN_ANYC &&
2728 	    IEEE80211_IS_CHAN_HT(bss->ni_chan);
2729 }
2730 
2731 /*
2732  * Dummy ioctl set handler so the linker set is defined.
2733  */
2734 static int
2735 dummy_ioctl_set(struct ieee80211vap *vap, struct ieee80211req *ireq)
2736 {
2737 	return ENOSYS;
2738 }
2739 IEEE80211_IOCTL_SET(dummy, dummy_ioctl_set);
2740 
2741 static int
2742 ieee80211_ioctl_setdefault(struct ieee80211vap *vap, struct ieee80211req *ireq)
2743 {
2744 	ieee80211_ioctl_setfunc * const *set;
2745 	int error;
2746 
2747 	SET_FOREACH(set, ieee80211_ioctl_setset) {
2748 		error = (*set)(vap, ireq);
2749 		if (error != ENOSYS)
2750 			return error;
2751 	}
2752 	return EINVAL;
2753 }
2754 
2755 static int
2756 ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq)
2757 {
2758 	struct ieee80211com *ic = vap->iv_ic;
2759 	int error;
2760 	const struct ieee80211_authenticator *auth;
2761 	uint8_t tmpkey[IEEE80211_KEYBUF_SIZE];
2762 	char tmpssid[IEEE80211_NWID_LEN];
2763 	uint8_t tmpbssid[IEEE80211_ADDR_LEN];
2764 	struct ieee80211_key *k;
2765 	u_int kid;
2766 	uint32_t flags;
2767 
2768 	error = 0;
2769 	switch (ireq->i_type) {
2770 	case IEEE80211_IOC_SSID:
2771 		if (ireq->i_val != 0 ||
2772 		    ireq->i_len > IEEE80211_NWID_LEN)
2773 			return EINVAL;
2774 		error = copyin(ireq->i_data, tmpssid, ireq->i_len);
2775 		if (error)
2776 			break;
2777 		memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN);
2778 		vap->iv_des_ssid[0].len = ireq->i_len;
2779 		memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len);
2780 		vap->iv_des_nssid = (ireq->i_len > 0);
2781 		error = ENETRESET;
2782 		break;
2783 	case IEEE80211_IOC_WEP:
2784 		switch (ireq->i_val) {
2785 		case IEEE80211_WEP_OFF:
2786 			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
2787 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2788 			break;
2789 		case IEEE80211_WEP_ON:
2790 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2791 			vap->iv_flags |= IEEE80211_F_DROPUNENC;
2792 			break;
2793 		case IEEE80211_WEP_MIXED:
2794 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2795 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2796 			break;
2797 		}
2798 		error = ENETRESET;
2799 		break;
2800 	case IEEE80211_IOC_WEPKEY:
2801 		kid = (u_int) ireq->i_val;
2802 		if (kid >= IEEE80211_WEP_NKID)
2803 			return EINVAL;
2804 		k = &vap->iv_nw_keys[kid];
2805 		if (ireq->i_len == 0) {
2806 			/* zero-len =>'s delete any existing key */
2807 			(void) ieee80211_crypto_delkey(vap, k);
2808 			break;
2809 		}
2810 		if (ireq->i_len > sizeof(tmpkey))
2811 			return EINVAL;
2812 		memset(tmpkey, 0, sizeof(tmpkey));
2813 		error = copyin(ireq->i_data, tmpkey, ireq->i_len);
2814 		if (error)
2815 			break;
2816 		ieee80211_key_update_begin(vap);
2817 		k->wk_keyix = kid;	/* NB: force fixed key id */
2818 		if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP,
2819 		    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) {
2820 			k->wk_keylen = ireq->i_len;
2821 			memcpy(k->wk_key, tmpkey, sizeof(tmpkey));
2822 			IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr);
2823 			if  (!ieee80211_crypto_setkey(vap, k))
2824 				error = EINVAL;
2825 		} else
2826 			error = EINVAL;
2827 		ieee80211_key_update_end(vap);
2828 		break;
2829 	case IEEE80211_IOC_WEPTXKEY:
2830 		kid = (u_int) ireq->i_val;
2831 		if (kid >= IEEE80211_WEP_NKID &&
2832 		    (uint16_t) kid != IEEE80211_KEYIX_NONE)
2833 			return EINVAL;
2834 		/*
2835 		 * Firmware devices may need to be told about an explicit
2836 		 * key index here, versus just inferring it from the
2837 		 * key set / change.  Since we may also need to pause
2838 		 * things like transmit before the key is updated,
2839 		 * give the driver a chance to flush things by tying
2840 		 * into key update begin/end.
2841 		 */
2842 		ieee80211_key_update_begin(vap);
2843 		ieee80211_crypto_set_deftxkey(vap, kid);
2844 		ieee80211_key_update_end(vap);
2845 		break;
2846 	case IEEE80211_IOC_AUTHMODE:
2847 		switch (ireq->i_val) {
2848 		case IEEE80211_AUTH_WPA:
2849 		case IEEE80211_AUTH_8021X:	/* 802.1x */
2850 		case IEEE80211_AUTH_OPEN:	/* open */
2851 		case IEEE80211_AUTH_SHARED:	/* shared-key */
2852 		case IEEE80211_AUTH_AUTO:	/* auto */
2853 			auth = ieee80211_authenticator_get(ireq->i_val);
2854 			if (auth == NULL)
2855 				return EINVAL;
2856 			break;
2857 		default:
2858 			return EINVAL;
2859 		}
2860 		switch (ireq->i_val) {
2861 		case IEEE80211_AUTH_WPA:	/* WPA w/ 802.1x */
2862 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2863 			ireq->i_val = IEEE80211_AUTH_8021X;
2864 			break;
2865 		case IEEE80211_AUTH_OPEN:	/* open */
2866 			vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY);
2867 			break;
2868 		case IEEE80211_AUTH_SHARED:	/* shared-key */
2869 		case IEEE80211_AUTH_8021X:	/* 802.1x */
2870 			vap->iv_flags &= ~IEEE80211_F_WPA;
2871 			/* both require a key so mark the PRIVACY capability */
2872 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2873 			break;
2874 		case IEEE80211_AUTH_AUTO:	/* auto */
2875 			vap->iv_flags &= ~IEEE80211_F_WPA;
2876 			/* XXX PRIVACY handling? */
2877 			/* XXX what's the right way to do this? */
2878 			break;
2879 		}
2880 		/* NB: authenticator attach/detach happens on state change */
2881 		vap->iv_bss->ni_authmode = ireq->i_val;
2882 		/* XXX mixed/mode/usage? */
2883 		vap->iv_auth = auth;
2884 		error = ENETRESET;
2885 		break;
2886 	case IEEE80211_IOC_CHANNEL:
2887 		error = ieee80211_ioctl_setchannel(vap, ireq);
2888 		break;
2889 	case IEEE80211_IOC_POWERSAVE:
2890 		switch (ireq->i_val) {
2891 		case IEEE80211_POWERSAVE_OFF:
2892 			if (vap->iv_flags & IEEE80211_F_PMGTON) {
2893 				ieee80211_syncflag(vap, -IEEE80211_F_PMGTON);
2894 				error = ERESTART;
2895 			}
2896 			break;
2897 		case IEEE80211_POWERSAVE_ON:
2898 			if ((vap->iv_caps & IEEE80211_C_PMGT) == 0)
2899 				error = EOPNOTSUPP;
2900 			else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) {
2901 				ieee80211_syncflag(vap, IEEE80211_F_PMGTON);
2902 				error = ERESTART;
2903 			}
2904 			break;
2905 		default:
2906 			error = EINVAL;
2907 			break;
2908 		}
2909 		break;
2910 	case IEEE80211_IOC_POWERSAVESLEEP:
2911 		if (ireq->i_val < 0)
2912 			return EINVAL;
2913 		ic->ic_lintval = ireq->i_val;
2914 		error = ERESTART;
2915 		break;
2916 	case IEEE80211_IOC_RTSTHRESHOLD:
2917 		if (!(IEEE80211_RTS_MIN <= ireq->i_val &&
2918 		      ireq->i_val <= IEEE80211_RTS_MAX))
2919 			return EINVAL;
2920 		vap->iv_rtsthreshold = ireq->i_val;
2921 		error = ERESTART;
2922 		break;
2923 	case IEEE80211_IOC_PROTMODE:
2924 		if (ireq->i_val > IEEE80211_PROT_RTSCTS)
2925 			return EINVAL;
2926 		vap->iv_protmode = (enum ieee80211_protmode)ireq->i_val;
2927 		/* NB: if not operating in 11g this can wait */
2928 		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
2929 		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
2930 			error = ERESTART;
2931 		/* driver callback for protection mode update */
2932 		ieee80211_vap_update_erp_protmode(vap);
2933 		break;
2934 	case IEEE80211_IOC_TXPOWER:
2935 		if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
2936 			return EOPNOTSUPP;
2937 		if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val &&
2938 		      ireq->i_val <= IEEE80211_TXPOWER_MAX))
2939 			return EINVAL;
2940 		ic->ic_txpowlimit = ireq->i_val;
2941 		error = ERESTART;
2942 		break;
2943 	case IEEE80211_IOC_ROAMING:
2944 		if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val &&
2945 		    ireq->i_val <= IEEE80211_ROAMING_MANUAL))
2946 			return EINVAL;
2947 		vap->iv_roaming = (enum ieee80211_roamingmode)ireq->i_val;
2948 		/* XXXX reset? */
2949 		break;
2950 	case IEEE80211_IOC_PRIVACY:
2951 		if (ireq->i_val) {
2952 			/* XXX check for key state? */
2953 			vap->iv_flags |= IEEE80211_F_PRIVACY;
2954 		} else
2955 			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
2956 		/* XXX ERESTART? */
2957 		break;
2958 	case IEEE80211_IOC_DROPUNENCRYPTED:
2959 		if (ireq->i_val)
2960 			vap->iv_flags |= IEEE80211_F_DROPUNENC;
2961 		else
2962 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
2963 		/* XXX ERESTART? */
2964 		break;
2965 	case IEEE80211_IOC_WPAKEY:
2966 		error = ieee80211_ioctl_setkey(vap, ireq);
2967 		break;
2968 	case IEEE80211_IOC_DELKEY:
2969 		error = ieee80211_ioctl_delkey(vap, ireq);
2970 		break;
2971 	case IEEE80211_IOC_MLME:
2972 		error = ieee80211_ioctl_setmlme(vap, ireq);
2973 		break;
2974 	case IEEE80211_IOC_COUNTERMEASURES:
2975 		if (ireq->i_val) {
2976 			if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
2977 				return EOPNOTSUPP;
2978 			vap->iv_flags |= IEEE80211_F_COUNTERM;
2979 		} else
2980 			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
2981 		/* XXX ERESTART? */
2982 		break;
2983 	case IEEE80211_IOC_WPA:
2984 		if (ireq->i_val > 3)
2985 			return EINVAL;
2986 		/* XXX verify ciphers available */
2987 		flags = vap->iv_flags & ~IEEE80211_F_WPA;
2988 		switch (ireq->i_val) {
2989 		case 0:
2990 			/* wpa_supplicant calls this to clear the WPA config */
2991 			break;
2992 		case 1:
2993 			if (!(vap->iv_caps & IEEE80211_C_WPA1))
2994 				return EOPNOTSUPP;
2995 			flags |= IEEE80211_F_WPA1;
2996 			break;
2997 		case 2:
2998 			if (!(vap->iv_caps & IEEE80211_C_WPA2))
2999 				return EOPNOTSUPP;
3000 			flags |= IEEE80211_F_WPA2;
3001 			break;
3002 		case 3:
3003 			if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA)
3004 				return EOPNOTSUPP;
3005 			flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
3006 			break;
3007 		default:	/*  Can't set any -> error */
3008 			return EOPNOTSUPP;
3009 		}
3010 		vap->iv_flags = flags;
3011 		error = ERESTART;	/* NB: can change beacon frame */
3012 		break;
3013 	case IEEE80211_IOC_WME:
3014 		if (ireq->i_val) {
3015 			if ((vap->iv_caps & IEEE80211_C_WME) == 0)
3016 				return EOPNOTSUPP;
3017 			ieee80211_syncflag(vap, IEEE80211_F_WME);
3018 		} else
3019 			ieee80211_syncflag(vap, -IEEE80211_F_WME);
3020 		error = ERESTART;	/* NB: can change beacon frame */
3021 		break;
3022 	case IEEE80211_IOC_HIDESSID:
3023 		if (ireq->i_val)
3024 			vap->iv_flags |= IEEE80211_F_HIDESSID;
3025 		else
3026 			vap->iv_flags &= ~IEEE80211_F_HIDESSID;
3027 		error = ERESTART;		/* XXX ENETRESET? */
3028 		break;
3029 	case IEEE80211_IOC_APBRIDGE:
3030 		if (ireq->i_val == 0)
3031 			vap->iv_flags |= IEEE80211_F_NOBRIDGE;
3032 		else
3033 			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
3034 		break;
3035 	case IEEE80211_IOC_BSSID:
3036 		if (ireq->i_len != sizeof(tmpbssid))
3037 			return EINVAL;
3038 		error = copyin(ireq->i_data, tmpbssid, ireq->i_len);
3039 		if (error)
3040 			break;
3041 		IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid);
3042 		if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid))
3043 			vap->iv_flags &= ~IEEE80211_F_DESBSSID;
3044 		else
3045 			vap->iv_flags |= IEEE80211_F_DESBSSID;
3046 		error = ENETRESET;
3047 		break;
3048 	case IEEE80211_IOC_CHANLIST:
3049 		error = ieee80211_ioctl_setchanlist(vap, ireq);
3050 		break;
3051 #define	OLD_IEEE80211_IOC_SCAN_REQ	23
3052 #ifdef OLD_IEEE80211_IOC_SCAN_REQ
3053 	case OLD_IEEE80211_IOC_SCAN_REQ:
3054 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
3055 			"%s: active scan request\n", __func__);
3056 		/*
3057 		 * If we are in INIT state then the driver has never
3058 		 * had a chance to setup hardware state to do a scan;
3059 		 * use the state machine to get us up the SCAN state.
3060 		 * Otherwise just invoke the scan machinery to start
3061 		 * a one-time scan.
3062 		 */
3063 		if (vap->iv_state == IEEE80211_S_INIT)
3064 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
3065 		else
3066 			(void) ieee80211_start_scan(vap,
3067 				IEEE80211_SCAN_ACTIVE |
3068 				IEEE80211_SCAN_NOPICK |
3069 				IEEE80211_SCAN_ONCE,
3070 				IEEE80211_SCAN_FOREVER, 0, 0,
3071 				/* XXX use ioctl params */
3072 				vap->iv_des_nssid, vap->iv_des_ssid);
3073 		break;
3074 #endif /* OLD_IEEE80211_IOC_SCAN_REQ */
3075 	case IEEE80211_IOC_SCAN_REQ:
3076 		error = ieee80211_ioctl_scanreq(vap, ireq);
3077 		break;
3078 	case IEEE80211_IOC_SCAN_CANCEL:
3079 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
3080 		    "%s: cancel scan\n", __func__);
3081 		ieee80211_cancel_scan(vap);
3082 		break;
3083 	case IEEE80211_IOC_HTCONF:
3084 		if (ireq->i_val & 1)
3085 			ieee80211_syncflag_ht(vap, IEEE80211_FHT_HT);
3086 		else
3087 			ieee80211_syncflag_ht(vap, -IEEE80211_FHT_HT);
3088 		if (ireq->i_val & 2)
3089 			ieee80211_syncflag_ht(vap, IEEE80211_FHT_USEHT40);
3090 		else
3091 			ieee80211_syncflag_ht(vap, -IEEE80211_FHT_USEHT40);
3092 		error = ENETRESET;
3093 		break;
3094 	case IEEE80211_IOC_ADDMAC:
3095 	case IEEE80211_IOC_DELMAC:
3096 		error = ieee80211_ioctl_macmac(vap, ireq);
3097 		break;
3098 	case IEEE80211_IOC_MACCMD:
3099 		error = ieee80211_ioctl_setmaccmd(vap, ireq);
3100 		break;
3101 	case IEEE80211_IOC_STA_STATS:
3102 		error = ieee80211_ioctl_setstastats(vap, ireq);
3103 		break;
3104 	case IEEE80211_IOC_STA_TXPOW:
3105 		error = ieee80211_ioctl_setstatxpow(vap, ireq);
3106 		break;
3107 	case IEEE80211_IOC_WME_CWMIN:		/* WME: CWmin */
3108 	case IEEE80211_IOC_WME_CWMAX:		/* WME: CWmax */
3109 	case IEEE80211_IOC_WME_AIFS:		/* WME: AIFS */
3110 	case IEEE80211_IOC_WME_TXOPLIMIT:	/* WME: txops limit */
3111 	case IEEE80211_IOC_WME_ACM:		/* WME: ACM (bss only) */
3112 	case IEEE80211_IOC_WME_ACKPOLICY:	/* WME: ACK policy (!bss only) */
3113 		error = ieee80211_ioctl_setwmeparam(vap, ireq);
3114 		break;
3115 	case IEEE80211_IOC_DTIM_PERIOD:
3116 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3117 		    vap->iv_opmode != IEEE80211_M_MBSS &&
3118 		    vap->iv_opmode != IEEE80211_M_IBSS)
3119 			return EINVAL;
3120 		if (IEEE80211_DTIM_MIN <= ireq->i_val &&
3121 		    ireq->i_val <= IEEE80211_DTIM_MAX) {
3122 			vap->iv_dtim_period = ireq->i_val;
3123 			error = ENETRESET;		/* requires restart */
3124 		} else
3125 			error = EINVAL;
3126 		break;
3127 	case IEEE80211_IOC_BEACON_INTERVAL:
3128 		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3129 		    vap->iv_opmode != IEEE80211_M_MBSS &&
3130 		    vap->iv_opmode != IEEE80211_M_IBSS)
3131 			return EINVAL;
3132 		if (IEEE80211_BINTVAL_MIN <= ireq->i_val &&
3133 		    ireq->i_val <= IEEE80211_BINTVAL_MAX) {
3134 			ic->ic_bintval = ireq->i_val;
3135 			error = ENETRESET;		/* requires restart */
3136 		} else
3137 			error = EINVAL;
3138 		break;
3139 	case IEEE80211_IOC_PUREG:
3140 		if (ireq->i_val)
3141 			vap->iv_flags |= IEEE80211_F_PUREG;
3142 		else
3143 			vap->iv_flags &= ~IEEE80211_F_PUREG;
3144 		/* NB: reset only if we're operating on an 11g channel */
3145 		if (isvap11g(vap))
3146 			error = ENETRESET;
3147 		break;
3148 	case IEEE80211_IOC_QUIET:
3149 		vap->iv_quiet= ireq->i_val;
3150 		break;
3151 	case IEEE80211_IOC_QUIET_COUNT:
3152 		vap->iv_quiet_count=ireq->i_val;
3153 		break;
3154 	case IEEE80211_IOC_QUIET_PERIOD:
3155 		vap->iv_quiet_period=ireq->i_val;
3156 		break;
3157 	case IEEE80211_IOC_QUIET_OFFSET:
3158 		vap->iv_quiet_offset=ireq->i_val;
3159 		break;
3160 	case IEEE80211_IOC_QUIET_DUR:
3161 		if(ireq->i_val < vap->iv_bss->ni_intval)
3162 			vap->iv_quiet_duration = ireq->i_val;
3163 		else
3164 			error = EINVAL;
3165 		break;
3166 	case IEEE80211_IOC_BGSCAN:
3167 		if (ireq->i_val) {
3168 			if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
3169 				return EOPNOTSUPP;
3170 			vap->iv_flags |= IEEE80211_F_BGSCAN;
3171 		} else
3172 			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
3173 		break;
3174 	case IEEE80211_IOC_BGSCAN_IDLE:
3175 		if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN)
3176 			vap->iv_bgscanidle = ireq->i_val*hz/1000;
3177 		else
3178 			error = EINVAL;
3179 		break;
3180 	case IEEE80211_IOC_BGSCAN_INTERVAL:
3181 		if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN)
3182 			vap->iv_bgscanintvl = ireq->i_val*hz;
3183 		else
3184 			error = EINVAL;
3185 		break;
3186 	case IEEE80211_IOC_SCANVALID:
3187 		if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN)
3188 			vap->iv_scanvalid = ireq->i_val*hz;
3189 		else
3190 			error = EINVAL;
3191 		break;
3192 	case IEEE80211_IOC_FRAGTHRESHOLD:
3193 		if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 &&
3194 		    ireq->i_val != IEEE80211_FRAG_MAX)
3195 			return EOPNOTSUPP;
3196 		if (!(IEEE80211_FRAG_MIN <= ireq->i_val &&
3197 		      ireq->i_val <= IEEE80211_FRAG_MAX))
3198 			return EINVAL;
3199 		vap->iv_fragthreshold = ireq->i_val;
3200 		error = ERESTART;
3201 		break;
3202 	case IEEE80211_IOC_BURST:
3203 		if (ireq->i_val) {
3204 			if ((vap->iv_caps & IEEE80211_C_BURST) == 0)
3205 				return EOPNOTSUPP;
3206 			ieee80211_syncflag(vap, IEEE80211_F_BURST);
3207 		} else
3208 			ieee80211_syncflag(vap, -IEEE80211_F_BURST);
3209 		error = ERESTART;
3210 		break;
3211 	case IEEE80211_IOC_BMISSTHRESHOLD:
3212 		if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val &&
3213 		      ireq->i_val <= IEEE80211_HWBMISS_MAX))
3214 			return EINVAL;
3215 		vap->iv_bmissthreshold = ireq->i_val;
3216 		error = ERESTART;
3217 		break;
3218 	case IEEE80211_IOC_CURCHAN:
3219 		error = ieee80211_ioctl_setcurchan(vap, ireq);
3220 		break;
3221 	case IEEE80211_IOC_SHORTGI:
3222 		if (ireq->i_val) {
3223 #define	IEEE80211_HTCAP_SHORTGI \
3224 	(IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40)
3225 			if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0)
3226 				return EINVAL;
3227 			if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20)
3228 				vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20;
3229 			if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40)
3230 				vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40;
3231 #undef IEEE80211_HTCAP_SHORTGI
3232 		} else
3233 			vap->iv_flags_ht &=
3234 			    ~(IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40);
3235 		error = ERESTART;
3236 		break;
3237 	case IEEE80211_IOC_AMPDU:
3238 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0)
3239 			return EINVAL;
3240 		if (ireq->i_val & 1)
3241 			vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX;
3242 		else
3243 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_TX;
3244 		if (ireq->i_val & 2)
3245 			vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX;
3246 		else
3247 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX;
3248 		/* NB: reset only if we're operating on an 11n channel */
3249 		if (isvapht(vap))
3250 			error = ERESTART;
3251 		break;
3252 	case IEEE80211_IOC_AMPDU_LIMIT:
3253 		/* XXX TODO: figure out ampdu_limit versus ampdu_rxmax */
3254 		if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val &&
3255 		      ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K))
3256 			return EINVAL;
3257 		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
3258 			vap->iv_ampdu_rxmax = ireq->i_val;
3259 		else
3260 			vap->iv_ampdu_limit = ireq->i_val;
3261 		error = ERESTART;
3262 		break;
3263 	case IEEE80211_IOC_AMPDU_DENSITY:
3264 		if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val &&
3265 		      ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16))
3266 			return EINVAL;
3267 		vap->iv_ampdu_density = ireq->i_val;
3268 		error = ERESTART;
3269 		break;
3270 	case IEEE80211_IOC_AMSDU:
3271 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0)
3272 			return EINVAL;
3273 		if (ireq->i_val & 1)
3274 			vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX;
3275 		else
3276 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_TX;
3277 		if (ireq->i_val & 2)
3278 			vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX;
3279 		else
3280 			vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_RX;
3281 		/* NB: reset only if we're operating on an 11n channel */
3282 		if (isvapht(vap))
3283 			error = ERESTART;
3284 		break;
3285 	case IEEE80211_IOC_AMSDU_LIMIT:
3286 		/* XXX validate */
3287 		vap->iv_amsdu_limit = ireq->i_val;	/* XXX truncation? */
3288 		break;
3289 	case IEEE80211_IOC_PUREN:
3290 		if (ireq->i_val) {
3291 			if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0)
3292 				return EINVAL;
3293 			vap->iv_flags_ht |= IEEE80211_FHT_PUREN;
3294 		} else
3295 			vap->iv_flags_ht &= ~IEEE80211_FHT_PUREN;
3296 		/* NB: reset only if we're operating on an 11n channel */
3297 		if (isvapht(vap))
3298 			error = ERESTART;
3299 		break;
3300 	case IEEE80211_IOC_DOTH:
3301 		if (ireq->i_val) {
3302 #if 0
3303 			/* XXX no capability */
3304 			if ((vap->iv_caps & IEEE80211_C_DOTH) == 0)
3305 				return EOPNOTSUPP;
3306 #endif
3307 			vap->iv_flags |= IEEE80211_F_DOTH;
3308 		} else
3309 			vap->iv_flags &= ~IEEE80211_F_DOTH;
3310 		error = ENETRESET;
3311 		break;
3312 	case IEEE80211_IOC_REGDOMAIN:
3313 		error = ieee80211_ioctl_setregdomain(vap, ireq);
3314 		break;
3315 	case IEEE80211_IOC_ROAM:
3316 		error = ieee80211_ioctl_setroam(vap, ireq);
3317 		break;
3318 	case IEEE80211_IOC_TXPARAMS:
3319 		error = ieee80211_ioctl_settxparams(vap, ireq);
3320 		break;
3321 	case IEEE80211_IOC_HTCOMPAT:
3322 		if (ireq->i_val) {
3323 			if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0)
3324 				return EOPNOTSUPP;
3325 			vap->iv_flags_ht |= IEEE80211_FHT_HTCOMPAT;
3326 		} else
3327 			vap->iv_flags_ht &= ~IEEE80211_FHT_HTCOMPAT;
3328 		/* NB: reset only if we're operating on an 11n channel */
3329 		if (isvapht(vap))
3330 			error = ERESTART;
3331 		break;
3332 	case IEEE80211_IOC_DWDS:
3333 		if (ireq->i_val) {
3334 			/* NB: DWDS only makes sense for WDS-capable devices */
3335 			if ((ic->ic_caps & IEEE80211_C_WDS) == 0)
3336 				return EOPNOTSUPP;
3337 			/* NB: DWDS is used only with ap+sta vaps */
3338 			if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
3339 			    vap->iv_opmode != IEEE80211_M_STA)
3340 				return EINVAL;
3341 			vap->iv_flags |= IEEE80211_F_DWDS;
3342 			if (vap->iv_opmode == IEEE80211_M_STA)
3343 				vap->iv_flags_ext |= IEEE80211_FEXT_4ADDR;
3344 		} else {
3345 			vap->iv_flags &= ~IEEE80211_F_DWDS;
3346 			if (vap->iv_opmode == IEEE80211_M_STA)
3347 				vap->iv_flags_ext &= ~IEEE80211_FEXT_4ADDR;
3348 		}
3349 		break;
3350 	case IEEE80211_IOC_INACTIVITY:
3351 		if (ireq->i_val)
3352 			vap->iv_flags_ext |= IEEE80211_FEXT_INACT;
3353 		else
3354 			vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT;
3355 		break;
3356 	case IEEE80211_IOC_APPIE:
3357 		error = ieee80211_ioctl_setappie(vap, ireq);
3358 		break;
3359 	case IEEE80211_IOC_WPS:
3360 		if (ireq->i_val) {
3361 			if ((vap->iv_caps & IEEE80211_C_WPA) == 0)
3362 				return EOPNOTSUPP;
3363 			vap->iv_flags_ext |= IEEE80211_FEXT_WPS;
3364 		} else
3365 			vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS;
3366 		break;
3367 	case IEEE80211_IOC_TSN:
3368 		if (ireq->i_val) {
3369 			if ((vap->iv_caps & IEEE80211_C_WPA) == 0)
3370 				return EOPNOTSUPP;
3371 			vap->iv_flags_ext |= IEEE80211_FEXT_TSN;
3372 		} else
3373 			vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN;
3374 		break;
3375 	case IEEE80211_IOC_CHANSWITCH:
3376 		error = ieee80211_ioctl_chanswitch(vap, ireq);
3377 		break;
3378 	case IEEE80211_IOC_DFS:
3379 		if (ireq->i_val) {
3380 			if ((vap->iv_caps & IEEE80211_C_DFS) == 0)
3381 				return EOPNOTSUPP;
3382 			/* NB: DFS requires 11h support */
3383 			if ((vap->iv_flags & IEEE80211_F_DOTH) == 0)
3384 				return EINVAL;
3385 			vap->iv_flags_ext |= IEEE80211_FEXT_DFS;
3386 		} else
3387 			vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS;
3388 		break;
3389 	case IEEE80211_IOC_DOTD:
3390 		if (ireq->i_val)
3391 			vap->iv_flags_ext |= IEEE80211_FEXT_DOTD;
3392 		else
3393 			vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD;
3394 		if (vap->iv_opmode == IEEE80211_M_STA)
3395 			error = ENETRESET;
3396 		break;
3397 	case IEEE80211_IOC_HTPROTMODE:
3398 		if (ireq->i_val > IEEE80211_PROT_RTSCTS)
3399 			return EINVAL;
3400 		vap->iv_htprotmode = ireq->i_val ?
3401 		    IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE;
3402 		/* NB: if not operating in 11n this can wait */
3403 		if (isvapht(vap))
3404 			error = ERESTART;
3405 		/* Notify driver layer of HT protmode changes */
3406 		ieee80211_vap_update_ht_protmode(vap);
3407 		break;
3408 	case IEEE80211_IOC_STA_VLAN:
3409 		error = ieee80211_ioctl_setstavlan(vap, ireq);
3410 		break;
3411 	case IEEE80211_IOC_SMPS:
3412 		if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 ||
3413 		    ireq->i_val == 0x0008)	/* value of 2 is reserved */
3414 			return EINVAL;
3415 		if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF &&
3416 		    (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0)
3417 			return EOPNOTSUPP;
3418 		vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) |
3419 			ireq->i_val;
3420 		/* NB: if not operating in 11n this can wait */
3421 		if (isvapht(vap))
3422 			error = ERESTART;
3423 		break;
3424 	case IEEE80211_IOC_RIFS:
3425 		if (ireq->i_val != 0) {
3426 			if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0)
3427 				return EOPNOTSUPP;
3428 			vap->iv_flags_ht |= IEEE80211_FHT_RIFS;
3429 		} else
3430 			vap->iv_flags_ht &= ~IEEE80211_FHT_RIFS;
3431 		/* NB: if not operating in 11n this can wait */
3432 		if (isvapht(vap))
3433 			error = ERESTART;
3434 		break;
3435 	case IEEE80211_IOC_STBC:
3436 		/* Check if we can do STBC TX/RX before changing the setting */
3437 		if ((ireq->i_val & 1) &&
3438 		    ((vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) == 0))
3439 			return EOPNOTSUPP;
3440 		if ((ireq->i_val & 2) &&
3441 		    ((vap->iv_htcaps & IEEE80211_HTCAP_RXSTBC) == 0))
3442 			return EOPNOTSUPP;
3443 
3444 		/* TX */
3445 		if (ireq->i_val & 1)
3446 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_TX;
3447 		else
3448 			vap->iv_flags_ht &= ~IEEE80211_FHT_STBC_TX;
3449 
3450 		/* RX */
3451 		if (ireq->i_val & 2)
3452 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_RX;
3453 		else
3454 			vap->iv_flags_ht &= ~IEEE80211_FHT_STBC_RX;
3455 
3456 		/* NB: reset only if we're operating on an 11n channel */
3457 		if (isvapht(vap))
3458 			error = ERESTART;
3459 		break;
3460 	case IEEE80211_IOC_LDPC:
3461 		/* Check if we can do LDPC TX/RX before changing the setting */
3462 		if ((ireq->i_val & 1) &&
3463 		    (vap->iv_htcaps & IEEE80211_HTC_TXLDPC) == 0)
3464 			return EOPNOTSUPP;
3465 		if ((ireq->i_val & 2) &&
3466 		    (vap->iv_htcaps & IEEE80211_HTCAP_LDPC) == 0)
3467 			return EOPNOTSUPP;
3468 
3469 		/* TX */
3470 		if (ireq->i_val & 1)
3471 			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
3472 		else
3473 			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_TX;
3474 
3475 		/* RX */
3476 		if (ireq->i_val & 2)
3477 			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
3478 		else
3479 			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_RX;
3480 
3481 		/* NB: reset only if we're operating on an 11n channel */
3482 		if (isvapht(vap))
3483 			error = ERESTART;
3484 		break;
3485 	case IEEE80211_IOC_UAPSD:
3486 		if ((vap->iv_caps & IEEE80211_C_UAPSD) == 0)
3487 			return EOPNOTSUPP;
3488 		if (ireq->i_val == 0)
3489 			vap->iv_flags_ext &= ~IEEE80211_FEXT_UAPSD;
3490 		else if (ireq->i_val == 1)
3491 			vap->iv_flags_ext |= IEEE80211_FEXT_UAPSD;
3492 		else
3493 			return EINVAL;
3494 		break;
3495 
3496 	/* VHT */
3497 	case IEEE80211_IOC_VHTCONF:
3498 		if (ireq->i_val & IEEE80211_FVHT_VHT)
3499 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_VHT);
3500 		else
3501 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_VHT);
3502 
3503 		if (ireq->i_val & IEEE80211_FVHT_USEVHT40)
3504 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT40);
3505 		else
3506 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT40);
3507 
3508 		if (ireq->i_val & IEEE80211_FVHT_USEVHT80)
3509 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80);
3510 		else
3511 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80);
3512 
3513 		if (ireq->i_val & IEEE80211_FVHT_USEVHT160)
3514 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT160);
3515 		else
3516 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT160);
3517 
3518 		if (ireq->i_val & IEEE80211_FVHT_USEVHT80P80)
3519 			ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80P80);
3520 		else
3521 			ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80P80);
3522 
3523 		error = ENETRESET;
3524 		break;
3525 
3526 	default:
3527 		error = ieee80211_ioctl_setdefault(vap, ireq);
3528 		break;
3529 	}
3530 	/*
3531 	 * The convention is that ENETRESET means an operation
3532 	 * requires a complete re-initialization of the device (e.g.
3533 	 * changing something that affects the association state).
3534 	 * ERESTART means the request may be handled with only a
3535 	 * reload of the hardware state.  We hand ERESTART requests
3536 	 * to the iv_reset callback so the driver can decide.  If
3537 	 * a device does not fillin iv_reset then it defaults to one
3538 	 * that returns ENETRESET.  Otherwise a driver may return
3539 	 * ENETRESET (in which case a full reset will be done) or
3540 	 * 0 to mean there's no need to do anything (e.g. when the
3541 	 * change has no effect on the driver/device).
3542 	 */
3543 	if (error == ERESTART)
3544 		error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ?
3545 		    vap->iv_reset(vap, ireq->i_type) : 0;
3546 	if (error == ENETRESET) {
3547 		/* XXX need to re-think AUTO handling */
3548 		if (IS_UP_AUTO(vap))
3549 			ieee80211_init(vap);
3550 		error = 0;
3551 	}
3552 	return error;
3553 }
3554 
3555 int
3556 ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
3557 {
3558 	struct ieee80211vap *vap = ifp->if_softc;
3559 	struct ieee80211com *ic = vap->iv_ic;
3560 	int error = 0, wait = 0, ic_used;
3561 	struct ifreq *ifr;
3562 	struct ifaddr *ifa;			/* XXX */
3563 
3564 	ic_used = (cmd != SIOCSIFMTU && cmd != SIOCG80211STATS);
3565 	if (ic_used && (error = ieee80211_com_vincref(vap)) != 0)
3566 		return (error);
3567 
3568 	switch (cmd) {
3569 	case SIOCSIFFLAGS:
3570 		IEEE80211_LOCK(ic);
3571 		if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC) {
3572 			/*
3573 			 * Enable promiscuous mode when:
3574 			 * 1. Interface is not a member of bridge, or
3575 			 * 2. Requested by user, or
3576 			 * 3. In monitor (or adhoc-demo) mode.
3577 			 */
3578 			if (ifp->if_bridge == NULL ||
3579 			    (ifp->if_flags & IFF_PPROMISC) != 0 ||
3580 			    vap->iv_opmode == IEEE80211_M_MONITOR ||
3581 			    (vap->iv_opmode == IEEE80211_M_AHDEMO &&
3582 			    (vap->iv_caps & IEEE80211_C_TDMA) == 0)) {
3583 				ieee80211_promisc(vap,
3584 				    ifp->if_flags & IFF_PROMISC);
3585 				vap->iv_ifflags ^= IFF_PROMISC;
3586 			}
3587 		}
3588 		if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI) {
3589 			ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI);
3590 			vap->iv_ifflags ^= IFF_ALLMULTI;
3591 		}
3592 		if (ifp->if_flags & IFF_UP) {
3593 			/*
3594 			 * Bring ourself up unless we're already operational.
3595 			 * If we're the first vap and the parent is not up
3596 			 * then it will automatically be brought up as a
3597 			 * side-effect of bringing ourself up.
3598 			 */
3599 			if (vap->iv_state == IEEE80211_S_INIT) {
3600 				if (ic->ic_nrunning == 0)
3601 					wait = 1;
3602 				ieee80211_start_locked(vap);
3603 			}
3604 		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3605 			/*
3606 			 * Stop ourself.  If we are the last vap to be
3607 			 * marked down the parent will also be taken down.
3608 			 */
3609 			if (ic->ic_nrunning == 1)
3610 				wait = 1;
3611 			ieee80211_stop_locked(vap);
3612 		}
3613 		IEEE80211_UNLOCK(ic);
3614 		/* Wait for parent ioctl handler if it was queued */
3615 		if (wait) {
3616 			struct epoch_tracker et;
3617 
3618 			ieee80211_waitfor_parent(ic);
3619 
3620 			/*
3621 			 * Check if the MAC address was changed
3622 			 * via SIOCSIFLLADDR ioctl.
3623 			 *
3624 			 * NB: device may be detached during initialization;
3625 			 * use if_ioctl for existence check.
3626 			 */
3627 			NET_EPOCH_ENTER(et);
3628 			if (ifp->if_ioctl == ieee80211_ioctl &&
3629 			    (ifp->if_flags & IFF_UP) == 0 &&
3630 			    !IEEE80211_ADDR_EQ(vap->iv_myaddr, IF_LLADDR(ifp)))
3631 				IEEE80211_ADDR_COPY(vap->iv_myaddr,
3632 				    IF_LLADDR(ifp));
3633 			NET_EPOCH_EXIT(et);
3634 		}
3635 		break;
3636 	case SIOCADDMULTI:
3637 	case SIOCDELMULTI:
3638 		ieee80211_runtask(ic, &ic->ic_mcast_task);
3639 		break;
3640 	case SIOCSIFMEDIA:
3641 	case SIOCGIFMEDIA:
3642 		ifr = (struct ifreq *)data;
3643 		error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd);
3644 		break;
3645 	case SIOCG80211:
3646 		error = ieee80211_ioctl_get80211(vap, cmd,
3647 				(struct ieee80211req *) data);
3648 		break;
3649 	case SIOCS80211:
3650 		error = ieee80211_priv_check_vap_manage(cmd, vap, ifp);
3651 		if (error == 0)
3652 			error = ieee80211_ioctl_set80211(vap, cmd,
3653 					(struct ieee80211req *) data);
3654 		break;
3655 	case SIOCG80211STATS:
3656 		ifr = (struct ifreq *)data;
3657 		error = copyout(&vap->iv_stats, ifr_data_get_ptr(ifr),
3658 		    sizeof(vap->iv_stats));
3659 		break;
3660 	case SIOCSIFMTU:
3661 		ifr = (struct ifreq *)data;
3662 		if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu &&
3663 		    ifr->ifr_mtu <= IEEE80211_MTU_MAX))
3664 			error = EINVAL;
3665 		else
3666 			ifp->if_mtu = ifr->ifr_mtu;
3667 		break;
3668 	case SIOCSIFADDR:
3669 		/*
3670 		 * XXX Handle this directly so we can suppress if_init calls.
3671 		 * XXX This should be done in ether_ioctl but for the moment
3672 		 * XXX there are too many other parts of the system that
3673 		 * XXX set IFF_UP and so suppress if_init being called when
3674 		 * XXX it should be.
3675 		 */
3676 		ifa = (struct ifaddr *) data;
3677 		switch (ifa->ifa_addr->sa_family) {
3678 #ifdef INET
3679 		case AF_INET:
3680 			if ((ifp->if_flags & IFF_UP) == 0) {
3681 				ifp->if_flags |= IFF_UP;
3682 				ifp->if_init(ifp->if_softc);
3683 			}
3684 			arp_ifinit(ifp, ifa);
3685 			break;
3686 #endif
3687 		default:
3688 			if ((ifp->if_flags & IFF_UP) == 0) {
3689 				ifp->if_flags |= IFF_UP;
3690 				ifp->if_init(ifp->if_softc);
3691 			}
3692 			break;
3693 		}
3694 		break;
3695 	case SIOCSIFLLADDR:
3696 		error = ieee80211_priv_check_vap_setmac(cmd, vap, ifp);
3697 		if (error == 0)
3698 			break;
3699 		/* Fallthrough */
3700 	default:
3701 		/*
3702 		 * Pass unknown ioctls first to the driver, and if it
3703 		 * returns ENOTTY, then to the generic Ethernet handler.
3704 		 */
3705 		if (ic->ic_ioctl != NULL &&
3706 		    (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY)
3707 			break;
3708 		error = ether_ioctl(ifp, cmd, data);
3709 		break;
3710 	}
3711 
3712 	if (ic_used)
3713 		ieee80211_com_vdecref(vap);
3714 
3715 	return (error);
3716 }
3717