1 /*-
2  * Copyright (c) 2003
3  *	Bill Paul <wpaul@windriver.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * WPA support originally contributed by Arvind Srinivasan <arvind@celar.us>
33  * then hacked upon mercilessly by my.
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: stable/10/sys/dev/if_ndis/if_ndis.c 343820 2019-02-06 02:07:37Z avos $");
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/sockio.h>
42 #include <sys/mbuf.h>
43 #include <sys/malloc.h>
44 #include <sys/endian.h>
45 #include <sys/priv.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48 #include <sys/queue.h>
49 #include <sys/module.h>
50 #include <sys/proc.h>
51 #include <sys/sysctl.h>
52 #include <sys/kthread.h>
53 
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/ethernet.h>
57 #include <net/if_dl.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60 #include <net/route.h>
61 
62 #include <net/bpf.h>
63 
64 #include <machine/bus.h>
65 #include <machine/resource.h>
66 #include <sys/bus.h>
67 #include <sys/rman.h>
68 
69 #include <net80211/ieee80211_var.h>
70 #include <net80211/ieee80211_ioctl.h>
71 #include <net80211/ieee80211_regdomain.h>
72 
73 #include <dev/pci/pcireg.h>
74 #include <dev/pci/pcivar.h>
75 #include <dev/usb/usb.h>
76 #include <dev/usb/usbdi.h>
77 
78 #include <compat/ndis/pe_var.h>
79 #include <compat/ndis/cfg_var.h>
80 #include <compat/ndis/resource_var.h>
81 #include <compat/ndis/ntoskrnl_var.h>
82 #include <compat/ndis/hal_var.h>
83 #include <compat/ndis/ndis_var.h>
84 #include <compat/ndis/usbd_var.h>
85 #include <dev/if_ndis/if_ndisvar.h>
86 
87 #define NDIS_DEBUG
88 #ifdef NDIS_DEBUG
89 #define DPRINTF(x)	do { if (ndis_debug > 0) printf x; } while (0)
90 int ndis_debug = 0;
91 SYSCTL_INT(_debug, OID_AUTO, ndis, CTLFLAG_RW, &ndis_debug, 0,
92     "if_ndis debug level");
93 #else
94 #define DPRINTF(x)
95 #endif
96 
97 SYSCTL_DECL(_hw_ndisusb);
98 int ndisusb_halt = 1;
99 SYSCTL_INT(_hw_ndisusb, OID_AUTO, halt, CTLFLAG_RW, &ndisusb_halt, 0,
100     "Halt NDIS USB driver when it's attached");
101 
102 /* 0 - 30 dBm to mW conversion table */
103 static const uint16_t dBm2mW[] = {
104 	1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
105 	3, 4, 4, 4, 5, 6, 6, 7, 8, 9,
106 	10, 11, 13, 14, 16, 18, 20, 22, 25, 28,
107 	32, 35, 40, 45, 50, 56, 63, 71, 79, 89,
108 	100, 112, 126, 141, 158, 178, 200, 224, 251, 282,
109 	316, 355, 398, 447, 501, 562, 631, 708, 794, 891,
110 	1000
111 };
112 
113 MODULE_DEPEND(ndis, ether, 1, 1, 1);
114 MODULE_DEPEND(ndis, wlan, 1, 1, 1);
115 MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
116 
117 MODULE_VERSION(ndis, 1);
118 
119 int ndis_attach			(device_t);
120 int ndis_detach			(device_t);
121 int ndis_suspend		(device_t);
122 int ndis_resume			(device_t);
123 void ndis_shutdown		(device_t);
124 
125 int ndisdrv_modevent		(module_t, int, void *);
126 
127 static void ndis_txeof		(ndis_handle, ndis_packet *, ndis_status);
128 static void ndis_rxeof		(ndis_handle, ndis_packet **, uint32_t);
129 static void ndis_rxeof_eth	(ndis_handle, ndis_handle, char *, void *,
130 				 uint32_t, void *, uint32_t, uint32_t);
131 static void ndis_rxeof_done	(ndis_handle);
132 static void ndis_rxeof_xfr	(kdpc *, ndis_handle, void *, void *);
133 static void ndis_rxeof_xfr_done	(ndis_handle, ndis_packet *,
134 				 uint32_t, uint32_t);
135 static void ndis_linksts	(ndis_handle, ndis_status, void *, uint32_t);
136 static void ndis_linksts_done	(ndis_handle);
137 
138 /* We need to wrap these functions for amd64. */
139 static funcptr ndis_txeof_wrap;
140 static funcptr ndis_rxeof_wrap;
141 static funcptr ndis_rxeof_eth_wrap;
142 static funcptr ndis_rxeof_done_wrap;
143 static funcptr ndis_rxeof_xfr_wrap;
144 static funcptr ndis_rxeof_xfr_done_wrap;
145 static funcptr ndis_linksts_wrap;
146 static funcptr ndis_linksts_done_wrap;
147 static funcptr ndis_ticktask_wrap;
148 static funcptr ndis_starttask_wrap;
149 static funcptr ndis_resettask_wrap;
150 static funcptr ndis_inputtask_wrap;
151 
152 static struct	ieee80211vap *ndis_vap_create(struct ieee80211com *,
153 		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
154 		    const uint8_t [IEEE80211_ADDR_LEN],
155 		    const uint8_t [IEEE80211_ADDR_LEN]);
156 static void ndis_vap_delete	(struct ieee80211vap *);
157 static void ndis_tick		(void *);
158 static void ndis_ticktask	(device_object *, void *);
159 static int ndis_raw_xmit	(struct ieee80211_node *, struct mbuf *,
160 	const struct ieee80211_bpf_params *);
161 static void ndis_update_mcast	(struct ifnet *ifp);
162 static void ndis_update_promisc	(struct ifnet *ifp);
163 static void ndis_start		(struct ifnet *);
164 static void ndis_starttask	(device_object *, void *);
165 static void ndis_resettask	(device_object *, void *);
166 static void ndis_inputtask	(device_object *, void *);
167 static int ndis_ioctl		(struct ifnet *, u_long, caddr_t);
168 static int ndis_ioctl_80211	(struct ifnet *, u_long, caddr_t);
169 static int ndis_newstate	(struct ieee80211vap *, enum ieee80211_state,
170 	int);
171 static int ndis_nettype_chan	(uint32_t);
172 static int ndis_nettype_mode	(uint32_t);
173 static void ndis_scan		(void *);
174 static void ndis_scan_results	(struct ndis_softc *);
175 static void ndis_scan_start	(struct ieee80211com *);
176 static void ndis_scan_end	(struct ieee80211com *);
177 static void ndis_set_channel	(struct ieee80211com *);
178 static void ndis_scan_curchan	(struct ieee80211_scan_state *, unsigned long);
179 static void ndis_scan_mindwell	(struct ieee80211_scan_state *);
180 static void ndis_init		(void *);
181 static void ndis_stop		(struct ndis_softc *);
182 static int ndis_ifmedia_upd	(struct ifnet *);
183 static void ndis_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
184 static int ndis_get_bssid_list	(struct ndis_softc *,
185 					ndis_80211_bssid_list_ex **);
186 static int ndis_get_assoc	(struct ndis_softc *, ndis_wlan_bssid_ex **);
187 static int ndis_probe_offload	(struct ndis_softc *);
188 static int ndis_set_offload	(struct ndis_softc *);
189 static void ndis_getstate_80211	(struct ndis_softc *);
190 static void ndis_setstate_80211	(struct ndis_softc *);
191 static void ndis_auth_and_assoc	(struct ndis_softc *, struct ieee80211vap *);
192 static void ndis_media_status	(struct ifnet *, struct ifmediareq *);
193 static int ndis_set_cipher	(struct ndis_softc *, int);
194 static int ndis_set_wpa		(struct ndis_softc *, void *, int);
195 static int ndis_add_key		(struct ieee80211vap *,
196 	const struct ieee80211_key *, const u_int8_t []);
197 static int ndis_del_key		(struct ieee80211vap *,
198 	const struct ieee80211_key *);
199 
200 static void ndis_setmulti	(struct ndis_softc *);
201 static void ndis_map_sclist	(void *, bus_dma_segment_t *,
202 	int, bus_size_t, int);
203 
204 static int ndisdrv_loaded = 0;
205 
206 /*
207  * This routine should call windrv_load() once for each driver
208  * image. This will do the relocation and dynalinking for the
209  * image, and create a Windows driver object which will be
210  * saved in our driver database.
211  */
212 int
ndisdrv_modevent(mod,cmd,arg)213 ndisdrv_modevent(mod, cmd, arg)
214 	module_t		mod;
215 	int			cmd;
216 	void			*arg;
217 {
218 	int			error = 0;
219 
220 	switch (cmd) {
221 	case MOD_LOAD:
222 		ndisdrv_loaded++;
223                 if (ndisdrv_loaded > 1)
224 			break;
225 		windrv_wrap((funcptr)ndis_rxeof, &ndis_rxeof_wrap,
226 		    3, WINDRV_WRAP_STDCALL);
227 		windrv_wrap((funcptr)ndis_rxeof_eth, &ndis_rxeof_eth_wrap,
228 		    8, WINDRV_WRAP_STDCALL);
229 		windrv_wrap((funcptr)ndis_rxeof_done, &ndis_rxeof_done_wrap,
230 		    1, WINDRV_WRAP_STDCALL);
231 		windrv_wrap((funcptr)ndis_rxeof_xfr, &ndis_rxeof_xfr_wrap,
232 		    4, WINDRV_WRAP_STDCALL);
233 		windrv_wrap((funcptr)ndis_rxeof_xfr_done,
234 		    &ndis_rxeof_xfr_done_wrap, 4, WINDRV_WRAP_STDCALL);
235 		windrv_wrap((funcptr)ndis_txeof, &ndis_txeof_wrap,
236 		    3, WINDRV_WRAP_STDCALL);
237 		windrv_wrap((funcptr)ndis_linksts, &ndis_linksts_wrap,
238 		    4, WINDRV_WRAP_STDCALL);
239 		windrv_wrap((funcptr)ndis_linksts_done,
240 		    &ndis_linksts_done_wrap, 1, WINDRV_WRAP_STDCALL);
241 		windrv_wrap((funcptr)ndis_ticktask, &ndis_ticktask_wrap,
242 		    2, WINDRV_WRAP_STDCALL);
243 		windrv_wrap((funcptr)ndis_starttask, &ndis_starttask_wrap,
244 		    2, WINDRV_WRAP_STDCALL);
245 		windrv_wrap((funcptr)ndis_resettask, &ndis_resettask_wrap,
246 		    2, WINDRV_WRAP_STDCALL);
247 		windrv_wrap((funcptr)ndis_inputtask, &ndis_inputtask_wrap,
248 		    2, WINDRV_WRAP_STDCALL);
249 		break;
250 	case MOD_UNLOAD:
251 		ndisdrv_loaded--;
252 		if (ndisdrv_loaded > 0)
253 			break;
254 		/* fallthrough */
255 	case MOD_SHUTDOWN:
256 		windrv_unwrap(ndis_rxeof_wrap);
257 		windrv_unwrap(ndis_rxeof_eth_wrap);
258 		windrv_unwrap(ndis_rxeof_done_wrap);
259 		windrv_unwrap(ndis_rxeof_xfr_wrap);
260 		windrv_unwrap(ndis_rxeof_xfr_done_wrap);
261 		windrv_unwrap(ndis_txeof_wrap);
262 		windrv_unwrap(ndis_linksts_wrap);
263 		windrv_unwrap(ndis_linksts_done_wrap);
264 		windrv_unwrap(ndis_ticktask_wrap);
265 		windrv_unwrap(ndis_starttask_wrap);
266 		windrv_unwrap(ndis_resettask_wrap);
267 		windrv_unwrap(ndis_inputtask_wrap);
268 		break;
269 	default:
270 		error = EINVAL;
271 		break;
272 	}
273 
274 	return (error);
275 }
276 
277 /*
278  * Program the 64-bit multicast hash filter.
279  */
280 static void
ndis_setmulti(sc)281 ndis_setmulti(sc)
282 	struct ndis_softc	*sc;
283 {
284 	struct ifnet		*ifp;
285 	struct ifmultiaddr	*ifma;
286 	int			len, mclistsz, error;
287 	uint8_t			*mclist;
288 
289 	ifp = sc->ifp;
290 
291 	if (!NDIS_INITIALIZED(sc))
292 		return;
293 
294 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
295 		sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
296 		len = sizeof(sc->ndis_filter);
297 		error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
298 		    &sc->ndis_filter, &len);
299 		if (error)
300 			device_printf(sc->ndis_dev,
301 			    "set allmulti failed: %d\n", error);
302 		return;
303 	}
304 
305 	if (TAILQ_EMPTY(&ifp->if_multiaddrs))
306 		return;
307 
308 	len = sizeof(mclistsz);
309 	ndis_get_info(sc, OID_802_3_MAXIMUM_LIST_SIZE, &mclistsz, &len);
310 
311 	mclist = malloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_NOWAIT|M_ZERO);
312 
313 	if (mclist == NULL) {
314 		sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
315 		goto out;
316 	}
317 
318 	sc->ndis_filter |= NDIS_PACKET_TYPE_MULTICAST;
319 
320 	len = 0;
321 	if_maddr_rlock(ifp);
322 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
323 		if (ifma->ifma_addr->sa_family != AF_LINK)
324 			continue;
325 		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
326 		    mclist + (ETHER_ADDR_LEN * len), ETHER_ADDR_LEN);
327 		len++;
328 		if (len > mclistsz) {
329 			if_maddr_runlock(ifp);
330 			sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
331 			sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
332 			goto out;
333 		}
334 	}
335 	if_maddr_runlock(ifp);
336 
337 	len = len * ETHER_ADDR_LEN;
338 	error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len);
339 	if (error) {
340 		device_printf(sc->ndis_dev, "set mclist failed: %d\n", error);
341 		sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
342 		sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
343 	}
344 
345 out:
346 	free(mclist, M_TEMP);
347 
348 	len = sizeof(sc->ndis_filter);
349 	error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
350 	    &sc->ndis_filter, &len);
351 	if (error)
352 		device_printf(sc->ndis_dev, "set multi failed: %d\n", error);
353 }
354 
355 static int
ndis_set_offload(sc)356 ndis_set_offload(sc)
357 	struct ndis_softc	*sc;
358 {
359 	ndis_task_offload	*nto;
360 	ndis_task_offload_hdr	*ntoh;
361 	ndis_task_tcpip_csum	*nttc;
362 	struct ifnet		*ifp;
363 	int			len, error;
364 
365 	ifp = sc->ifp;
366 
367 	if (!NDIS_INITIALIZED(sc))
368 		return (EINVAL);
369 
370 	/* See if there's anything to set. */
371 
372 	error = ndis_probe_offload(sc);
373 	if (error)
374 		return (error);
375 
376 	if (sc->ndis_hwassist == 0 && ifp->if_capabilities == 0)
377 		return (0);
378 
379 	len = sizeof(ndis_task_offload_hdr) + sizeof(ndis_task_offload) +
380 	    sizeof(ndis_task_tcpip_csum);
381 
382 	ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
383 
384 	if (ntoh == NULL)
385 		return (ENOMEM);
386 
387 	ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
388 	ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
389 	ntoh->ntoh_offset_firsttask = sizeof(ndis_task_offload_hdr);
390 	ntoh->ntoh_encapfmt.nef_encaphdrlen = sizeof(struct ether_header);
391 	ntoh->ntoh_encapfmt.nef_encap = NDIS_ENCAP_IEEE802_3;
392 	ntoh->ntoh_encapfmt.nef_flags = NDIS_ENCAPFLAG_FIXEDHDRLEN;
393 
394 	nto = (ndis_task_offload *)((char *)ntoh +
395 	    ntoh->ntoh_offset_firsttask);
396 
397 	nto->nto_vers = NDIS_TASK_OFFLOAD_VERSION;
398 	nto->nto_len = sizeof(ndis_task_offload);
399 	nto->nto_task = NDIS_TASK_TCPIP_CSUM;
400 	nto->nto_offset_nexttask = 0;
401 	nto->nto_taskbuflen = sizeof(ndis_task_tcpip_csum);
402 
403 	nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
404 
405 	if (ifp->if_capenable & IFCAP_TXCSUM)
406 		nttc->nttc_v4tx = sc->ndis_v4tx;
407 
408 	if (ifp->if_capenable & IFCAP_RXCSUM)
409 		nttc->nttc_v4rx = sc->ndis_v4rx;
410 
411 	error = ndis_set_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
412 	free(ntoh, M_TEMP);
413 
414 	return (error);
415 }
416 
417 static int
ndis_probe_offload(sc)418 ndis_probe_offload(sc)
419 	struct ndis_softc	*sc;
420 {
421 	ndis_task_offload	*nto;
422 	ndis_task_offload_hdr	*ntoh;
423 	ndis_task_tcpip_csum	*nttc = NULL;
424 	struct ifnet		*ifp;
425 	int			len, error, dummy;
426 
427 	ifp = sc->ifp;
428 
429 	len = sizeof(dummy);
430 	error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, &dummy, &len);
431 
432 	if (error != ENOSPC)
433 		return (error);
434 
435 	ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
436 
437 	if (ntoh == NULL)
438 		return (ENOMEM);
439 
440 	ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
441 	ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
442 	ntoh->ntoh_encapfmt.nef_encaphdrlen = sizeof(struct ether_header);
443 	ntoh->ntoh_encapfmt.nef_encap = NDIS_ENCAP_IEEE802_3;
444 	ntoh->ntoh_encapfmt.nef_flags = NDIS_ENCAPFLAG_FIXEDHDRLEN;
445 
446 	error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
447 
448 	if (error) {
449 		free(ntoh, M_TEMP);
450 		return (error);
451 	}
452 
453 	if (ntoh->ntoh_vers != NDIS_TASK_OFFLOAD_VERSION) {
454 		free(ntoh, M_TEMP);
455 		return (EINVAL);
456 	}
457 
458 	nto = (ndis_task_offload *)((char *)ntoh +
459 	    ntoh->ntoh_offset_firsttask);
460 
461 	while (1) {
462 		switch (nto->nto_task) {
463 		case NDIS_TASK_TCPIP_CSUM:
464 			nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
465 			break;
466 		/* Don't handle these yet. */
467 		case NDIS_TASK_IPSEC:
468 		case NDIS_TASK_TCP_LARGESEND:
469 		default:
470 			break;
471 		}
472 		if (nto->nto_offset_nexttask == 0)
473 			break;
474 		nto = (ndis_task_offload *)((char *)nto +
475 		    nto->nto_offset_nexttask);
476 	}
477 
478 	if (nttc == NULL) {
479 		free(ntoh, M_TEMP);
480 		return (ENOENT);
481 	}
482 
483 	sc->ndis_v4tx = nttc->nttc_v4tx;
484 	sc->ndis_v4rx = nttc->nttc_v4rx;
485 
486 	if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_IP_CSUM)
487 		sc->ndis_hwassist |= CSUM_IP;
488 	if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_TCP_CSUM)
489 		sc->ndis_hwassist |= CSUM_TCP;
490 	if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_UDP_CSUM)
491 		sc->ndis_hwassist |= CSUM_UDP;
492 
493 	if (sc->ndis_hwassist)
494 		ifp->if_capabilities |= IFCAP_TXCSUM;
495 
496 	if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_IP_CSUM)
497 		ifp->if_capabilities |= IFCAP_RXCSUM;
498 	if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_TCP_CSUM)
499 		ifp->if_capabilities |= IFCAP_RXCSUM;
500 	if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_UDP_CSUM)
501 		ifp->if_capabilities |= IFCAP_RXCSUM;
502 
503 	free(ntoh, M_TEMP);
504 	return (0);
505 }
506 
507 static int
ndis_nettype_chan(uint32_t type)508 ndis_nettype_chan(uint32_t type)
509 {
510 	switch (type) {
511 	case NDIS_80211_NETTYPE_11FH:		return (IEEE80211_CHAN_FHSS);
512 	case NDIS_80211_NETTYPE_11DS:		return (IEEE80211_CHAN_B);
513 	case NDIS_80211_NETTYPE_11OFDM5:	return (IEEE80211_CHAN_A);
514 	case NDIS_80211_NETTYPE_11OFDM24:	return (IEEE80211_CHAN_G);
515 	}
516 	DPRINTF(("unknown channel nettype %d\n", type));
517 	return (IEEE80211_CHAN_B);	/* Default to 11B chan */
518 }
519 
520 static int
ndis_nettype_mode(uint32_t type)521 ndis_nettype_mode(uint32_t type)
522 {
523 	switch (type) {
524 	case NDIS_80211_NETTYPE_11FH:		return (IEEE80211_MODE_FH);
525 	case NDIS_80211_NETTYPE_11DS:		return (IEEE80211_MODE_11B);
526 	case NDIS_80211_NETTYPE_11OFDM5:	return (IEEE80211_MODE_11A);
527 	case NDIS_80211_NETTYPE_11OFDM24:	return (IEEE80211_MODE_11G);
528 	}
529 	DPRINTF(("unknown mode nettype %d\n", type));
530 	return (IEEE80211_MODE_AUTO);
531 }
532 
533 /*
534  * Attach the interface. Allocate softc structures, do ifmedia
535  * setup and ethernet/BPF attach.
536  */
537 int
ndis_attach(dev)538 ndis_attach(dev)
539 	device_t		dev;
540 {
541 	u_char			eaddr[ETHER_ADDR_LEN];
542 	struct ndis_softc	*sc;
543 	driver_object		*pdrv;
544 	device_object		*pdo;
545 	struct ifnet		*ifp = NULL;
546 	int			error = 0, len, mode;
547 	uint8_t			bands = 0;
548 	int			i;
549 
550 	sc = device_get_softc(dev);
551 
552 	mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
553 	    MTX_DEF);
554 	KeInitializeSpinLock(&sc->ndis_rxlock);
555 	KeInitializeSpinLock(&sc->ndisusb_tasklock);
556 	KeInitializeSpinLock(&sc->ndisusb_xferdonelock);
557 	InitializeListHead(&sc->ndis_shlist);
558 	InitializeListHead(&sc->ndisusb_tasklist);
559 	InitializeListHead(&sc->ndisusb_xferdonelist);
560 	callout_init(&sc->ndis_stat_callout, 1);
561 
562 	/* Create sysctl registry nodes */
563 	ndis_create_sysctls(sc);
564 
565 	/* Find the PDO for this device instance. */
566 
567 	if (sc->ndis_iftype == PCIBus)
568 		pdrv = windrv_lookup(0, "PCI Bus");
569 	else if (sc->ndis_iftype == PCMCIABus)
570 		pdrv = windrv_lookup(0, "PCCARD Bus");
571 	else
572 		pdrv = windrv_lookup(0, "USB Bus");
573 	pdo = windrv_find_pdo(pdrv, dev);
574 
575 	/*
576 	 * Create a new functional device object for this
577 	 * device. This is what creates the miniport block
578 	 * for this device instance.
579 	 */
580 
581 	if (NdisAddDevice(sc->ndis_dobj, pdo) != STATUS_SUCCESS) {
582 		device_printf(dev, "failed to create FDO!\n");
583 		error = ENXIO;
584 		goto fail;
585 	}
586 
587 	/* Tell the user what version of the API the driver is using. */
588 	device_printf(dev, "NDIS API version: %d.%d\n",
589 	    sc->ndis_chars->nmc_version_major,
590 	    sc->ndis_chars->nmc_version_minor);
591 
592 	/* Do resource conversion. */
593 	if (sc->ndis_iftype == PCMCIABus || sc->ndis_iftype == PCIBus)
594 		ndis_convert_res(sc);
595 	else
596 		sc->ndis_block->nmb_rlist = NULL;
597 
598 	/* Install our RX and TX interrupt handlers. */
599 	sc->ndis_block->nmb_senddone_func = ndis_txeof_wrap;
600 	sc->ndis_block->nmb_pktind_func = ndis_rxeof_wrap;
601 	sc->ndis_block->nmb_ethrxindicate_func = ndis_rxeof_eth_wrap;
602 	sc->ndis_block->nmb_ethrxdone_func = ndis_rxeof_done_wrap;
603 	sc->ndis_block->nmb_tdcond_func = ndis_rxeof_xfr_done_wrap;
604 
605 	/* Override the status handler so we can detect link changes. */
606 	sc->ndis_block->nmb_status_func = ndis_linksts_wrap;
607 	sc->ndis_block->nmb_statusdone_func = ndis_linksts_done_wrap;
608 
609 	/* Set up work item handlers. */
610 	sc->ndis_tickitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
611 	sc->ndis_startitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
612 	sc->ndis_resetitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
613 	sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
614 	sc->ndisusb_xferdoneitem =
615 	    IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
616 	sc->ndisusb_taskitem =
617 	    IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
618 	KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block);
619 
620 	/* Call driver's init routine. */
621 	if (ndis_init_nic(sc)) {
622 		device_printf(dev, "init handler failed\n");
623 		error = ENXIO;
624 		goto fail;
625 	}
626 
627 	/*
628 	 * Get station address from the driver.
629 	 */
630 	len = sizeof(eaddr);
631 	ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len);
632 
633 	/*
634 	 * Figure out how big to make the TX buffer pool.
635 	 */
636 
637 	len = sizeof(sc->ndis_maxpkts);
638 	if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS,
639 		    &sc->ndis_maxpkts, &len)) {
640 		device_printf(dev, "failed to get max TX packets\n");
641 		error = ENXIO;
642 		goto fail;
643 	}
644 
645 	/*
646 	 * If this is a deserialized miniport, we don't have
647 	 * to honor the OID_GEN_MAXIMUM_SEND_PACKETS result.
648 	 */
649 	if (!NDIS_SERIALIZED(sc->ndis_block))
650 		sc->ndis_maxpkts = NDIS_TXPKTS;
651 
652 	/* Enforce some sanity, just in case. */
653 
654 	if (sc->ndis_maxpkts == 0)
655 		sc->ndis_maxpkts = 10;
656 
657 	sc->ndis_txarray = malloc(sizeof(ndis_packet *) *
658 	    sc->ndis_maxpkts, M_DEVBUF, M_NOWAIT|M_ZERO);
659 
660 	/* Allocate a pool of ndis_packets for TX encapsulation. */
661 
662 	NdisAllocatePacketPool(&i, &sc->ndis_txpool,
663 	    sc->ndis_maxpkts, PROTOCOL_RESERVED_SIZE_IN_PACKET);
664 
665 	if (i != NDIS_STATUS_SUCCESS) {
666 		sc->ndis_txpool = NULL;
667 		device_printf(dev, "failed to allocate TX packet pool");
668 		error = ENOMEM;
669 		goto fail;
670 	}
671 
672 	sc->ndis_txpending = sc->ndis_maxpkts;
673 
674 	sc->ndis_oidcnt = 0;
675 	/* Get supported oid list. */
676 	ndis_get_supported_oids(sc, &sc->ndis_oids, &sc->ndis_oidcnt);
677 
678 	/* If the NDIS module requested scatter/gather, init maps. */
679 	if (sc->ndis_sc)
680 		ndis_init_dma(sc);
681 
682 	/*
683 	 * See if the OID_802_11_CONFIGURATION OID is
684 	 * supported by this driver. If it is, then this an 802.11
685 	 * wireless driver, and we should set up media for wireless.
686 	 */
687 	for (i = 0; i < sc->ndis_oidcnt; i++)
688 		if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) {
689 			sc->ndis_80211++;
690 			break;
691 		}
692 
693 	if (sc->ndis_80211)
694 		ifp = if_alloc(IFT_IEEE80211);
695 	else
696 		ifp = if_alloc(IFT_ETHER);
697 	if (ifp == NULL) {
698 		error = ENOSPC;
699 		goto fail;
700 	}
701 	sc->ifp = ifp;
702 	ifp->if_softc = sc;
703 
704 	/* Check for task offload support. */
705 	ndis_probe_offload(sc);
706 
707 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
708 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
709 	ifp->if_ioctl = ndis_ioctl;
710 	ifp->if_start = ndis_start;
711 	ifp->if_init = ndis_init;
712 	ifp->if_baudrate = 10000000;
713 	IFQ_SET_MAXLEN(&ifp->if_snd, 50);
714 	ifp->if_snd.ifq_drv_maxlen = 25;
715 	IFQ_SET_READY(&ifp->if_snd);
716 	ifp->if_capenable = ifp->if_capabilities;
717 	ifp->if_hwassist = sc->ndis_hwassist;
718 
719 	/* Do media setup */
720 	if (sc->ndis_80211) {
721 		struct ieee80211com	*ic = ifp->if_l2com;
722 		ndis_80211_rates_ex	rates;
723 		struct ndis_80211_nettype_list *ntl;
724 		uint32_t		arg;
725 		int			r;
726 
727 		callout_init(&sc->ndis_scan_callout, 1);
728 
729 		ifp->if_ioctl = ndis_ioctl_80211;
730 		ic->ic_ifp = ifp;
731 		ic->ic_opmode = IEEE80211_M_STA;
732 	        ic->ic_phytype = IEEE80211_T_DS;
733 		ic->ic_caps = IEEE80211_C_8023ENCAP |
734 			IEEE80211_C_STA | IEEE80211_C_IBSS;
735 		setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
736 		len = 0;
737 		r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
738 		    NULL, &len);
739 		if (r != ENOSPC)
740 			goto nonettypes;
741 		ntl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
742 		r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
743 		    ntl, &len);
744 		if (r != 0) {
745 			free(ntl, M_DEVBUF);
746 			goto nonettypes;
747 		}
748 
749 		for (i = 0; i < ntl->ntl_items; i++) {
750 			mode = ndis_nettype_mode(ntl->ntl_type[i]);
751 			if (mode) {
752 				setbit(ic->ic_modecaps, mode);
753 				setbit(&bands, mode);
754 			} else
755 				device_printf(dev, "Unknown nettype %d\n",
756 				    ntl->ntl_type[i]);
757 		}
758 		free(ntl, M_DEVBUF);
759 nonettypes:
760 		/* Default to 11b channels if the card did not supply any */
761 		if (bands == 0) {
762 			setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
763 			setbit(&bands, IEEE80211_MODE_11B);
764 		}
765 		len = sizeof(rates);
766 		bzero((char *)&rates, len);
767 		r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
768 		    (void *)rates, &len);
769 		if (r)
770 			device_printf(dev, "get rates failed: 0x%x\n", r);
771 		/*
772 		 * Since the supported rates only up to 8 can be supported,
773 		 * if this is not 802.11b we're just going to be faking it
774 		 * all up to heck.
775 		 */
776 
777 #define TESTSETRATE(x, y)						\
778 	do {								\
779 		int			i;				\
780 		for (i = 0; i < ic->ic_sup_rates[x].rs_nrates; i++) {	\
781 			if (ic->ic_sup_rates[x].rs_rates[i] == (y))	\
782 				break;					\
783 		}							\
784 		if (i == ic->ic_sup_rates[x].rs_nrates) {		\
785 			ic->ic_sup_rates[x].rs_rates[i] = (y);		\
786 			ic->ic_sup_rates[x].rs_nrates++;		\
787 		}							\
788 	} while (0)
789 
790 #define SETRATE(x, y)	\
791 	ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y)
792 #define INCRATE(x)	\
793 	ic->ic_sup_rates[x].rs_nrates++
794 
795 		ic->ic_curmode = IEEE80211_MODE_AUTO;
796 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11A))
797 			ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0;
798 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11B))
799 			ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0;
800 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11G))
801 			ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0;
802 		for (i = 0; i < len; i++) {
803 			switch (rates[i] & IEEE80211_RATE_VAL) {
804 			case 2:
805 			case 4:
806 			case 11:
807 			case 10:
808 			case 22:
809 				if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) {
810 					/* Lazy-init 802.11b. */
811 					setbit(ic->ic_modecaps,
812 					    IEEE80211_MODE_11B);
813 					ic->ic_sup_rates[IEEE80211_MODE_11B].
814 					    rs_nrates = 0;
815 				}
816 				SETRATE(IEEE80211_MODE_11B, rates[i]);
817 				INCRATE(IEEE80211_MODE_11B);
818 				break;
819 			default:
820 				if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
821 					SETRATE(IEEE80211_MODE_11A, rates[i]);
822 					INCRATE(IEEE80211_MODE_11A);
823 				}
824 				if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
825 					SETRATE(IEEE80211_MODE_11G, rates[i]);
826 					INCRATE(IEEE80211_MODE_11G);
827 				}
828 				break;
829 			}
830 		}
831 
832 		/*
833 		 * If the hardware supports 802.11g, it most
834 		 * likely supports 802.11b and all of the
835 		 * 802.11b and 802.11g speeds, so maybe we can
836 		 * just cheat here.  Just how in the heck do
837 		 * we detect turbo modes, though?
838 		 */
839 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
840 			TESTSETRATE(IEEE80211_MODE_11B,
841 			    IEEE80211_RATE_BASIC|2);
842 			TESTSETRATE(IEEE80211_MODE_11B,
843 			    IEEE80211_RATE_BASIC|4);
844 			TESTSETRATE(IEEE80211_MODE_11B,
845 			    IEEE80211_RATE_BASIC|11);
846 			TESTSETRATE(IEEE80211_MODE_11B,
847 			    IEEE80211_RATE_BASIC|22);
848 		}
849 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
850 			TESTSETRATE(IEEE80211_MODE_11G, 48);
851 			TESTSETRATE(IEEE80211_MODE_11G, 72);
852 			TESTSETRATE(IEEE80211_MODE_11G, 96);
853 			TESTSETRATE(IEEE80211_MODE_11G, 108);
854 		}
855 		if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
856 			TESTSETRATE(IEEE80211_MODE_11A, 48);
857 			TESTSETRATE(IEEE80211_MODE_11A, 72);
858 			TESTSETRATE(IEEE80211_MODE_11A, 96);
859 			TESTSETRATE(IEEE80211_MODE_11A, 108);
860 		}
861 #undef SETRATE
862 #undef INCRATE
863 		ieee80211_init_channels(ic, NULL, &bands);
864 
865 		/*
866 		 * To test for WPA support, we need to see if we can
867 		 * set AUTHENTICATION_MODE to WPA and read it back
868 		 * successfully.
869 		 */
870 		i = sizeof(arg);
871 		arg = NDIS_80211_AUTHMODE_WPA;
872 		r = ndis_set_info(sc,
873 		    OID_802_11_AUTHENTICATION_MODE, &arg, &i);
874 		if (r == 0) {
875 			r = ndis_get_info(sc,
876 			    OID_802_11_AUTHENTICATION_MODE, &arg, &i);
877 			if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA)
878 				ic->ic_caps |= IEEE80211_C_WPA;
879 		}
880 
881 		/*
882 		 * To test for supported ciphers, we set each
883 		 * available encryption type in descending order.
884 		 * If ENC3 works, then we have WEP, TKIP and AES.
885 		 * If only ENC2 works, then we have WEP and TKIP.
886 		 * If only ENC1 works, then we have just WEP.
887 		 */
888 		i = sizeof(arg);
889 		arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
890 		r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
891 		if (r == 0) {
892 			ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
893 					  |  IEEE80211_CRYPTO_TKIP
894 					  |  IEEE80211_CRYPTO_AES_CCM;
895 			goto got_crypto;
896 		}
897 		arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
898 		r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
899 		if (r == 0) {
900 			ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
901 					  |  IEEE80211_CRYPTO_TKIP;
902 			goto got_crypto;
903 		}
904 		arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
905 		r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
906 		if (r == 0)
907 			ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
908 got_crypto:
909 		i = sizeof(arg);
910 		r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
911 		if (r == 0)
912 			ic->ic_caps |= IEEE80211_C_PMGT;
913 
914 		r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i);
915 		if (r == 0)
916 			ic->ic_caps |= IEEE80211_C_TXPMGT;
917 
918 		ieee80211_ifattach(ic, eaddr);
919 		ic->ic_raw_xmit = ndis_raw_xmit;
920 		ic->ic_scan_start = ndis_scan_start;
921 		ic->ic_scan_end = ndis_scan_end;
922 		ic->ic_set_channel = ndis_set_channel;
923 		ic->ic_scan_curchan = ndis_scan_curchan;
924 		ic->ic_scan_mindwell = ndis_scan_mindwell;
925 		ic->ic_bsschan = IEEE80211_CHAN_ANYC;
926 		//ic->ic_bss->ni_chan = ic->ic_bsschan;
927 		ic->ic_vap_create = ndis_vap_create;
928 		ic->ic_vap_delete = ndis_vap_delete;
929 		ic->ic_update_mcast = ndis_update_mcast;
930 		ic->ic_update_promisc = ndis_update_promisc;
931 
932 		if (bootverbose)
933 			ieee80211_announce(ic);
934 
935 	} else {
936 		ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
937 		    ndis_ifmedia_sts);
938 		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
939 		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
940 		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
941 		ifmedia_add(&sc->ifmedia,
942 		    IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
943 		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
944 		ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
945 		ether_ifattach(ifp, eaddr);
946 	}
947 
948 fail:
949 	if (error) {
950 		ndis_detach(dev);
951 		return (error);
952 	}
953 
954 	if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
955 		return (error);
956 
957 	DPRINTF(("attach done.\n"));
958 	/* We're done talking to the NIC for now; halt it. */
959 	ndis_halt_nic(sc);
960 	DPRINTF(("halting done.\n"));
961 
962 	return (error);
963 }
964 
965 static struct ieee80211vap *
ndis_vap_create(struct ieee80211com * ic,const char name[IFNAMSIZ],int unit,enum ieee80211_opmode opmode,int flags,const uint8_t bssid[IEEE80211_ADDR_LEN],const uint8_t mac[IEEE80211_ADDR_LEN])966 ndis_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
967     enum ieee80211_opmode opmode, int flags,
968     const uint8_t bssid[IEEE80211_ADDR_LEN],
969     const uint8_t mac[IEEE80211_ADDR_LEN])
970 {
971 	struct ndis_vap *nvp;
972 	struct ieee80211vap *vap;
973 
974 	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
975 		return NULL;
976 	nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap),
977 	    M_80211_VAP, M_NOWAIT | M_ZERO);
978 	if (nvp == NULL)
979 		return NULL;
980 	vap = &nvp->vap;
981 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
982 	/* override with driver methods */
983 	nvp->newstate = vap->iv_newstate;
984 	vap->iv_newstate = ndis_newstate;
985 
986 	/* complete setup */
987 	ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status);
988 	ic->ic_opmode = opmode;
989 	/* install key handing routines */
990 	vap->iv_key_set = ndis_add_key;
991 	vap->iv_key_delete = ndis_del_key;
992 	return vap;
993 }
994 
995 static void
ndis_vap_delete(struct ieee80211vap * vap)996 ndis_vap_delete(struct ieee80211vap *vap)
997 {
998 	struct ndis_vap *nvp = NDIS_VAP(vap);
999 	struct ieee80211com *ic = vap->iv_ic;
1000 	struct ifnet *ifp = ic->ic_ifp;
1001 	struct ndis_softc *sc = ifp->if_softc;
1002 
1003 	ndis_stop(sc);
1004 	callout_drain(&sc->ndis_scan_callout);
1005 	ieee80211_vap_detach(vap);
1006 	free(nvp, M_80211_VAP);
1007 }
1008 
1009 /*
1010  * Shutdown hardware and free up resources. This can be called any
1011  * time after the mutex has been initialized. It is called in both
1012  * the error case in attach and the normal detach case so it needs
1013  * to be careful about only freeing resources that have actually been
1014  * allocated.
1015  */
1016 int
ndis_detach(dev)1017 ndis_detach(dev)
1018 	device_t		dev;
1019 {
1020 	struct ndis_softc	*sc;
1021 	struct ifnet		*ifp;
1022 	driver_object		*drv;
1023 
1024 	sc = device_get_softc(dev);
1025 	NDIS_LOCK(sc);
1026 	ifp = sc->ifp;
1027 	if (ifp != NULL)
1028 		ifp->if_flags &= ~IFF_UP;
1029 
1030 	if (device_is_attached(dev)) {
1031 		NDIS_UNLOCK(sc);
1032 		ndis_stop(sc);
1033 		if (ifp != NULL) {
1034 			if (sc->ndis_80211)
1035 				ieee80211_ifdetach(ifp->if_l2com);
1036 			else
1037 				ether_ifdetach(ifp);
1038 		}
1039 	} else
1040 		NDIS_UNLOCK(sc);
1041 
1042 	if (sc->ndis_tickitem != NULL)
1043 		IoFreeWorkItem(sc->ndis_tickitem);
1044 	if (sc->ndis_startitem != NULL)
1045 		IoFreeWorkItem(sc->ndis_startitem);
1046 	if (sc->ndis_resetitem != NULL)
1047 		IoFreeWorkItem(sc->ndis_resetitem);
1048 	if (sc->ndis_inputitem != NULL)
1049 		IoFreeWorkItem(sc->ndis_inputitem);
1050 	if (sc->ndisusb_xferdoneitem != NULL)
1051 		IoFreeWorkItem(sc->ndisusb_xferdoneitem);
1052 	if (sc->ndisusb_taskitem != NULL)
1053 		IoFreeWorkItem(sc->ndisusb_taskitem);
1054 
1055 	bus_generic_detach(dev);
1056 	ndis_unload_driver(sc);
1057 
1058 	if (sc->ndis_irq)
1059 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ndis_irq);
1060 	if (sc->ndis_res_io)
1061 		bus_release_resource(dev, SYS_RES_IOPORT,
1062 		    sc->ndis_io_rid, sc->ndis_res_io);
1063 	if (sc->ndis_res_mem)
1064 		bus_release_resource(dev, SYS_RES_MEMORY,
1065 		    sc->ndis_mem_rid, sc->ndis_res_mem);
1066 	if (sc->ndis_res_altmem)
1067 		bus_release_resource(dev, SYS_RES_MEMORY,
1068 		    sc->ndis_altmem_rid, sc->ndis_res_altmem);
1069 
1070 	if (ifp != NULL)
1071 		if_free(ifp);
1072 
1073 	if (sc->ndis_sc)
1074 		ndis_destroy_dma(sc);
1075 
1076 	if (sc->ndis_txarray)
1077 		free(sc->ndis_txarray, M_DEVBUF);
1078 
1079 	if (!sc->ndis_80211)
1080 		ifmedia_removeall(&sc->ifmedia);
1081 
1082 	if (sc->ndis_txpool != NULL)
1083 		NdisFreePacketPool(sc->ndis_txpool);
1084 
1085 	/* Destroy the PDO for this device. */
1086 
1087 	if (sc->ndis_iftype == PCIBus)
1088 		drv = windrv_lookup(0, "PCI Bus");
1089 	else if (sc->ndis_iftype == PCMCIABus)
1090 		drv = windrv_lookup(0, "PCCARD Bus");
1091 	else
1092 		drv = windrv_lookup(0, "USB Bus");
1093 	if (drv == NULL)
1094 		panic("couldn't find driver object");
1095 	windrv_destroy_pdo(drv, dev);
1096 
1097 	if (sc->ndis_iftype == PCIBus)
1098 		bus_dma_tag_destroy(sc->ndis_parent_tag);
1099 
1100 	return (0);
1101 }
1102 
1103 int
ndis_suspend(dev)1104 ndis_suspend(dev)
1105 	device_t		dev;
1106 {
1107 	struct ndis_softc	*sc;
1108 	struct ifnet		*ifp;
1109 
1110 	sc = device_get_softc(dev);
1111 	ifp = sc->ifp;
1112 
1113 #ifdef notdef
1114 	if (NDIS_INITIALIZED(sc))
1115         	ndis_stop(sc);
1116 #endif
1117 
1118 	return (0);
1119 }
1120 
1121 int
ndis_resume(dev)1122 ndis_resume(dev)
1123 	device_t		dev;
1124 {
1125 	struct ndis_softc	*sc;
1126 	struct ifnet		*ifp;
1127 
1128 	sc = device_get_softc(dev);
1129 	ifp = sc->ifp;
1130 
1131 	if (NDIS_INITIALIZED(sc))
1132         	ndis_init(sc);
1133 
1134 	return (0);
1135 }
1136 
1137 /*
1138  * The following bunch of routines are here to support drivers that
1139  * use the NdisMEthIndicateReceive()/MiniportTransferData() mechanism.
1140  * The NdisMEthIndicateReceive() handler runs at DISPATCH_LEVEL for
1141  * serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
1142  * miniports.
1143  */
1144 static void
ndis_rxeof_eth(adapter,ctx,addr,hdr,hdrlen,lookahead,lookaheadlen,pktlen)1145 ndis_rxeof_eth(adapter, ctx, addr, hdr, hdrlen, lookahead, lookaheadlen, pktlen)
1146 	ndis_handle		adapter;
1147 	ndis_handle		ctx;
1148 	char			*addr;
1149 	void			*hdr;
1150 	uint32_t		hdrlen;
1151 	void			*lookahead;
1152 	uint32_t		lookaheadlen;
1153 	uint32_t		pktlen;
1154 {
1155 	ndis_miniport_block	*block;
1156 	uint8_t			irql = 0;
1157 	uint32_t		status;
1158 	ndis_buffer		*b;
1159 	ndis_packet		*p;
1160 	struct mbuf		*m;
1161 	ndis_ethpriv		*priv;
1162 
1163 	block = adapter;
1164 
1165 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1166 	if (m == NULL)
1167 		return;
1168 
1169 	/* Save the data provided to us so far. */
1170 
1171 	m->m_len = lookaheadlen + hdrlen;
1172 	m->m_pkthdr.len = pktlen + hdrlen;
1173 	m->m_next = NULL;
1174 	m_copyback(m, 0, hdrlen, hdr);
1175 	m_copyback(m, hdrlen, lookaheadlen, lookahead);
1176 
1177 	/* Now create a fake NDIS_PACKET to hold the data */
1178 
1179 	NdisAllocatePacket(&status, &p, block->nmb_rxpool);
1180 
1181 	if (status != NDIS_STATUS_SUCCESS) {
1182 		m_freem(m);
1183 		return;
1184 	}
1185 
1186 	p->np_m0 = m;
1187 
1188 	b = IoAllocateMdl(m->m_data, m->m_pkthdr.len, FALSE, FALSE, NULL);
1189 
1190 	if (b == NULL) {
1191 		NdisFreePacket(p);
1192 		m_freem(m);
1193 		return;
1194 	}
1195 
1196 	p->np_private.npp_head = p->np_private.npp_tail = b;
1197 	p->np_private.npp_totlen = m->m_pkthdr.len;
1198 
1199 	/* Save the packet RX context somewhere. */
1200 	priv = (ndis_ethpriv *)&p->np_protocolreserved;
1201 	priv->nep_ctx = ctx;
1202 
1203 	if (!NDIS_SERIALIZED(block))
1204 		KeAcquireSpinLock(&block->nmb_lock, &irql);
1205 
1206 	InsertTailList((&block->nmb_packetlist), (&p->np_list));
1207 
1208 	if (!NDIS_SERIALIZED(block))
1209 		KeReleaseSpinLock(&block->nmb_lock, irql);
1210 }
1211 
1212 /*
1213  * NdisMEthIndicateReceiveComplete() handler, runs at DISPATCH_LEVEL
1214  * for serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
1215  * miniports.
1216  */
1217 static void
ndis_rxeof_done(adapter)1218 ndis_rxeof_done(adapter)
1219 	ndis_handle		adapter;
1220 {
1221 	struct ndis_softc	*sc;
1222 	ndis_miniport_block	*block;
1223 
1224 	block = adapter;
1225 
1226 	/* Schedule transfer/RX of queued packets. */
1227 
1228 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1229 
1230 	KeInsertQueueDpc(&sc->ndis_rxdpc, NULL, NULL);
1231 }
1232 
1233 /*
1234  * MiniportTransferData() handler, runs at DISPATCH_LEVEL.
1235  */
1236 static void
ndis_rxeof_xfr(dpc,adapter,sysarg1,sysarg2)1237 ndis_rxeof_xfr(dpc, adapter, sysarg1, sysarg2)
1238 	kdpc			*dpc;
1239 	ndis_handle		adapter;
1240 	void			*sysarg1;
1241 	void			*sysarg2;
1242 {
1243 	ndis_miniport_block	*block;
1244 	struct ndis_softc	*sc;
1245 	ndis_packet		*p;
1246 	list_entry		*l;
1247 	uint32_t		status;
1248 	ndis_ethpriv		*priv;
1249 	struct ifnet		*ifp;
1250 	struct mbuf		*m;
1251 
1252 	block = adapter;
1253 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1254 	ifp = sc->ifp;
1255 
1256 	KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
1257 
1258 	l = block->nmb_packetlist.nle_flink;
1259 	while(!IsListEmpty(&block->nmb_packetlist)) {
1260 		l = RemoveHeadList((&block->nmb_packetlist));
1261 		p = CONTAINING_RECORD(l, ndis_packet, np_list);
1262 		InitializeListHead((&p->np_list));
1263 
1264 		priv = (ndis_ethpriv *)&p->np_protocolreserved;
1265 		m = p->np_m0;
1266 		p->np_softc = sc;
1267 		p->np_m0 = NULL;
1268 
1269 		KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
1270 
1271 		status = MSCALL6(sc->ndis_chars->nmc_transferdata_func,
1272 		    p, &p->np_private.npp_totlen, block, priv->nep_ctx,
1273 		    m->m_len, m->m_pkthdr.len - m->m_len);
1274 
1275 		KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
1276 
1277 		/*
1278 		 * If status is NDIS_STATUS_PENDING, do nothing and
1279 		 * wait for a callback to the ndis_rxeof_xfr_done()
1280 		 * handler.
1281 	 	 */
1282 
1283 		m->m_len = m->m_pkthdr.len;
1284 		m->m_pkthdr.rcvif = ifp;
1285 
1286 		if (status == NDIS_STATUS_SUCCESS) {
1287 			IoFreeMdl(p->np_private.npp_head);
1288 			NdisFreePacket(p);
1289 			KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1290 			_IF_ENQUEUE(&sc->ndis_rxqueue, m);
1291 			KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1292 			IoQueueWorkItem(sc->ndis_inputitem,
1293 			    (io_workitem_func)ndis_inputtask_wrap,
1294 			    WORKQUEUE_CRITICAL, ifp);
1295 		}
1296 
1297 		if (status == NDIS_STATUS_FAILURE)
1298 			m_freem(m);
1299 
1300 		/* Advance to next packet */
1301 		l = block->nmb_packetlist.nle_flink;
1302 	}
1303 
1304 	KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
1305 }
1306 
1307 /*
1308  * NdisMTransferDataComplete() handler, runs at DISPATCH_LEVEL.
1309  */
1310 static void
ndis_rxeof_xfr_done(adapter,packet,status,len)1311 ndis_rxeof_xfr_done(adapter, packet, status, len)
1312 	ndis_handle		adapter;
1313 	ndis_packet		*packet;
1314 	uint32_t		status;
1315 	uint32_t		len;
1316 {
1317 	ndis_miniport_block	*block;
1318 	struct ndis_softc	*sc;
1319 	struct ifnet		*ifp;
1320 	struct mbuf		*m;
1321 
1322 	block = adapter;
1323 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1324 	ifp = sc->ifp;
1325 
1326 	m = packet->np_m0;
1327 	IoFreeMdl(packet->np_private.npp_head);
1328 	NdisFreePacket(packet);
1329 
1330 	if (status != NDIS_STATUS_SUCCESS) {
1331 		m_freem(m);
1332 		return;
1333 	}
1334 
1335 	m->m_len = m->m_pkthdr.len;
1336 	m->m_pkthdr.rcvif = ifp;
1337 	KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1338 	_IF_ENQUEUE(&sc->ndis_rxqueue, m);
1339 	KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1340 	IoQueueWorkItem(sc->ndis_inputitem,
1341 	    (io_workitem_func)ndis_inputtask_wrap,
1342 	    WORKQUEUE_CRITICAL, ifp);
1343 }
1344 /*
1345  * A frame has been uploaded: pass the resulting mbuf chain up to
1346  * the higher level protocols.
1347  *
1348  * When handling received NDIS packets, the 'status' field in the
1349  * out-of-band portion of the ndis_packet has special meaning. In the
1350  * most common case, the underlying NDIS driver will set this field
1351  * to NDIS_STATUS_SUCCESS, which indicates that it's ok for us to
1352  * take posession of it. We then change the status field to
1353  * NDIS_STATUS_PENDING to tell the driver that we now own the packet,
1354  * and that we will return it at some point in the future via the
1355  * return packet handler.
1356  *
1357  * If the driver hands us a packet with a status of NDIS_STATUS_RESOURCES,
1358  * this means the driver is running out of packet/buffer resources and
1359  * wants to maintain ownership of the packet. In this case, we have to
1360  * copy the packet data into local storage and let the driver keep the
1361  * packet.
1362  */
1363 static void
ndis_rxeof(adapter,packets,pktcnt)1364 ndis_rxeof(adapter, packets, pktcnt)
1365 	ndis_handle		adapter;
1366 	ndis_packet		**packets;
1367 	uint32_t		pktcnt;
1368 {
1369 	struct ndis_softc	*sc;
1370 	ndis_miniport_block	*block;
1371 	ndis_packet		*p;
1372 	uint32_t		s;
1373 	ndis_tcpip_csum		*csum;
1374 	struct ifnet		*ifp;
1375 	struct mbuf		*m0, *m;
1376 	int			i;
1377 
1378 	block = (ndis_miniport_block *)adapter;
1379 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1380 	ifp = sc->ifp;
1381 
1382 	/*
1383 	 * There's a slim chance the driver may indicate some packets
1384 	 * before we're completely ready to handle them. If we detect this,
1385 	 * we need to return them to the miniport and ignore them.
1386 	 */
1387         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1388 		for (i = 0; i < pktcnt; i++) {
1389 			p = packets[i];
1390 			if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) {
1391 				p->np_refcnt++;
1392 				(void)ndis_return_packet(NULL ,p, block);
1393 			}
1394 		}
1395 		return;
1396         }
1397 
1398 	for (i = 0; i < pktcnt; i++) {
1399 		p = packets[i];
1400 		/* Stash the softc here so ptom can use it. */
1401 		p->np_softc = sc;
1402 		if (ndis_ptom(&m0, p)) {
1403 			device_printf(sc->ndis_dev, "ptom failed\n");
1404 			if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS)
1405 				(void)ndis_return_packet(NULL, p, block);
1406 		} else {
1407 #ifdef notdef
1408 			if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) {
1409 				m = m_dup(m0, M_NOWAIT);
1410 				/*
1411 				 * NOTE: we want to destroy the mbuf here, but
1412 				 * we don't actually want to return it to the
1413 				 * driver via the return packet handler. By
1414 				 * bumping np_refcnt, we can prevent the
1415 				 * ndis_return_packet() routine from actually
1416 				 * doing anything.
1417 				 */
1418 				p->np_refcnt++;
1419 				m_freem(m0);
1420 				if (m == NULL)
1421 					ifp->if_ierrors++;
1422 				else
1423 					m0 = m;
1424 			} else
1425 				p->np_oob.npo_status = NDIS_STATUS_PENDING;
1426 #endif
1427 			m = m_dup(m0, M_NOWAIT);
1428 			if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES)
1429 				p->np_refcnt++;
1430 			else
1431 				p->np_oob.npo_status = NDIS_STATUS_PENDING;
1432 			m_freem(m0);
1433 			if (m == NULL) {
1434 				ifp->if_ierrors++;
1435 				continue;
1436 			}
1437 			m0 = m;
1438 			m0->m_pkthdr.rcvif = ifp;
1439 
1440 			/* Deal with checksum offload. */
1441 
1442 			if (ifp->if_capenable & IFCAP_RXCSUM &&
1443 			    p->np_ext.npe_info[ndis_tcpipcsum_info] != NULL) {
1444 				s = (uintptr_t)
1445 			 	    p->np_ext.npe_info[ndis_tcpipcsum_info];
1446 				csum = (ndis_tcpip_csum *)&s;
1447 				if (csum->u.ntc_rxflags &
1448 				    NDIS_RXCSUM_IP_PASSED)
1449 					m0->m_pkthdr.csum_flags |=
1450 					    CSUM_IP_CHECKED|CSUM_IP_VALID;
1451 				if (csum->u.ntc_rxflags &
1452 				    (NDIS_RXCSUM_TCP_PASSED |
1453 				    NDIS_RXCSUM_UDP_PASSED)) {
1454 					m0->m_pkthdr.csum_flags |=
1455 					    CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
1456 					m0->m_pkthdr.csum_data = 0xFFFF;
1457 				}
1458 			}
1459 
1460 			KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1461 			_IF_ENQUEUE(&sc->ndis_rxqueue, m0);
1462 			KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1463 			IoQueueWorkItem(sc->ndis_inputitem,
1464 			    (io_workitem_func)ndis_inputtask_wrap,
1465 			    WORKQUEUE_CRITICAL, ifp);
1466 		}
1467 	}
1468 }
1469 
1470 /*
1471  * This routine is run at PASSIVE_LEVEL. We use this routine to pass
1472  * packets into the stack in order to avoid calling (*ifp->if_input)()
1473  * with any locks held (at DISPATCH_LEVEL, we'll be holding the
1474  * 'dispatch level' per-cpu sleep lock).
1475  */
1476 static void
ndis_inputtask(dobj,arg)1477 ndis_inputtask(dobj, arg)
1478 	device_object		*dobj;
1479 	void			*arg;
1480 {
1481 	ndis_miniport_block	*block;
1482 	struct ifnet		*ifp;
1483 	struct ndis_softc	*sc;
1484 	struct mbuf		*m;
1485 	struct ieee80211com	*ic;
1486 	struct ieee80211vap	*vap;
1487 	uint8_t			irql;
1488 
1489 	ifp = arg;
1490 	sc = ifp->if_softc;
1491 	ic = ifp->if_l2com;
1492 	vap = TAILQ_FIRST(&ic->ic_vaps);
1493 	block = dobj->do_devext;
1494 
1495 	KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1496 	while(1) {
1497 		_IF_DEQUEUE(&sc->ndis_rxqueue, m);
1498 		if (m == NULL)
1499 			break;
1500 		KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1501 		if ((sc->ndis_80211 != 0) && (vap != NULL))
1502 			vap->iv_deliver_data(vap, vap->iv_bss, m);
1503 		else
1504 			(*ifp->if_input)(ifp, m);
1505 		KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1506 	}
1507 	KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1508 }
1509 
1510 /*
1511  * A frame was downloaded to the chip. It's safe for us to clean up
1512  * the list buffers.
1513  */
1514 static void
ndis_txeof(adapter,packet,status)1515 ndis_txeof(adapter, packet, status)
1516 	ndis_handle		adapter;
1517 	ndis_packet		*packet;
1518 	ndis_status		status;
1519 
1520 {
1521 	struct ndis_softc	*sc;
1522 	ndis_miniport_block	*block;
1523 	struct ifnet		*ifp;
1524 	int			idx;
1525 	struct mbuf		*m;
1526 
1527 	block = (ndis_miniport_block *)adapter;
1528 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1529 	ifp = sc->ifp;
1530 
1531 	m = packet->np_m0;
1532 	idx = packet->np_txidx;
1533 	if (sc->ndis_sc)
1534 		bus_dmamap_unload(sc->ndis_ttag, sc->ndis_tmaps[idx]);
1535 
1536 	ndis_free_packet(packet);
1537 	m_freem(m);
1538 
1539 	NDIS_LOCK(sc);
1540 	sc->ndis_txarray[idx] = NULL;
1541 	sc->ndis_txpending++;
1542 
1543 	if (status == NDIS_STATUS_SUCCESS)
1544 		ifp->if_opackets++;
1545 	else
1546 		ifp->if_oerrors++;
1547 
1548 	sc->ndis_tx_timer = 0;
1549 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1550 
1551 	NDIS_UNLOCK(sc);
1552 
1553 	IoQueueWorkItem(sc->ndis_startitem,
1554 	    (io_workitem_func)ndis_starttask_wrap,
1555 	    WORKQUEUE_CRITICAL, ifp);
1556 }
1557 
1558 static void
ndis_linksts(adapter,status,sbuf,slen)1559 ndis_linksts(adapter, status, sbuf, slen)
1560 	ndis_handle		adapter;
1561 	ndis_status		status;
1562 	void			*sbuf;
1563 	uint32_t		slen;
1564 {
1565 	ndis_miniport_block	*block;
1566 	struct ndis_softc	*sc;
1567 
1568 	block = adapter;
1569 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1570 	sc->ndis_sts = status;
1571 
1572 	/* Event list is all full up, drop this one. */
1573 
1574 	NDIS_LOCK(sc);
1575 	if (sc->ndis_evt[sc->ndis_evtpidx].ne_sts) {
1576 		NDIS_UNLOCK(sc);
1577 		return;
1578 	}
1579 
1580 	/* Cache the event. */
1581 
1582 	if (slen) {
1583 		sc->ndis_evt[sc->ndis_evtpidx].ne_buf = malloc(slen,
1584 		    M_TEMP, M_NOWAIT);
1585 		if (sc->ndis_evt[sc->ndis_evtpidx].ne_buf == NULL) {
1586 			NDIS_UNLOCK(sc);
1587 			return;
1588 		}
1589 		bcopy((char *)sbuf,
1590 		    sc->ndis_evt[sc->ndis_evtpidx].ne_buf, slen);
1591 	}
1592 	sc->ndis_evt[sc->ndis_evtpidx].ne_sts = status;
1593 	sc->ndis_evt[sc->ndis_evtpidx].ne_len = slen;
1594 	NDIS_EVTINC(sc->ndis_evtpidx);
1595 	NDIS_UNLOCK(sc);
1596 }
1597 
1598 static void
ndis_linksts_done(adapter)1599 ndis_linksts_done(adapter)
1600 	ndis_handle		adapter;
1601 {
1602 	ndis_miniport_block	*block;
1603 	struct ndis_softc	*sc;
1604 	struct ifnet		*ifp;
1605 
1606 	block = adapter;
1607 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1608 	ifp = sc->ifp;
1609 
1610 	if (!NDIS_INITIALIZED(sc))
1611 		return;
1612 
1613 	switch (sc->ndis_sts) {
1614 	case NDIS_STATUS_MEDIA_CONNECT:
1615 		IoQueueWorkItem(sc->ndis_tickitem,
1616 		    (io_workitem_func)ndis_ticktask_wrap,
1617 		    WORKQUEUE_CRITICAL, sc);
1618 		IoQueueWorkItem(sc->ndis_startitem,
1619 		    (io_workitem_func)ndis_starttask_wrap,
1620 		    WORKQUEUE_CRITICAL, ifp);
1621 		break;
1622 	case NDIS_STATUS_MEDIA_DISCONNECT:
1623 		if (sc->ndis_link)
1624 			IoQueueWorkItem(sc->ndis_tickitem,
1625 		    	    (io_workitem_func)ndis_ticktask_wrap,
1626 			    WORKQUEUE_CRITICAL, sc);
1627 		break;
1628 	default:
1629 		break;
1630 	}
1631 }
1632 
1633 static void
ndis_tick(xsc)1634 ndis_tick(xsc)
1635 	void			*xsc;
1636 {
1637 	struct ndis_softc	*sc;
1638 
1639 	sc = xsc;
1640 
1641 	if (sc->ndis_hang_timer && --sc->ndis_hang_timer == 0) {
1642 		IoQueueWorkItem(sc->ndis_tickitem,
1643 		    (io_workitem_func)ndis_ticktask_wrap,
1644 		    WORKQUEUE_CRITICAL, sc);
1645 		sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
1646 	}
1647 
1648 	if (sc->ndis_tx_timer && --sc->ndis_tx_timer == 0) {
1649 		sc->ifp->if_oerrors++;
1650 		device_printf(sc->ndis_dev, "watchdog timeout\n");
1651 
1652 		IoQueueWorkItem(sc->ndis_resetitem,
1653 		    (io_workitem_func)ndis_resettask_wrap,
1654 		    WORKQUEUE_CRITICAL, sc);
1655 		IoQueueWorkItem(sc->ndis_startitem,
1656 		    (io_workitem_func)ndis_starttask_wrap,
1657 		    WORKQUEUE_CRITICAL, sc->ifp);
1658 	}
1659 
1660 	callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
1661 }
1662 
1663 static void
ndis_ticktask(d,xsc)1664 ndis_ticktask(d, xsc)
1665 	device_object		*d;
1666 	void			*xsc;
1667 {
1668 	struct ndis_softc	*sc;
1669 	struct ieee80211com	*ic;
1670 	struct ieee80211vap	*vap;
1671 	ndis_checkforhang_handler hangfunc;
1672 	uint8_t			rval;
1673 
1674 	sc = xsc;
1675 	ic = sc->ifp->if_l2com;
1676 	vap = TAILQ_FIRST(&ic->ic_vaps);
1677 
1678 	NDIS_LOCK(sc);
1679 	if (!NDIS_INITIALIZED(sc)) {
1680 		NDIS_UNLOCK(sc);
1681 		return;
1682 	}
1683 	NDIS_UNLOCK(sc);
1684 
1685 	hangfunc = sc->ndis_chars->nmc_checkhang_func;
1686 
1687 	if (hangfunc != NULL) {
1688 		rval = MSCALL1(hangfunc,
1689 		    sc->ndis_block->nmb_miniportadapterctx);
1690 		if (rval == TRUE) {
1691 			ndis_reset_nic(sc);
1692 			return;
1693 		}
1694 	}
1695 
1696 	NDIS_LOCK(sc);
1697 	if (sc->ndis_link == 0 &&
1698 	    sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) {
1699 		sc->ndis_link = 1;
1700 		if ((sc->ndis_80211 != 0) && (vap != NULL)) {
1701 			NDIS_UNLOCK(sc);
1702 			ndis_getstate_80211(sc);
1703 			ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
1704 			NDIS_LOCK(sc);
1705 			if_link_state_change(vap->iv_ifp, LINK_STATE_UP);
1706 		} else
1707 			if_link_state_change(sc->ifp, LINK_STATE_UP);
1708 	}
1709 
1710 	if (sc->ndis_link == 1 &&
1711 	    sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
1712 		sc->ndis_link = 0;
1713 		if ((sc->ndis_80211 != 0) && (vap != NULL)) {
1714 			NDIS_UNLOCK(sc);
1715 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1716 			NDIS_LOCK(sc);
1717 			if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN);
1718 		} else
1719 			if_link_state_change(sc->ifp, LINK_STATE_DOWN);
1720 	}
1721 
1722 	NDIS_UNLOCK(sc);
1723 }
1724 
1725 static void
ndis_map_sclist(arg,segs,nseg,mapsize,error)1726 ndis_map_sclist(arg, segs, nseg, mapsize, error)
1727 	void			*arg;
1728 	bus_dma_segment_t	*segs;
1729 	int			nseg;
1730 	bus_size_t		mapsize;
1731 	int			error;
1732 
1733 {
1734 	struct ndis_sc_list	*sclist;
1735 	int			i;
1736 
1737 	if (error || arg == NULL)
1738 		return;
1739 
1740 	sclist = arg;
1741 
1742 	sclist->nsl_frags = nseg;
1743 
1744 	for (i = 0; i < nseg; i++) {
1745 		sclist->nsl_elements[i].nse_addr.np_quad = segs[i].ds_addr;
1746 		sclist->nsl_elements[i].nse_len = segs[i].ds_len;
1747 	}
1748 }
1749 
1750 static int
ndis_raw_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params)1751 ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1752 	const struct ieee80211_bpf_params *params)
1753 {
1754 	/* no support; just discard */
1755 	m_freem(m);
1756 	ieee80211_free_node(ni);
1757 	return (0);
1758 }
1759 
1760 static void
ndis_update_mcast(struct ifnet * ifp)1761 ndis_update_mcast(struct ifnet *ifp)
1762 {
1763        struct ndis_softc       *sc = ifp->if_softc;
1764 
1765        ndis_setmulti(sc);
1766 }
1767 
1768 static void
ndis_update_promisc(struct ifnet * ifp)1769 ndis_update_promisc(struct ifnet *ifp)
1770 {
1771        /* not supported */
1772 }
1773 
1774 static void
ndis_starttask(d,arg)1775 ndis_starttask(d, arg)
1776 	device_object		*d;
1777 	void			*arg;
1778 {
1779 	struct ifnet		*ifp;
1780 
1781 	ifp = arg;
1782 
1783 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1784 		ndis_start(ifp);
1785 }
1786 
1787 /*
1788  * Main transmit routine. To make NDIS drivers happy, we need to
1789  * transform mbuf chains into NDIS packets and feed them to the
1790  * send packet routines. Most drivers allow you to send several
1791  * packets at once (up to the maxpkts limit). Unfortunately, rather
1792  * that accepting them in the form of a linked list, they expect
1793  * a contiguous array of pointers to packets.
1794  *
1795  * For those drivers which use the NDIS scatter/gather DMA mechanism,
1796  * we need to perform busdma work here. Those that use map registers
1797  * will do the mapping themselves on a buffer by buffer basis.
1798  */
1799 static void
ndis_start(ifp)1800 ndis_start(ifp)
1801 	struct ifnet		*ifp;
1802 {
1803 	struct ndis_softc	*sc;
1804 	struct mbuf		*m = NULL;
1805 	ndis_packet		**p0 = NULL, *p = NULL;
1806 	ndis_tcpip_csum		*csum;
1807 	int			pcnt = 0, status;
1808 
1809 	sc = ifp->if_softc;
1810 
1811 	NDIS_LOCK(sc);
1812 	if (!sc->ndis_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1813 		NDIS_UNLOCK(sc);
1814 		return;
1815 	}
1816 
1817 	p0 = &sc->ndis_txarray[sc->ndis_txidx];
1818 
1819 	while(sc->ndis_txpending) {
1820 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1821 		if (m == NULL)
1822 			break;
1823 
1824 		NdisAllocatePacket(&status,
1825 		    &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool);
1826 
1827 		if (status != NDIS_STATUS_SUCCESS)
1828 			break;
1829 
1830 		if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) {
1831 			IFQ_DRV_PREPEND(&ifp->if_snd, m);
1832 			NDIS_UNLOCK(sc);
1833 			return;
1834 		}
1835 
1836 		/*
1837 		 * Save pointer to original mbuf
1838 		 * so we can free it later.
1839 		 */
1840 
1841 		p = sc->ndis_txarray[sc->ndis_txidx];
1842 		p->np_txidx = sc->ndis_txidx;
1843 		p->np_m0 = m;
1844 		p->np_oob.npo_status = NDIS_STATUS_PENDING;
1845 
1846 		/*
1847 		 * Do scatter/gather processing, if driver requested it.
1848 		 */
1849 		if (sc->ndis_sc) {
1850 			bus_dmamap_load_mbuf(sc->ndis_ttag,
1851 			    sc->ndis_tmaps[sc->ndis_txidx], m,
1852 			    ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT);
1853 			bus_dmamap_sync(sc->ndis_ttag,
1854 			    sc->ndis_tmaps[sc->ndis_txidx],
1855 			    BUS_DMASYNC_PREREAD);
1856 			p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist;
1857 		}
1858 
1859 		/* Handle checksum offload. */
1860 
1861 		if (ifp->if_capenable & IFCAP_TXCSUM &&
1862 		    m->m_pkthdr.csum_flags) {
1863 			csum = (ndis_tcpip_csum *)
1864 				&p->np_ext.npe_info[ndis_tcpipcsum_info];
1865 			csum->u.ntc_txflags = NDIS_TXCSUM_DO_IPV4;
1866 			if (m->m_pkthdr.csum_flags & CSUM_IP)
1867 				csum->u.ntc_txflags |= NDIS_TXCSUM_DO_IP;
1868 			if (m->m_pkthdr.csum_flags & CSUM_TCP)
1869 				csum->u.ntc_txflags |= NDIS_TXCSUM_DO_TCP;
1870 			if (m->m_pkthdr.csum_flags & CSUM_UDP)
1871 				csum->u.ntc_txflags |= NDIS_TXCSUM_DO_UDP;
1872 			p->np_private.npp_flags = NDIS_PROTOCOL_ID_TCP_IP;
1873 		}
1874 
1875 		NDIS_INC(sc);
1876 		sc->ndis_txpending--;
1877 
1878 		pcnt++;
1879 
1880 		/*
1881 		 * If there's a BPF listener, bounce a copy of this frame
1882 		 * to him.
1883 		 */
1884 		if (!sc->ndis_80211)	/* XXX handle 80211 */
1885 			BPF_MTAP(ifp, m);
1886 
1887 		/*
1888 		 * The array that p0 points to must appear contiguous,
1889 		 * so we must not wrap past the end of sc->ndis_txarray[].
1890 		 * If it looks like we're about to wrap, break out here
1891 		 * so the this batch of packets can be transmitted, then
1892 		 * wait for txeof to ask us to send the rest.
1893 		 */
1894 		if (sc->ndis_txidx == 0)
1895 			break;
1896 	}
1897 
1898 	if (pcnt == 0) {
1899 		NDIS_UNLOCK(sc);
1900 		return;
1901 	}
1902 
1903 	if (sc->ndis_txpending == 0)
1904 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1905 
1906 	/*
1907 	 * Set a timeout in case the chip goes out to lunch.
1908 	 */
1909 	sc->ndis_tx_timer = 5;
1910 
1911 	NDIS_UNLOCK(sc);
1912 
1913 	/*
1914 	 * According to NDIS documentation, if a driver exports
1915 	 * a MiniportSendPackets() routine, we prefer that over
1916 	 * a MiniportSend() routine (which sends just a single
1917 	 * packet).
1918 	 */
1919 	if (sc->ndis_chars->nmc_sendmulti_func != NULL)
1920 		ndis_send_packets(sc, p0, pcnt);
1921 	else
1922 		ndis_send_packet(sc, p);
1923 
1924 	return;
1925 }
1926 
1927 static void
ndis_init(xsc)1928 ndis_init(xsc)
1929 	void			*xsc;
1930 {
1931 	struct ndis_softc	*sc = xsc;
1932 	struct ifnet		*ifp = sc->ifp;
1933 	struct ieee80211com	*ic = ifp->if_l2com;
1934 	int			i, len, error;
1935 
1936 	/*
1937 	 * Avoid reintializing the link unnecessarily.
1938 	 * This should be dealt with in a better way by
1939 	 * fixing the upper layer modules so they don't
1940 	 * call ifp->if_init() quite as often.
1941 	 */
1942 	if (sc->ndis_link)
1943 		return;
1944 
1945 	/*
1946 	 * Cancel pending I/O and free all RX/TX buffers.
1947 	 */
1948 	ndis_stop(sc);
1949 
1950 	if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0)) {
1951 		error = ndis_init_nic(sc);
1952 		if (error != 0) {
1953 			device_printf(sc->ndis_dev,
1954 			    "failed to initialize the device: %d\n", error);
1955 			return;
1956 		}
1957 	}
1958 
1959 	/* Init our MAC address */
1960 
1961 	/* Program the packet filter */
1962 
1963 	sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
1964 
1965 	if (ifp->if_flags & IFF_BROADCAST)
1966 		sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
1967 
1968 	if (ifp->if_flags & IFF_PROMISC)
1969 		sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
1970 
1971 	len = sizeof(sc->ndis_filter);
1972 
1973 	error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
1974 	    &sc->ndis_filter, &len);
1975 
1976 	if (error)
1977 		device_printf(sc->ndis_dev, "set filter failed: %d\n", error);
1978 
1979 	/*
1980 	 * Set lookahead.
1981  	 */
1982 	i = ifp->if_mtu;
1983 	len = sizeof(i);
1984 	ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len);
1985 
1986 	/*
1987 	 * Program the multicast filter, if necessary.
1988 	 */
1989 	ndis_setmulti(sc);
1990 
1991 	/* Setup task offload. */
1992 	ndis_set_offload(sc);
1993 
1994 	NDIS_LOCK(sc);
1995 
1996 	sc->ndis_txidx = 0;
1997 	sc->ndis_txpending = sc->ndis_maxpkts;
1998 	sc->ndis_link = 0;
1999 
2000 	if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN);
2001 
2002 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2003 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2004 	sc->ndis_tx_timer = 0;
2005 
2006 	/*
2007 	 * Some drivers don't set this value. The NDIS spec says
2008 	 * the default checkforhang timeout is "approximately 2
2009 	 * seconds." We use 3 seconds, because it seems for some
2010 	 * drivers, exactly 2 seconds is too fast.
2011 	 */
2012 	if (sc->ndis_block->nmb_checkforhangsecs == 0)
2013 		sc->ndis_block->nmb_checkforhangsecs = 3;
2014 
2015 	sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
2016 	callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
2017 	NDIS_UNLOCK(sc);
2018 
2019 	/* XXX force handling */
2020 	if (sc->ndis_80211)
2021 		ieee80211_start_all(ic);	/* start all vap's */
2022 }
2023 
2024 /*
2025  * Set media options.
2026  */
2027 static int
ndis_ifmedia_upd(ifp)2028 ndis_ifmedia_upd(ifp)
2029 	struct ifnet		*ifp;
2030 {
2031 	struct ndis_softc		*sc;
2032 
2033 	sc = ifp->if_softc;
2034 
2035 	if (NDIS_INITIALIZED(sc))
2036 		ndis_init(sc);
2037 
2038 	return (0);
2039 }
2040 
2041 /*
2042  * Report current media status.
2043  */
2044 static void
ndis_ifmedia_sts(ifp,ifmr)2045 ndis_ifmedia_sts(ifp, ifmr)
2046 	struct ifnet		*ifp;
2047 	struct ifmediareq	*ifmr;
2048 {
2049 	struct ndis_softc	*sc;
2050 	uint32_t		media_info;
2051 	ndis_media_state	linkstate;
2052 	int			len;
2053 
2054 	ifmr->ifm_status = IFM_AVALID;
2055 	ifmr->ifm_active = IFM_ETHER;
2056 	sc = ifp->if_softc;
2057 
2058 	if (!NDIS_INITIALIZED(sc))
2059 		return;
2060 
2061 	len = sizeof(linkstate);
2062 	ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
2063 	    (void *)&linkstate, &len);
2064 
2065 	len = sizeof(media_info);
2066 	ndis_get_info(sc, OID_GEN_LINK_SPEED,
2067 	    (void *)&media_info, &len);
2068 
2069 	if (linkstate == nmc_connected)
2070 		ifmr->ifm_status |= IFM_ACTIVE;
2071 
2072 	switch (media_info) {
2073 	case 100000:
2074 		ifmr->ifm_active |= IFM_10_T;
2075 		break;
2076 	case 1000000:
2077 		ifmr->ifm_active |= IFM_100_TX;
2078 		break;
2079 	case 10000000:
2080 		ifmr->ifm_active |= IFM_1000_T;
2081 		break;
2082 	default:
2083 		device_printf(sc->ndis_dev, "unknown speed: %d\n", media_info);
2084 		break;
2085 	}
2086 }
2087 
2088 static int
ndis_set_cipher(sc,cipher)2089 ndis_set_cipher(sc, cipher)
2090 	struct ndis_softc	*sc;
2091 	int			cipher;
2092 {
2093 	struct ieee80211com	*ic;
2094 	int			rval = 0, len;
2095 	uint32_t		arg, save;
2096 
2097 	ic = sc->ifp->if_l2com;
2098 
2099 	len = sizeof(arg);
2100 
2101 	if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) {
2102 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP))
2103 			return (ENOTSUP);
2104 		arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
2105 	}
2106 
2107 	if (cipher == WPA_CSE_TKIP) {
2108 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP))
2109 			return (ENOTSUP);
2110 		arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
2111 	}
2112 
2113 	if (cipher == WPA_CSE_CCMP) {
2114 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM))
2115 			return (ENOTSUP);
2116 		arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
2117 	}
2118 
2119 	DPRINTF(("Setting cipher to %d\n", arg));
2120 	save = arg;
2121 	rval = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2122 
2123 	if (rval)
2124 		return (rval);
2125 
2126 	/* Check that the cipher was set correctly. */
2127 
2128 	len = sizeof(save);
2129 	rval = ndis_get_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2130 
2131 	if (rval != 0 || arg != save)
2132 		return (ENODEV);
2133 
2134 	return (0);
2135 }
2136 
2137 /*
2138  * WPA is hairy to set up. Do the work in a separate routine
2139  * so we don't clutter the setstate function too much.
2140  * Important yet undocumented fact: first we have to set the
2141  * authentication mode, _then_ we enable the ciphers. If one
2142  * of the WPA authentication modes isn't enabled, the driver
2143  * might not permit the TKIP or AES ciphers to be selected.
2144  */
2145 static int
ndis_set_wpa(sc,ie,ielen)2146 ndis_set_wpa(sc, ie, ielen)
2147 	struct ndis_softc	*sc;
2148 	void			*ie;
2149 	int			ielen;
2150 {
2151 	struct ieee80211_ie_wpa	*w;
2152 	struct ndis_ie		*n;
2153 	char			*pos;
2154 	uint32_t		arg;
2155 	int			i;
2156 
2157 	/*
2158 	 * Apparently, the only way for us to know what ciphers
2159 	 * and key management/authentication mode to use is for
2160 	 * us to inspect the optional information element (IE)
2161 	 * stored in the 802.11 state machine. This IE should be
2162 	 * supplied by the WPA supplicant.
2163 	 */
2164 
2165 	w = (struct ieee80211_ie_wpa *)ie;
2166 
2167 	/* Check for the right kind of IE. */
2168 	if (w->wpa_id != IEEE80211_ELEMID_VENDOR) {
2169 		DPRINTF(("Incorrect IE type %d\n", w->wpa_id));
2170 		return (EINVAL);
2171 	}
2172 
2173 	/* Skip over the ucast cipher OIDs. */
2174 	pos = (char *)&w->wpa_uciphers[0];
2175 	pos += w->wpa_uciphercnt * sizeof(struct ndis_ie);
2176 
2177 	/* Skip over the authmode count. */
2178 	pos += sizeof(u_int16_t);
2179 
2180 	/*
2181 	 * Check for the authentication modes. I'm
2182 	 * pretty sure there's only supposed to be one.
2183 	 */
2184 
2185 	n = (struct ndis_ie *)pos;
2186 	if (n->ni_val == WPA_ASE_NONE)
2187 		arg = NDIS_80211_AUTHMODE_WPANONE;
2188 
2189 	if (n->ni_val == WPA_ASE_8021X_UNSPEC)
2190 		arg = NDIS_80211_AUTHMODE_WPA;
2191 
2192 	if (n->ni_val == WPA_ASE_8021X_PSK)
2193 		arg = NDIS_80211_AUTHMODE_WPAPSK;
2194 
2195 	DPRINTF(("Setting WPA auth mode to %d\n", arg));
2196 	i = sizeof(arg);
2197 	if (ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i))
2198 		return (ENOTSUP);
2199 	i = sizeof(arg);
2200 	ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
2201 
2202 	/* Now configure the desired ciphers. */
2203 
2204 	/* First, set up the multicast group cipher. */
2205 	n = (struct ndis_ie *)&w->wpa_mcipher[0];
2206 
2207 	if (ndis_set_cipher(sc, n->ni_val))
2208 		return (ENOTSUP);
2209 
2210 	/* Now start looking around for the unicast ciphers. */
2211 	pos = (char *)&w->wpa_uciphers[0];
2212 	n = (struct ndis_ie *)pos;
2213 
2214 	for (i = 0; i < w->wpa_uciphercnt; i++) {
2215 		if (ndis_set_cipher(sc, n->ni_val))
2216 			return (ENOTSUP);
2217 		n++;
2218 	}
2219 
2220 	return (0);
2221 }
2222 
2223 static void
ndis_media_status(struct ifnet * ifp,struct ifmediareq * imr)2224 ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
2225 {
2226 	struct ieee80211vap *vap = ifp->if_softc;
2227 	struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc;
2228 	uint32_t txrate;
2229 	int len;
2230 
2231 	if (!NDIS_INITIALIZED(sc))
2232 		return;
2233 
2234 	len = sizeof(txrate);
2235 	if (ndis_get_info(sc, OID_GEN_LINK_SPEED, &txrate, &len) == 0)
2236 		vap->iv_bss->ni_txrate = txrate / 5000;
2237 	ieee80211_media_status(ifp, imr);
2238 }
2239 
2240 static void
ndis_setstate_80211(sc)2241 ndis_setstate_80211(sc)
2242 	struct ndis_softc	*sc;
2243 {
2244 	struct ieee80211com	*ic;
2245 	struct ieee80211vap	*vap;
2246 	ndis_80211_macaddr	bssid;
2247 	ndis_80211_config	config;
2248 	int			rval = 0, len;
2249 	uint32_t		arg;
2250 	struct ifnet		*ifp;
2251 
2252 	ifp = sc->ifp;
2253 	ic = ifp->if_l2com;
2254 	vap = TAILQ_FIRST(&ic->ic_vaps);
2255 
2256 	if (!NDIS_INITIALIZED(sc)) {
2257 		DPRINTF(("%s: NDIS not initialized\n", __func__));
2258 		return;
2259 	}
2260 
2261 	/* Disassociate and turn off radio. */
2262 	len = sizeof(arg);
2263 	arg = 1;
2264 	ndis_set_info(sc, OID_802_11_DISASSOCIATE, &arg, &len);
2265 
2266 	/* Set network infrastructure mode. */
2267 
2268 	len = sizeof(arg);
2269 	if (ic->ic_opmode == IEEE80211_M_IBSS)
2270 		arg = NDIS_80211_NET_INFRA_IBSS;
2271 	else
2272 		arg = NDIS_80211_NET_INFRA_BSS;
2273 
2274 	rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2275 
2276 	if (rval)
2277 		device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2278 
2279 	/* Set power management */
2280 	len = sizeof(arg);
2281 	if (vap->iv_flags & IEEE80211_F_PMGTON)
2282 		arg = NDIS_80211_POWERMODE_FAST_PSP;
2283 	else
2284 		arg = NDIS_80211_POWERMODE_CAM;
2285 	ndis_set_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2286 
2287 	/* Set TX power */
2288 	if ((ic->ic_caps & IEEE80211_C_TXPMGT) &&
2289 	    ic->ic_txpowlimit < (sizeof(dBm2mW) / sizeof(dBm2mW[0]))) {
2290 		arg = dBm2mW[ic->ic_txpowlimit];
2291 		len = sizeof(arg);
2292 		ndis_set_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2293 	}
2294 
2295 	/*
2296 	 * Default encryption mode to off, authentication
2297 	 * to open and privacy to 'accept everything.'
2298 	 */
2299 	len = sizeof(arg);
2300 	arg = NDIS_80211_WEPSTAT_DISABLED;
2301 	ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2302 
2303 	len = sizeof(arg);
2304 	arg = NDIS_80211_AUTHMODE_OPEN;
2305 	ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2306 
2307 	/*
2308 	 * Note that OID_802_11_PRIVACY_FILTER is optional:
2309 	 * not all drivers implement it.
2310 	 */
2311 	len = sizeof(arg);
2312 	arg = NDIS_80211_PRIVFILT_8021XWEP;
2313 	ndis_set_info(sc, OID_802_11_PRIVACY_FILTER, &arg, &len);
2314 
2315 	len = sizeof(config);
2316 	bzero((char *)&config, len);
2317 	config.nc_length = len;
2318 	config.nc_fhconfig.ncf_length = sizeof(ndis_80211_config_fh);
2319 	rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len);
2320 
2321 	/*
2322 	 * Some drivers expect us to initialize these values, so
2323 	 * provide some defaults.
2324 	 */
2325 
2326 	if (config.nc_beaconperiod == 0)
2327 		config.nc_beaconperiod = 100;
2328 	if (config.nc_atimwin == 0)
2329 		config.nc_atimwin = 100;
2330 	if (config.nc_fhconfig.ncf_dwelltime == 0)
2331 		config.nc_fhconfig.ncf_dwelltime = 200;
2332 	if (rval == 0 && ic->ic_bsschan != IEEE80211_CHAN_ANYC) {
2333 		int chan, chanflag;
2334 
2335 		chan = ieee80211_chan2ieee(ic, ic->ic_bsschan);
2336 		chanflag = config.nc_dsconfig > 2500000 ? IEEE80211_CHAN_2GHZ :
2337 		    IEEE80211_CHAN_5GHZ;
2338 		if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) {
2339 			config.nc_dsconfig =
2340 				ic->ic_bsschan->ic_freq * 1000;
2341 			len = sizeof(config);
2342 			config.nc_length = len;
2343 			config.nc_fhconfig.ncf_length =
2344 			    sizeof(ndis_80211_config_fh);
2345 			DPRINTF(("Setting channel to %ukHz\n", config.nc_dsconfig));
2346 			rval = ndis_set_info(sc, OID_802_11_CONFIGURATION,
2347 			    &config, &len);
2348 			if (rval)
2349 				device_printf(sc->ndis_dev, "couldn't change "
2350 				    "DS config to %ukHz: %d\n",
2351 				    config.nc_dsconfig, rval);
2352 		}
2353 	} else if (rval)
2354 		device_printf(sc->ndis_dev, "couldn't retrieve "
2355 		    "channel info: %d\n", rval);
2356 
2357 	/* Set the BSSID to our value so the driver doesn't associate */
2358 	len = IEEE80211_ADDR_LEN;
2359 	bcopy(IF_LLADDR(ifp), bssid, len);
2360 	DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
2361 	rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2362 	if (rval)
2363 		device_printf(sc->ndis_dev,
2364 		    "setting BSSID failed: %d\n", rval);
2365 }
2366 
2367 static void
ndis_auth_and_assoc(sc,vap)2368 ndis_auth_and_assoc(sc, vap)
2369 	struct ndis_softc	*sc;
2370 	struct ieee80211vap	*vap;
2371 {
2372 	struct ieee80211com	*ic;
2373 	struct ieee80211_node	*ni;
2374 	ndis_80211_ssid		ssid;
2375 	ndis_80211_macaddr	bssid;
2376 	ndis_80211_wep		wep;
2377 	int			i, rval = 0, len, error;
2378 	uint32_t		arg;
2379 	struct ifnet		*ifp;
2380 
2381 	ifp = sc->ifp;
2382 	ic = ifp->if_l2com;
2383 	ni = vap->iv_bss;
2384 
2385 	if (!NDIS_INITIALIZED(sc)) {
2386 		DPRINTF(("%s: NDIS not initialized\n", __func__));
2387 		return;
2388 	}
2389 
2390 	/* Initial setup */
2391 	ndis_setstate_80211(sc);
2392 
2393 	/* Set network infrastructure mode. */
2394 
2395 	len = sizeof(arg);
2396 	if (vap->iv_opmode == IEEE80211_M_IBSS)
2397 		arg = NDIS_80211_NET_INFRA_IBSS;
2398 	else
2399 		arg = NDIS_80211_NET_INFRA_BSS;
2400 
2401 	rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2402 
2403 	if (rval)
2404 		device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2405 
2406 	/* Set RTS threshold */
2407 
2408 	len = sizeof(arg);
2409 	arg = vap->iv_rtsthreshold;
2410 	ndis_set_info(sc, OID_802_11_RTS_THRESHOLD, &arg, &len);
2411 
2412 	/* Set fragmentation threshold */
2413 
2414 	len = sizeof(arg);
2415 	arg = vap->iv_fragthreshold;
2416 	ndis_set_info(sc, OID_802_11_FRAGMENTATION_THRESHOLD, &arg, &len);
2417 
2418 	/* Set WEP */
2419 
2420 	if (vap->iv_flags & IEEE80211_F_PRIVACY &&
2421 	    !(vap->iv_flags & IEEE80211_F_WPA)) {
2422 		int keys_set = 0;
2423 
2424 		if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
2425 			len = sizeof(arg);
2426 			arg = NDIS_80211_AUTHMODE_SHARED;
2427 			DPRINTF(("Setting shared auth\n"));
2428 			ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE,
2429 			    &arg, &len);
2430 		}
2431 		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2432 			if (vap->iv_nw_keys[i].wk_keylen) {
2433 				if (vap->iv_nw_keys[i].wk_cipher->ic_cipher !=
2434 				    IEEE80211_CIPHER_WEP)
2435 					continue;
2436 				bzero((char *)&wep, sizeof(wep));
2437 				wep.nw_keylen = vap->iv_nw_keys[i].wk_keylen;
2438 
2439 				/*
2440 				 * 5, 13 and 16 are the only valid
2441 				 * key lengths. Anything in between
2442 				 * will be zero padded out to the
2443 				 * next highest boundary.
2444 				 */
2445 				if (vap->iv_nw_keys[i].wk_keylen < 5)
2446 					wep.nw_keylen = 5;
2447 				else if (vap->iv_nw_keys[i].wk_keylen > 5 &&
2448 				     vap->iv_nw_keys[i].wk_keylen < 13)
2449 					wep.nw_keylen = 13;
2450 				else if (vap->iv_nw_keys[i].wk_keylen > 13 &&
2451 				     vap->iv_nw_keys[i].wk_keylen < 16)
2452 					wep.nw_keylen = 16;
2453 
2454 				wep.nw_keyidx = i;
2455 				wep.nw_length = (sizeof(uint32_t) * 3)
2456 				    + wep.nw_keylen;
2457 				if (i == vap->iv_def_txkey)
2458 					wep.nw_keyidx |= NDIS_80211_WEPKEY_TX;
2459 				bcopy(vap->iv_nw_keys[i].wk_key,
2460 				    wep.nw_keydata, wep.nw_length);
2461 				len = sizeof(wep);
2462 				DPRINTF(("Setting WEP key %d\n", i));
2463 				rval = ndis_set_info(sc,
2464 				    OID_802_11_ADD_WEP, &wep, &len);
2465 				if (rval)
2466 					device_printf(sc->ndis_dev,
2467 					    "set wepkey failed: %d\n", rval);
2468 				keys_set++;
2469 			}
2470 		}
2471 		if (keys_set) {
2472 			DPRINTF(("Setting WEP on\n"));
2473 			arg = NDIS_80211_WEPSTAT_ENABLED;
2474 			len = sizeof(arg);
2475 			rval = ndis_set_info(sc,
2476 			    OID_802_11_WEP_STATUS, &arg, &len);
2477 			if (rval)
2478 				device_printf(sc->ndis_dev,
2479 				    "enable WEP failed: %d\n", rval);
2480 			if (vap->iv_flags & IEEE80211_F_DROPUNENC)
2481 				arg = NDIS_80211_PRIVFILT_8021XWEP;
2482 			else
2483 				arg = NDIS_80211_PRIVFILT_ACCEPTALL;
2484 
2485 			len = sizeof(arg);
2486 			ndis_set_info(sc,
2487 			    OID_802_11_PRIVACY_FILTER, &arg, &len);
2488 		}
2489 	}
2490 
2491 	/* Set up WPA. */
2492 	if ((vap->iv_flags & IEEE80211_F_WPA) &&
2493 	    vap->iv_appie_assocreq != NULL) {
2494 		struct ieee80211_appie *ie = vap->iv_appie_assocreq;
2495 		error = ndis_set_wpa(sc, ie->ie_data, ie->ie_len);
2496 		if (error != 0)
2497 			device_printf(sc->ndis_dev, "WPA setup failed\n");
2498 	}
2499 
2500 #ifdef notyet
2501 	/* Set network type. */
2502 
2503 	arg = 0;
2504 
2505 	switch (vap->iv_curmode) {
2506 	case IEEE80211_MODE_11A:
2507 		arg = NDIS_80211_NETTYPE_11OFDM5;
2508 		break;
2509 	case IEEE80211_MODE_11B:
2510 		arg = NDIS_80211_NETTYPE_11DS;
2511 		break;
2512 	case IEEE80211_MODE_11G:
2513 		arg = NDIS_80211_NETTYPE_11OFDM24;
2514 		break;
2515 	default:
2516 		device_printf(sc->ndis_dev, "unknown mode: %d\n",
2517 		    vap->iv_curmode);
2518 	}
2519 
2520 	if (arg) {
2521 		DPRINTF(("Setting network type to %d\n", arg));
2522 		len = sizeof(arg);
2523 		rval = ndis_set_info(sc, OID_802_11_NETWORK_TYPE_IN_USE,
2524 		    &arg, &len);
2525 		if (rval)
2526 			device_printf(sc->ndis_dev,
2527 			    "set nettype failed: %d\n", rval);
2528 	}
2529 #endif
2530 
2531 	/*
2532 	 * If the user selected a specific BSSID, try
2533 	 * to use that one. This is useful in the case where
2534 	 * there are several APs in range with the same network
2535 	 * name. To delete the BSSID, we use the broadcast
2536 	 * address as the BSSID.
2537 	 * Note that some drivers seem to allow setting a BSSID
2538 	 * in ad-hoc mode, which has the effect of forcing the
2539 	 * NIC to create an ad-hoc cell with a specific BSSID,
2540 	 * instead of a randomly chosen one. However, the net80211
2541 	 * code makes the assumtion that the BSSID setting is invalid
2542 	 * when you're in ad-hoc mode, so we don't allow that here.
2543 	 */
2544 
2545 	len = IEEE80211_ADDR_LEN;
2546 	if (vap->iv_flags & IEEE80211_F_DESBSSID &&
2547 	    vap->iv_opmode != IEEE80211_M_IBSS)
2548 		bcopy(ni->ni_bssid, bssid, len);
2549 	else
2550 		bcopy(ifp->if_broadcastaddr, bssid, len);
2551 
2552 	DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
2553 	rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2554 	if (rval)
2555 		device_printf(sc->ndis_dev,
2556 		    "setting BSSID failed: %d\n", rval);
2557 
2558 	/* Set SSID -- always do this last. */
2559 
2560 #ifdef NDIS_DEBUG
2561 	if (ndis_debug > 0) {
2562 		printf("Setting ESSID to ");
2563 		ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2564 		printf("\n");
2565 	}
2566 #endif
2567 
2568 	len = sizeof(ssid);
2569 	bzero((char *)&ssid, len);
2570 	ssid.ns_ssidlen = ni->ni_esslen;
2571 	if (ssid.ns_ssidlen == 0) {
2572 		ssid.ns_ssidlen = 1;
2573 	} else
2574 		bcopy(ni->ni_essid, ssid.ns_ssid, ssid.ns_ssidlen);
2575 
2576 	rval = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
2577 
2578 	if (rval)
2579 		device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval);
2580 
2581 	return;
2582 }
2583 
2584 static int
ndis_get_bssid_list(sc,bl)2585 ndis_get_bssid_list(sc, bl)
2586 	struct ndis_softc	*sc;
2587 	ndis_80211_bssid_list_ex	**bl;
2588 {
2589 	int	len, error;
2590 
2591 	len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16);
2592 	*bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2593 	if (*bl == NULL)
2594 		return (ENOMEM);
2595 
2596 	error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2597 	if (error == ENOSPC) {
2598 		free(*bl, M_DEVBUF);
2599 		*bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2600 		if (*bl == NULL)
2601 			return (ENOMEM);
2602 
2603 		error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2604 	}
2605 	if (error) {
2606 		DPRINTF(("%s: failed to read\n", __func__));
2607 		free(*bl, M_DEVBUF);
2608 		return (error);
2609 	}
2610 
2611 	return (0);
2612 }
2613 
2614 static int
ndis_get_assoc(sc,assoc)2615 ndis_get_assoc(sc, assoc)
2616 	struct ndis_softc	*sc;
2617 	ndis_wlan_bssid_ex	**assoc;
2618 {
2619 	struct ifnet *ifp = sc->ifp;
2620 	struct ieee80211com *ic = ifp->if_l2com;
2621 	struct ieee80211vap     *vap;
2622 	struct ieee80211_node   *ni;
2623 	ndis_80211_bssid_list_ex	*bl;
2624 	ndis_wlan_bssid_ex	*bs;
2625 	ndis_80211_macaddr	bssid;
2626 	int			i, len, error;
2627 
2628 	if (!sc->ndis_link)
2629 		return (ENOENT);
2630 
2631 	len = sizeof(bssid);
2632 	error = ndis_get_info(sc, OID_802_11_BSSID, &bssid, &len);
2633 	if (error) {
2634 		device_printf(sc->ndis_dev, "failed to get bssid\n");
2635 		return (ENOENT);
2636 	}
2637 
2638 	vap = TAILQ_FIRST(&ic->ic_vaps);
2639 	ni = vap->iv_bss;
2640 
2641 	error = ndis_get_bssid_list(sc, &bl);
2642 	if (error)
2643 		return (error);
2644 
2645 	bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0];
2646 	for (i = 0; i < bl->nblx_items; i++) {
2647 		if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) {
2648 			*assoc = malloc(bs->nwbx_len, M_TEMP, M_NOWAIT);
2649 			if (*assoc == NULL) {
2650 				free(bl, M_TEMP);
2651 				return (ENOMEM);
2652 			}
2653 			bcopy((char *)bs, (char *)*assoc, bs->nwbx_len);
2654 			free(bl, M_TEMP);
2655 			if (ic->ic_opmode == IEEE80211_M_STA)
2656 				ni->ni_associd = 1 | 0xc000; /* fake associd */
2657 			return (0);
2658 		}
2659 		bs = (ndis_wlan_bssid_ex *)((char *)bs + bs->nwbx_len);
2660 	}
2661 
2662 	free(bl, M_TEMP);
2663 	return (ENOENT);
2664 }
2665 
2666 static void
ndis_getstate_80211(sc)2667 ndis_getstate_80211(sc)
2668 	struct ndis_softc	*sc;
2669 {
2670 	struct ieee80211com	*ic;
2671 	struct ieee80211vap	*vap;
2672 	struct ieee80211_node	*ni;
2673 	ndis_wlan_bssid_ex	*bs;
2674 	int			rval, len, i = 0;
2675 	int			chanflag;
2676 	uint32_t		arg;
2677 	struct ifnet		*ifp;
2678 
2679 	ifp = sc->ifp;
2680 	ic = ifp->if_l2com;
2681 	vap = TAILQ_FIRST(&ic->ic_vaps);
2682 	ni = vap->iv_bss;
2683 
2684 	if (!NDIS_INITIALIZED(sc))
2685 		return;
2686 
2687 	if ((rval = ndis_get_assoc(sc, &bs)) != 0)
2688 		return;
2689 
2690 	/* We're associated, retrieve info on the current bssid. */
2691 	ic->ic_curmode = ndis_nettype_mode(bs->nwbx_nettype);
2692 	chanflag = ndis_nettype_chan(bs->nwbx_nettype);
2693 	IEEE80211_ADDR_COPY(ni->ni_bssid, bs->nwbx_macaddr);
2694 
2695 	/* Get SSID from current association info. */
2696 	bcopy(bs->nwbx_ssid.ns_ssid, ni->ni_essid,
2697 	    bs->nwbx_ssid.ns_ssidlen);
2698 	ni->ni_esslen = bs->nwbx_ssid.ns_ssidlen;
2699 
2700 	if (ic->ic_caps & IEEE80211_C_PMGT) {
2701 		len = sizeof(arg);
2702 		rval = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2703 
2704 		if (rval)
2705 			device_printf(sc->ndis_dev,
2706 			    "get power mode failed: %d\n", rval);
2707 		if (arg == NDIS_80211_POWERMODE_CAM)
2708 			vap->iv_flags &= ~IEEE80211_F_PMGTON;
2709 		else
2710 			vap->iv_flags |= IEEE80211_F_PMGTON;
2711 	}
2712 
2713 	/* Get TX power */
2714 	if (ic->ic_caps & IEEE80211_C_TXPMGT) {
2715 		len = sizeof(arg);
2716 		ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2717 		for (i = 0; i < (sizeof(dBm2mW) / sizeof(dBm2mW[0])); i++)
2718 			if (dBm2mW[i] >= arg)
2719 				break;
2720 		ic->ic_txpowlimit = i;
2721 	}
2722 
2723 	/*
2724 	 * Use the current association information to reflect
2725 	 * what channel we're on.
2726 	 */
2727 	ic->ic_curchan = ieee80211_find_channel(ic,
2728 	    bs->nwbx_config.nc_dsconfig / 1000, chanflag);
2729 	if (ic->ic_curchan == NULL)
2730 		ic->ic_curchan = &ic->ic_channels[0];
2731 	ni->ni_chan = ic->ic_curchan;
2732 	ic->ic_bsschan = ic->ic_curchan;
2733 
2734 	free(bs, M_TEMP);
2735 
2736 	/*
2737 	 * Determine current authentication mode.
2738 	 */
2739 	len = sizeof(arg);
2740 	rval = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2741 	if (rval)
2742 		device_printf(sc->ndis_dev,
2743 		    "get authmode status failed: %d\n", rval);
2744 	else {
2745 		vap->iv_flags &= ~IEEE80211_F_WPA;
2746 		switch (arg) {
2747 		case NDIS_80211_AUTHMODE_OPEN:
2748 			ni->ni_authmode = IEEE80211_AUTH_OPEN;
2749 			break;
2750 		case NDIS_80211_AUTHMODE_SHARED:
2751 			ni->ni_authmode = IEEE80211_AUTH_SHARED;
2752 			break;
2753 		case NDIS_80211_AUTHMODE_AUTO:
2754 			ni->ni_authmode = IEEE80211_AUTH_AUTO;
2755 			break;
2756 		case NDIS_80211_AUTHMODE_WPA:
2757 		case NDIS_80211_AUTHMODE_WPAPSK:
2758 		case NDIS_80211_AUTHMODE_WPANONE:
2759 			ni->ni_authmode = IEEE80211_AUTH_WPA;
2760 			vap->iv_flags |= IEEE80211_F_WPA1;
2761 			break;
2762 		case NDIS_80211_AUTHMODE_WPA2:
2763 		case NDIS_80211_AUTHMODE_WPA2PSK:
2764 			ni->ni_authmode = IEEE80211_AUTH_WPA;
2765 			vap->iv_flags |= IEEE80211_F_WPA2;
2766 			break;
2767 		default:
2768 			ni->ni_authmode = IEEE80211_AUTH_NONE;
2769 			break;
2770 		}
2771 	}
2772 
2773 	len = sizeof(arg);
2774 	rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len);
2775 
2776 	if (rval)
2777 		device_printf(sc->ndis_dev,
2778 		    "get wep status failed: %d\n", rval);
2779 
2780 	if (arg == NDIS_80211_WEPSTAT_ENABLED)
2781 		vap->iv_flags |= IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC;
2782 	else
2783 		vap->iv_flags &= ~(IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC);
2784 }
2785 
2786 static int
ndis_ioctl(ifp,command,data)2787 ndis_ioctl(ifp, command, data)
2788 	struct ifnet		*ifp;
2789 	u_long			command;
2790 	caddr_t			data;
2791 {
2792 	struct ndis_softc	*sc = ifp->if_softc;
2793 	struct ifreq		*ifr = (struct ifreq *) data;
2794 	int			i, error = 0;
2795 
2796 	/*NDIS_LOCK(sc);*/
2797 
2798 	switch (command) {
2799 	case SIOCSIFFLAGS:
2800 		if (ifp->if_flags & IFF_UP) {
2801 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
2802 			    ifp->if_flags & IFF_PROMISC &&
2803 			    !(sc->ndis_if_flags & IFF_PROMISC)) {
2804 				sc->ndis_filter |=
2805 				    NDIS_PACKET_TYPE_PROMISCUOUS;
2806 				i = sizeof(sc->ndis_filter);
2807 				error = ndis_set_info(sc,
2808 				    OID_GEN_CURRENT_PACKET_FILTER,
2809 				    &sc->ndis_filter, &i);
2810 			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
2811 			    !(ifp->if_flags & IFF_PROMISC) &&
2812 			    sc->ndis_if_flags & IFF_PROMISC) {
2813 				sc->ndis_filter &=
2814 				    ~NDIS_PACKET_TYPE_PROMISCUOUS;
2815 				i = sizeof(sc->ndis_filter);
2816 				error = ndis_set_info(sc,
2817 				    OID_GEN_CURRENT_PACKET_FILTER,
2818 				    &sc->ndis_filter, &i);
2819 			} else
2820 				ndis_init(sc);
2821 		} else {
2822 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2823 				ndis_stop(sc);
2824 		}
2825 		sc->ndis_if_flags = ifp->if_flags;
2826 		error = 0;
2827 		break;
2828 	case SIOCADDMULTI:
2829 	case SIOCDELMULTI:
2830 		ndis_setmulti(sc);
2831 		error = 0;
2832 		break;
2833 	case SIOCGIFMEDIA:
2834 	case SIOCSIFMEDIA:
2835 		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
2836 		break;
2837 	case SIOCSIFCAP:
2838 		ifp->if_capenable = ifr->ifr_reqcap;
2839 		if (ifp->if_capenable & IFCAP_TXCSUM)
2840 			ifp->if_hwassist = sc->ndis_hwassist;
2841 		else
2842 			ifp->if_hwassist = 0;
2843 		ndis_set_offload(sc);
2844 		break;
2845 	default:
2846 		error = ether_ioctl(ifp, command, data);
2847 		break;
2848 	}
2849 
2850 	/*NDIS_UNLOCK(sc);*/
2851 
2852 	return(error);
2853 }
2854 
2855 static int
ndis_ioctl_80211(ifp,command,data)2856 ndis_ioctl_80211(ifp, command, data)
2857 	struct ifnet		*ifp;
2858 	u_long			command;
2859 	caddr_t			data;
2860 {
2861 	struct ndis_softc	*sc = ifp->if_softc;
2862 	struct ieee80211com	*ic = ifp->if_l2com;
2863 	struct ifreq		*ifr = (struct ifreq *) data;
2864 	struct ndis_oid_data	oid;
2865 	struct ndis_evt		evt;
2866 	void			*oidbuf;
2867 	int			error = 0;
2868 
2869 	switch (command) {
2870 	case SIOCSIFFLAGS:
2871 		/*NDIS_LOCK(sc);*/
2872 		if (ifp->if_flags & IFF_UP) {
2873 			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2874 				ndis_init(sc);
2875 		} else {
2876 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2877 				ndis_stop(sc);
2878 		}
2879 		sc->ndis_if_flags = ifp->if_flags;
2880 		error = 0;
2881 		/*NDIS_UNLOCK(sc);*/
2882 		break;
2883 	case SIOCGDRVSPEC:
2884 		if ((error = priv_check(curthread, PRIV_DRIVER)))
2885 			break;
2886 		error =  copyin(ifr->ifr_data, &oid, sizeof(oid));
2887 		if (error)
2888 			break;
2889 		oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2890 		if (oidbuf == NULL) {
2891 			error = ENOMEM;
2892 			break;
2893 		}
2894 		error =  copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2895 		if (error) {
2896 			free(oidbuf, M_TEMP);
2897 			break;
2898 		}
2899 		error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len);
2900 		if (error) {
2901 			free(oidbuf, M_TEMP);
2902 			break;
2903 		}
2904 		error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2905 		if (error) {
2906 			free(oidbuf, M_TEMP);
2907 			break;
2908 		}
2909 		error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
2910 		free(oidbuf, M_TEMP);
2911 		break;
2912 	case SIOCSDRVSPEC:
2913 		if ((error = priv_check(curthread, PRIV_DRIVER)))
2914 			break;
2915 		error =  copyin(ifr->ifr_data, &oid, sizeof(oid));
2916 		if (error)
2917 			break;
2918 		oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2919 		if (oidbuf == NULL) {
2920 			error = ENOMEM;
2921 			break;
2922 		}
2923 		error =  copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2924 		if (error) {
2925 			free(oidbuf, M_TEMP);
2926 			break;
2927 		}
2928 		error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len);
2929 		if (error) {
2930 			free(oidbuf, M_TEMP);
2931 			break;
2932 		}
2933 		error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2934 		if (error) {
2935 			free(oidbuf, M_TEMP);
2936 			break;
2937 		}
2938 		error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
2939 		free(oidbuf, M_TEMP);
2940 		break;
2941 	case SIOCGPRIVATE_0:
2942 		if ((error = priv_check(curthread, PRIV_DRIVER)))
2943 			break;
2944 		NDIS_LOCK(sc);
2945 		if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) {
2946 			error = ENOENT;
2947 			NDIS_UNLOCK(sc);
2948 			break;
2949 		}
2950 		error =  copyin(ifr->ifr_data, &evt, sizeof(evt));
2951 		if (error) {
2952 			NDIS_UNLOCK(sc);
2953 			break;
2954 		}
2955 		if (evt.ne_len < sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2956 			error = ENOSPC;
2957 			NDIS_UNLOCK(sc);
2958 			break;
2959 		}
2960 		error = copyout(&sc->ndis_evt[sc->ndis_evtcidx],
2961 		    ifr->ifr_data, sizeof(uint32_t) * 2);
2962 		if (error) {
2963 			NDIS_UNLOCK(sc);
2964 			break;
2965 		}
2966 		if (sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2967 			error = copyout(sc->ndis_evt[sc->ndis_evtcidx].ne_buf,
2968 			    ifr->ifr_data + (sizeof(uint32_t) * 2),
2969 			    sc->ndis_evt[sc->ndis_evtcidx].ne_len);
2970 			if (error) {
2971 				NDIS_UNLOCK(sc);
2972 				break;
2973 			}
2974 			free(sc->ndis_evt[sc->ndis_evtcidx].ne_buf, M_TEMP);
2975 			sc->ndis_evt[sc->ndis_evtcidx].ne_buf = NULL;
2976 		}
2977 		sc->ndis_evt[sc->ndis_evtcidx].ne_len = 0;
2978 		sc->ndis_evt[sc->ndis_evtcidx].ne_sts = 0;
2979 		NDIS_EVTINC(sc->ndis_evtcidx);
2980 		NDIS_UNLOCK(sc);
2981 		break;
2982 	case SIOCGIFMEDIA:
2983 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
2984 		break;
2985 	case SIOCGIFADDR:
2986 		error = ether_ioctl(ifp, command, data);
2987 		break;
2988 	default:
2989 		error = EINVAL;
2990 		break;
2991 	}
2992 	return (error);
2993 }
2994 
2995 int
ndis_del_key(vap,key)2996 ndis_del_key(vap, key)
2997 	struct ieee80211vap	*vap;
2998 	const struct ieee80211_key *key;
2999 {
3000 	struct ndis_softc	*sc;
3001 	ndis_80211_key		rkey;
3002 	int			len, error = 0;
3003 
3004 	sc = vap->iv_ic->ic_ifp->if_softc;
3005 
3006 	bzero((char *)&rkey, sizeof(rkey));
3007 	len = sizeof(rkey);
3008 
3009 	rkey.nk_len = len;
3010 	rkey.nk_keyidx = key->wk_keyix;
3011 
3012 	bcopy(vap->iv_ifp->if_broadcastaddr,
3013 	    rkey.nk_bssid, IEEE80211_ADDR_LEN);
3014 
3015 	error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len);
3016 
3017 	if (error)
3018 		return (0);
3019 
3020 	return (1);
3021 }
3022 
3023 /*
3024  * In theory this could be called for any key, but we'll
3025  * only use it for WPA TKIP or AES keys. These need to be
3026  * set after initial authentication with the AP.
3027  */
3028 static int
ndis_add_key(vap,key,mac)3029 ndis_add_key(vap, key, mac)
3030 	struct ieee80211vap	*vap;
3031 	const struct ieee80211_key *key;
3032 	const uint8_t		mac[IEEE80211_ADDR_LEN];
3033 {
3034 	struct ndis_softc	*sc;
3035 	struct ifnet		*ifp;
3036 	ndis_80211_key		rkey;
3037 	int			len, error = 0;
3038 
3039 	ifp = vap->iv_ic->ic_ifp;
3040 	sc = ifp->if_softc;
3041 
3042 	switch (key->wk_cipher->ic_cipher) {
3043 	case IEEE80211_CIPHER_TKIP:
3044 
3045 		len = sizeof(ndis_80211_key);
3046 		bzero((char *)&rkey, sizeof(rkey));
3047 
3048 		rkey.nk_len = len;
3049 		rkey.nk_keylen = key->wk_keylen;
3050 
3051 		if (key->wk_flags & IEEE80211_KEY_SWMIC)
3052 			rkey.nk_keylen += 16;
3053 
3054 		/* key index - gets weird in NDIS */
3055 
3056 		if (key->wk_keyix != IEEE80211_KEYIX_NONE)
3057 			rkey.nk_keyidx = key->wk_keyix;
3058 		else
3059 			rkey.nk_keyidx = 0;
3060 
3061 		if (key->wk_flags & IEEE80211_KEY_XMIT)
3062 			rkey.nk_keyidx |= 1 << 31;
3063 
3064 		if (key->wk_flags & IEEE80211_KEY_GROUP) {
3065 			bcopy(ifp->if_broadcastaddr,
3066 			    rkey.nk_bssid, IEEE80211_ADDR_LEN);
3067 		} else {
3068 			bcopy(vap->iv_bss->ni_bssid,
3069 			    rkey.nk_bssid, IEEE80211_ADDR_LEN);
3070 			/* pairwise key */
3071 			rkey.nk_keyidx |= 1 << 30;
3072 		}
3073 
3074 		/* need to set bit 29 based on keyrsc */
3075 		rkey.nk_keyrsc = key->wk_keyrsc[0];	/* XXX need tid */
3076 
3077 		if (rkey.nk_keyrsc)
3078 			rkey.nk_keyidx |= 1 << 29;
3079 
3080 		if (key->wk_flags & IEEE80211_KEY_SWMIC) {
3081 			bcopy(key->wk_key, rkey.nk_keydata, 16);
3082 			bcopy(key->wk_key + 24, rkey.nk_keydata + 16, 8);
3083 			bcopy(key->wk_key + 16, rkey.nk_keydata + 24, 8);
3084 		} else
3085 			bcopy(key->wk_key, rkey.nk_keydata, key->wk_keylen);
3086 
3087 		error = ndis_set_info(sc, OID_802_11_ADD_KEY, &rkey, &len);
3088 		break;
3089 	case IEEE80211_CIPHER_WEP:
3090 		error = 0;
3091 		break;
3092 	/*
3093 	 * I don't know how to set up keys for the AES
3094 	 * cipher yet. Is it the same as TKIP?
3095 	 */
3096 	case IEEE80211_CIPHER_AES_CCM:
3097 	default:
3098 		error = ENOTTY;
3099 		break;
3100 	}
3101 
3102 	/* We need to return 1 for success, 0 for failure. */
3103 
3104 	if (error)
3105 		return (0);
3106 
3107 	return (1);
3108 }
3109 
3110 static void
ndis_resettask(d,arg)3111 ndis_resettask(d, arg)
3112 	device_object		*d;
3113 	void			*arg;
3114 {
3115 	struct ndis_softc		*sc;
3116 
3117 	sc = arg;
3118 	ndis_reset_nic(sc);
3119 }
3120 
3121 /*
3122  * Stop the adapter and free any mbufs allocated to the
3123  * RX and TX lists.
3124  */
3125 static void
ndis_stop(sc)3126 ndis_stop(sc)
3127 	struct ndis_softc		*sc;
3128 {
3129 	struct ifnet		*ifp;
3130 	int			i;
3131 
3132 	ifp = sc->ifp;
3133 	callout_drain(&sc->ndis_stat_callout);
3134 
3135 	NDIS_LOCK(sc);
3136 	sc->ndis_tx_timer = 0;
3137 	sc->ndis_link = 0;
3138 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3139 	NDIS_UNLOCK(sc);
3140 
3141 	if (sc->ndis_iftype != PNPBus ||
3142 	    (sc->ndis_iftype == PNPBus &&
3143 	     !(sc->ndisusb_status & NDISUSB_STATUS_DETACH) &&
3144 	     ndisusb_halt != 0))
3145 		ndis_halt_nic(sc);
3146 
3147 	NDIS_LOCK(sc);
3148 	for (i = 0; i < NDIS_EVENTS; i++) {
3149 		if (sc->ndis_evt[i].ne_sts && sc->ndis_evt[i].ne_buf != NULL) {
3150 			free(sc->ndis_evt[i].ne_buf, M_TEMP);
3151 			sc->ndis_evt[i].ne_buf = NULL;
3152 		}
3153 		sc->ndis_evt[i].ne_sts = 0;
3154 		sc->ndis_evt[i].ne_len = 0;
3155 	}
3156 	sc->ndis_evtcidx = 0;
3157 	sc->ndis_evtpidx = 0;
3158 	NDIS_UNLOCK(sc);
3159 }
3160 
3161 /*
3162  * Stop all chip I/O so that the kernel's probe routines don't
3163  * get confused by errant DMAs when rebooting.
3164  */
3165 void
ndis_shutdown(dev)3166 ndis_shutdown(dev)
3167 	device_t		dev;
3168 {
3169 	struct ndis_softc		*sc;
3170 
3171 	sc = device_get_softc(dev);
3172 	ndis_stop(sc);
3173 }
3174 
3175 static int
ndis_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3176 ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3177 {
3178 	struct ndis_vap *nvp = NDIS_VAP(vap);
3179 	struct ieee80211com *ic = vap->iv_ic;
3180 	struct ifnet *ifp = ic->ic_ifp;
3181 	struct ndis_softc *sc = ifp->if_softc;
3182 	enum ieee80211_state ostate;
3183 
3184 	DPRINTF(("%s: %s -> %s\n", __func__,
3185 		ieee80211_state_name[vap->iv_state],
3186 		ieee80211_state_name[nstate]));
3187 
3188 	ostate = vap->iv_state;
3189 	vap->iv_state = nstate;
3190 
3191 	switch (nstate) {
3192 	/* pass on to net80211 */
3193 	case IEEE80211_S_INIT:
3194 	case IEEE80211_S_SCAN:
3195 		return nvp->newstate(vap, nstate, arg);
3196 	case IEEE80211_S_ASSOC:
3197 		if (ostate != IEEE80211_S_AUTH) {
3198 			IEEE80211_UNLOCK(ic);
3199 			ndis_auth_and_assoc(sc, vap);
3200 			IEEE80211_LOCK(ic);
3201 		}
3202 		break;
3203 	case IEEE80211_S_AUTH:
3204 		IEEE80211_UNLOCK(ic);
3205 		ndis_auth_and_assoc(sc, vap);
3206 		if (vap->iv_state == IEEE80211_S_AUTH) /* XXX */
3207 			ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
3208 		IEEE80211_LOCK(ic);
3209 		break;
3210 	default:
3211 		break;
3212 	}
3213 	return (0);
3214 }
3215 
3216 static void
ndis_scan(void * arg)3217 ndis_scan(void *arg)
3218 {
3219 	struct ieee80211vap *vap = arg;
3220 
3221 	ieee80211_scan_done(vap);
3222 }
3223 
3224 static void
ndis_scan_results(struct ndis_softc * sc)3225 ndis_scan_results(struct ndis_softc *sc)
3226 {
3227 	struct ieee80211com *ic;
3228 	struct ieee80211vap *vap;
3229 	ndis_80211_bssid_list_ex *bl;
3230 	ndis_wlan_bssid_ex	*wb;
3231 	struct ieee80211_scanparams sp;
3232 	struct ieee80211_frame wh;
3233 	struct ieee80211_channel *saved_chan;
3234 	int i, j;
3235 	int rssi, noise, freq, chanflag;
3236 	uint8_t ssid[2+IEEE80211_NWID_LEN];
3237 	uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
3238 	uint8_t *frm, *efrm;
3239 
3240 	ic = sc->ifp->if_l2com;
3241 	vap = TAILQ_FIRST(&ic->ic_vaps);
3242 	saved_chan = ic->ic_curchan;
3243 	noise = -96;
3244 
3245 	if (ndis_get_bssid_list(sc, &bl))
3246 		return;
3247 
3248 	DPRINTF(("%s: %d results\n", __func__, bl->nblx_items));
3249 	wb = &bl->nblx_bssid[0];
3250 	for (i = 0; i < bl->nblx_items; i++) {
3251 		memset(&sp, 0, sizeof(sp));
3252 
3253 		memcpy(wh.i_addr2, wb->nwbx_macaddr, sizeof(wh.i_addr2));
3254 		memcpy(wh.i_addr3, wb->nwbx_macaddr, sizeof(wh.i_addr3));
3255 		rssi = 100 * (wb->nwbx_rssi - noise) / (-32 - noise);
3256 		rssi = max(0, min(rssi, 100));	/* limit 0 <= rssi <= 100 */
3257 		if (wb->nwbx_privacy)
3258 			sp.capinfo |= IEEE80211_CAPINFO_PRIVACY;
3259 		sp.bintval = wb->nwbx_config.nc_beaconperiod;
3260 		switch (wb->nwbx_netinfra) {
3261 			case NDIS_80211_NET_INFRA_IBSS:
3262 				sp.capinfo |= IEEE80211_CAPINFO_IBSS;
3263 				break;
3264 			case NDIS_80211_NET_INFRA_BSS:
3265 				sp.capinfo |= IEEE80211_CAPINFO_ESS;
3266 				break;
3267 		}
3268 		sp.rates = &rates[0];
3269 		for (j = 0; j < IEEE80211_RATE_MAXSIZE; j++) {
3270 			/* XXX - check units */
3271 			if (wb->nwbx_supportedrates[j] == 0)
3272 				break;
3273 			rates[2 + j] =
3274 			wb->nwbx_supportedrates[j] & 0x7f;
3275 		}
3276 		rates[1] = j;
3277 		sp.ssid = (uint8_t *)&ssid[0];
3278 		memcpy(sp.ssid + 2, &wb->nwbx_ssid.ns_ssid,
3279 		    wb->nwbx_ssid.ns_ssidlen);
3280 		sp.ssid[1] = wb->nwbx_ssid.ns_ssidlen;
3281 
3282 		chanflag = ndis_nettype_chan(wb->nwbx_nettype);
3283 		freq = wb->nwbx_config.nc_dsconfig / 1000;
3284 		sp.chan = sp.bchan = ieee80211_mhz2ieee(freq, chanflag);
3285 		/* Hack ic->ic_curchan to be in sync with the scan result */
3286 		ic->ic_curchan = ieee80211_find_channel(ic, freq, chanflag);
3287 		if (ic->ic_curchan == NULL)
3288 			ic->ic_curchan = &ic->ic_channels[0];
3289 
3290 		/* Process extended info from AP */
3291 		if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) {
3292 			frm = (uint8_t *)&wb->nwbx_ies;
3293 			efrm = frm + wb->nwbx_ielen;
3294 			if (efrm - frm < 12)
3295 				goto done;
3296 			sp.tstamp = frm;			frm += 8;
3297 			sp.bintval = le16toh(*(uint16_t *)frm);	frm += 2;
3298 			sp.capinfo = le16toh(*(uint16_t *)frm);	frm += 2;
3299 			sp.ies = frm;
3300 			sp.ies_len = efrm - frm;
3301 		}
3302 done:
3303 		DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n",
3304 		    ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag,
3305 		    rssi));
3306 		ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise);
3307 		wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len);
3308 	}
3309 	free(bl, M_DEVBUF);
3310 	/* Restore the channel after messing with it */
3311 	ic->ic_curchan = saved_chan;
3312 }
3313 
3314 static void
ndis_scan_start(struct ieee80211com * ic)3315 ndis_scan_start(struct ieee80211com *ic)
3316 {
3317 	struct ifnet *ifp = ic->ic_ifp;
3318 	struct ndis_softc *sc = ifp->if_softc;
3319 	struct ieee80211vap *vap;
3320 	struct ieee80211_scan_state *ss;
3321 	ndis_80211_ssid ssid;
3322 	int error, len;
3323 
3324 	ss = ic->ic_scan;
3325 	vap = TAILQ_FIRST(&ic->ic_vaps);
3326 
3327 	if (!NDIS_INITIALIZED(sc)) {
3328 		DPRINTF(("%s: scan aborted\n", __func__));
3329 		ieee80211_cancel_scan(vap);
3330 		return;
3331 	}
3332 
3333 	len = sizeof(ssid);
3334 	bzero((char *)&ssid, len);
3335 	if (ss->ss_nssid == 0)
3336 		ssid.ns_ssidlen = 1;
3337 	else {
3338 		/* Perform a directed scan */
3339 		ssid.ns_ssidlen = ss->ss_ssid[0].len;
3340 		bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
3341 	}
3342 
3343 	error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
3344 	if (error)
3345 		DPRINTF(("%s: set ESSID failed\n", __func__));
3346 
3347 	len = 0;
3348 	error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, NULL, &len);
3349 	if (error) {
3350 		DPRINTF(("%s: scan command failed\n", __func__));
3351 		ieee80211_cancel_scan(vap);
3352 		return;
3353 	}
3354 	/* Set a timer to collect the results */
3355 	callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, vap);
3356 }
3357 
3358 static void
ndis_set_channel(struct ieee80211com * ic)3359 ndis_set_channel(struct ieee80211com *ic)
3360 {
3361 	/* ignore */
3362 }
3363 
3364 static void
ndis_scan_curchan(struct ieee80211_scan_state * ss,unsigned long maxdwell)3365 ndis_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
3366 {
3367 	/* ignore */
3368 }
3369 
3370 static void
ndis_scan_mindwell(struct ieee80211_scan_state * ss)3371 ndis_scan_mindwell(struct ieee80211_scan_state *ss)
3372 {
3373 	/* NB: don't try to abort scan; wait for firmware to finish */
3374 }
3375 
3376 static void
ndis_scan_end(struct ieee80211com * ic)3377 ndis_scan_end(struct ieee80211com *ic)
3378 {
3379 	struct ndis_softc *sc = ic->ic_ifp->if_softc;
3380 
3381 	ndis_scan_results(sc);
3382 }
3383