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