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