3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
32 * $FreeBSD: src/sys/dev/if_ndis/if_ndis.c,v 1.181 2012/11/17 01:51:54 svnexp Exp $
34 * WPA support originally contributed by Arvind Srinivasan <arvind@celar.us>
35 * then hacked upon mercilessly by me.
38 #include "use_oldusb.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sockio.h>
44 #include <sys/malloc.h>
45 #include <sys/endian.h>
47 #include <sys/kernel.h>
48 #include <sys/socket.h>
49 #include <sys/queue.h>
50 #include <sys/module.h>
52 #include <sys/sysctl.h>
53 #include <sys/kthread.h>
56 #include <net/if_arp.h>
57 #include <net/ethernet.h>
58 #include <net/if_dl.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/route.h>
64 #include <net/ifq_var.h>
68 #include <sys/mplock2.h>
70 #include <netproto/802_11/ieee80211_var.h>
71 #include <netproto/802_11/ieee80211_ioctl.h>
72 #include <netproto/802_11/ieee80211_regdomain.h>
74 #include <bus/pci/pcireg.h>
75 #include <bus/pci/pcivar.h>
77 #include <bus/u4b/usb.h>
78 #include <bus/u4b/usbdi.h>
80 #include <bus/usb/usb.h>
81 #include <bus/usb/usbdi.h>
84 #include <emulation/ndis/pe_var.h>
85 #include <emulation/ndis/cfg_var.h>
86 #include <emulation/ndis/resource_var.h>
87 #include <emulation/ndis/ntoskrnl_var.h>
88 #include <emulation/ndis/hal_var.h>
89 #include <emulation/ndis/ndis_var.h>
91 #include <emulation/ndis/u4bd_var.h>
93 #include <emulation/ndis/usbd_var.h>
95 #include <dev/netif/ndis/if_ndisvar.h>
99 #define DPRINTF(x) do { if (ndis_debug > 0) kprintf x; } while (0)
101 SYSCTL_INT(_debug, OID_AUTO, ndis, CTLFLAG_RW, &ndis_debug, 0,
102 "if_ndis debug level");
107 SYSCTL_DECL(_hw_ndisusb);
108 int ndisusb_halt = 1;
109 SYSCTL_INT(_hw_ndisusb, OID_AUTO, halt, CTLFLAG_RW, &ndisusb_halt, 0,
110 "Halt NDIS USB driver when it's attached");
112 /* 0 - 30 dBm to mW conversion table */
113 static const uint16_t dBm2mW[] = {
114 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
115 3, 4, 4, 4, 5, 6, 6, 7, 8, 9,
116 10, 11, 13, 14, 16, 18, 20, 22, 25, 28,
117 32, 35, 40, 45, 50, 56, 63, 71, 79, 89,
118 100, 112, 126, 141, 158, 178, 200, 224, 251, 282,
119 316, 355, 398, 447, 501, 562, 631, 708, 794, 891,
123 MODULE_DEPEND(if_ndis, ether, 1, 1, 1);
124 MODULE_DEPEND(if_ndis, wlan, 1, 1, 1);
125 MODULE_DEPEND(if_ndis, ndis, 1, 1, 1);
127 MODULE_VERSION(if_ndis, 1);
129 int ndis_attach (device_t);
130 int ndis_detach (device_t);
131 int ndis_suspend (device_t);
132 int ndis_resume (device_t);
133 void ndis_shutdown (device_t);
135 int ndisdrv_modevent (module_t, int, void *);
137 static void ndis_txeof (ndis_handle, ndis_packet *, ndis_status);
138 static void ndis_rxeof (ndis_handle, ndis_packet **, uint32_t);
139 static void ndis_rxeof_eth (ndis_handle, ndis_handle, char *, void *,
140 uint32_t, void *, uint32_t, uint32_t);
141 static void ndis_rxeof_done (ndis_handle);
142 static void ndis_rxeof_xfr (kdpc *, ndis_handle, void *, void *);
143 static void ndis_rxeof_xfr_done (ndis_handle, ndis_packet *,
145 static void ndis_linksts (ndis_handle, ndis_status, void *, uint32_t);
146 static void ndis_linksts_done (ndis_handle);
148 /* We need to wrap these functions for amd64. */
149 static funcptr ndis_txeof_wrap;
150 static funcptr ndis_rxeof_wrap;
151 static funcptr ndis_rxeof_eth_wrap;
152 static funcptr ndis_rxeof_done_wrap;
153 static funcptr ndis_rxeof_xfr_wrap;
154 static funcptr ndis_rxeof_xfr_done_wrap;
155 static funcptr ndis_linksts_wrap;
156 static funcptr ndis_linksts_done_wrap;
157 static funcptr ndis_ticktask_wrap;
158 static funcptr ndis_starttask_wrap;
159 static funcptr ndis_resettask_wrap;
160 static funcptr ndis_inputtask_wrap;
162 static struct ieee80211vap *ndis_vap_create(struct ieee80211com *,
163 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
164 const uint8_t [IEEE80211_ADDR_LEN],
165 const uint8_t [IEEE80211_ADDR_LEN]);
166 static void ndis_vap_delete (struct ieee80211vap *);
167 static void ndis_tick (void *);
168 static void ndis_ticktask (device_object *, void *);
169 static int ndis_raw_xmit (struct ieee80211_node *, struct mbuf *,
170 const struct ieee80211_bpf_params *);
171 static void ndis_update_mcast (struct ifnet *ifp);
172 static void ndis_update_promisc (struct ifnet *ifp);
173 static void ndis_start (struct ifnet *, struct ifaltq_subque *);
174 static void ndis_starttask (device_object *, void *);
175 static void ndis_resettask (device_object *, void *);
176 static void ndis_inputtask (device_object *, void *);
177 static int ndis_ioctl (struct ifnet *, u_long, caddr_t, struct ucred *);
178 static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t, struct ucred *);
179 static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
181 static int ndis_nettype_chan (uint32_t);
182 static int ndis_nettype_mode (uint32_t);
183 static void ndis_scan (void *);
184 static void ndis_scan_results (struct ndis_softc *);
185 static void ndis_scan_start (struct ieee80211com *);
186 static void ndis_scan_end (struct ieee80211com *);
187 static void ndis_set_channel (struct ieee80211com *);
188 static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long);
189 static void ndis_scan_mindwell (struct ieee80211_scan_state *);
190 static void ndis_init (void *);
191 static void ndis_stop (struct ndis_softc *);
192 static int ndis_ifmedia_upd (struct ifnet *);
193 static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *);
194 static int ndis_get_bssid_list (struct ndis_softc *,
195 ndis_80211_bssid_list_ex **);
196 static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex **);
197 static int ndis_probe_offload (struct ndis_softc *);
198 static int ndis_set_offload (struct ndis_softc *);
199 static void ndis_getstate_80211 (struct ndis_softc *);
200 static void ndis_setstate_80211 (struct ndis_softc *);
201 static void ndis_auth_and_assoc (struct ndis_softc *, struct ieee80211vap *);
202 static void ndis_media_status (struct ifnet *, struct ifmediareq *);
203 static int ndis_set_cipher (struct ndis_softc *, int);
204 static int ndis_set_wpa (struct ndis_softc *, void *, int);
205 static int ndis_add_key (struct ieee80211vap *,
206 const struct ieee80211_key *, const u_int8_t []);
207 static int ndis_del_key (struct ieee80211vap *,
208 const struct ieee80211_key *);
210 static void ndis_setmulti (struct ndis_softc *);
211 static void ndis_map_sclist (void *, bus_dma_segment_t *,
212 int, bus_size_t, int);
214 static int ndisdrv_loaded = 0;
217 * This routine should call windrv_load() once for each driver
218 * image. This will do the relocation and dynalinking for the
219 * image, and create a Windows driver object which will be
220 * saved in our driver database.
223 ndisdrv_modevent(module_t mod, int cmd, void *arg)
230 if (ndisdrv_loaded > 1)
232 windrv_wrap((funcptr)ndis_rxeof, &ndis_rxeof_wrap,
233 3, WINDRV_WRAP_STDCALL);
234 windrv_wrap((funcptr)ndis_rxeof_eth, &ndis_rxeof_eth_wrap,
235 8, WINDRV_WRAP_STDCALL);
236 windrv_wrap((funcptr)ndis_rxeof_done, &ndis_rxeof_done_wrap,
237 1, WINDRV_WRAP_STDCALL);
238 windrv_wrap((funcptr)ndis_rxeof_xfr, &ndis_rxeof_xfr_wrap,
239 4, WINDRV_WRAP_STDCALL);
240 windrv_wrap((funcptr)ndis_rxeof_xfr_done,
241 &ndis_rxeof_xfr_done_wrap, 4, WINDRV_WRAP_STDCALL);
242 windrv_wrap((funcptr)ndis_txeof, &ndis_txeof_wrap,
243 3, WINDRV_WRAP_STDCALL);
244 windrv_wrap((funcptr)ndis_linksts, &ndis_linksts_wrap,
245 4, WINDRV_WRAP_STDCALL);
246 windrv_wrap((funcptr)ndis_linksts_done,
247 &ndis_linksts_done_wrap, 1, WINDRV_WRAP_STDCALL);
248 windrv_wrap((funcptr)ndis_ticktask, &ndis_ticktask_wrap,
249 2, WINDRV_WRAP_STDCALL);
250 windrv_wrap((funcptr)ndis_starttask, &ndis_starttask_wrap,
251 2, WINDRV_WRAP_STDCALL);
252 windrv_wrap((funcptr)ndis_resettask, &ndis_resettask_wrap,
253 2, WINDRV_WRAP_STDCALL);
254 windrv_wrap((funcptr)ndis_inputtask, &ndis_inputtask_wrap,
255 2, WINDRV_WRAP_STDCALL);
259 if (ndisdrv_loaded > 0)
263 windrv_unwrap(ndis_rxeof_wrap);
264 windrv_unwrap(ndis_rxeof_eth_wrap);
265 windrv_unwrap(ndis_rxeof_done_wrap);
266 windrv_unwrap(ndis_rxeof_xfr_wrap);
267 windrv_unwrap(ndis_rxeof_xfr_done_wrap);
268 windrv_unwrap(ndis_txeof_wrap);
269 windrv_unwrap(ndis_linksts_wrap);
270 windrv_unwrap(ndis_linksts_done_wrap);
271 windrv_unwrap(ndis_ticktask_wrap);
272 windrv_unwrap(ndis_starttask_wrap);
273 windrv_unwrap(ndis_resettask_wrap);
274 windrv_unwrap(ndis_inputtask_wrap);
285 * Program the 64-bit multicast hash filter.
288 ndis_setmulti(struct ndis_softc *sc)
291 struct ifmultiaddr *ifma;
292 int len, mclistsz, error;
297 if (!NDIS_INITIALIZED(sc))
300 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
301 sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
302 len = sizeof(sc->ndis_filter);
303 error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
304 &sc->ndis_filter, &len);
306 device_printf(sc->ndis_dev,
307 "set allmulti failed: %d\n", error);
311 if (TAILQ_EMPTY(&ifp->if_multiaddrs))
314 len = sizeof(mclistsz);
315 ndis_get_info(sc, OID_802_3_MAXIMUM_LIST_SIZE, &mclistsz, &len);
317 mclist = kmalloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_NOWAIT|M_ZERO);
319 if (mclist == NULL) {
320 sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
324 sc->ndis_filter |= NDIS_PACKET_TYPE_MULTICAST;
327 #if 0 /* XXX swildner */
330 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
331 if (ifma->ifma_addr->sa_family != AF_LINK)
333 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
334 mclist + (ETHER_ADDR_LEN * len), ETHER_ADDR_LEN);
336 if (len > mclistsz) {
337 #if 0 /* XXX swildner */
338 if_maddr_runlock(ifp);
340 sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
341 sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
345 #if 0 /* XXX swildner */
346 if_maddr_runlock(ifp);
349 len = len * ETHER_ADDR_LEN;
350 error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len);
352 device_printf(sc->ndis_dev, "set mclist failed: %d\n", error);
353 sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
354 sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
358 kfree(mclist, M_TEMP);
360 len = sizeof(sc->ndis_filter);
361 error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
362 &sc->ndis_filter, &len);
364 device_printf(sc->ndis_dev, "set multi failed: %d\n", error);
368 ndis_set_offload(struct ndis_softc *sc)
370 ndis_task_offload *nto;
371 ndis_task_offload_hdr *ntoh;
372 ndis_task_tcpip_csum *nttc;
378 if (!NDIS_INITIALIZED(sc))
381 /* See if there's anything to set. */
383 error = ndis_probe_offload(sc);
387 if (sc->ndis_hwassist == 0 && ifp->if_capabilities == 0)
390 len = sizeof(ndis_task_offload_hdr) + sizeof(ndis_task_offload) +
391 sizeof(ndis_task_tcpip_csum);
393 ntoh = kmalloc(len, M_TEMP, M_NOWAIT|M_ZERO);
398 ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
399 ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
400 ntoh->ntoh_offset_firsttask = sizeof(ndis_task_offload_hdr);
401 ntoh->ntoh_encapfmt.nef_encaphdrlen = sizeof(struct ether_header);
402 ntoh->ntoh_encapfmt.nef_encap = NDIS_ENCAP_IEEE802_3;
403 ntoh->ntoh_encapfmt.nef_flags = NDIS_ENCAPFLAG_FIXEDHDRLEN;
405 nto = (ndis_task_offload *)((char *)ntoh +
406 ntoh->ntoh_offset_firsttask);
408 nto->nto_vers = NDIS_TASK_OFFLOAD_VERSION;
409 nto->nto_len = sizeof(ndis_task_offload);
410 nto->nto_task = NDIS_TASK_TCPIP_CSUM;
411 nto->nto_offset_nexttask = 0;
412 nto->nto_taskbuflen = sizeof(ndis_task_tcpip_csum);
414 nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
416 if (ifp->if_capenable & IFCAP_TXCSUM)
417 nttc->nttc_v4tx = sc->ndis_v4tx;
419 if (ifp->if_capenable & IFCAP_RXCSUM)
420 nttc->nttc_v4rx = sc->ndis_v4rx;
422 error = ndis_set_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
429 ndis_probe_offload(struct ndis_softc *sc)
431 ndis_task_offload *nto;
432 ndis_task_offload_hdr *ntoh;
433 ndis_task_tcpip_csum *nttc = NULL;
435 int len, error, dummy;
440 error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, &dummy, &len);
445 ntoh = kmalloc(len, M_TEMP, M_NOWAIT|M_ZERO);
450 ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
451 ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
452 ntoh->ntoh_encapfmt.nef_encaphdrlen = sizeof(struct ether_header);
453 ntoh->ntoh_encapfmt.nef_encap = NDIS_ENCAP_IEEE802_3;
454 ntoh->ntoh_encapfmt.nef_flags = NDIS_ENCAPFLAG_FIXEDHDRLEN;
456 error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
463 if (ntoh->ntoh_vers != NDIS_TASK_OFFLOAD_VERSION) {
468 nto = (ndis_task_offload *)((char *)ntoh +
469 ntoh->ntoh_offset_firsttask);
472 switch (nto->nto_task) {
473 case NDIS_TASK_TCPIP_CSUM:
474 nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
476 /* Don't handle these yet. */
477 case NDIS_TASK_IPSEC:
478 case NDIS_TASK_TCP_LARGESEND:
482 if (nto->nto_offset_nexttask == 0)
484 nto = (ndis_task_offload *)((char *)nto +
485 nto->nto_offset_nexttask);
493 sc->ndis_v4tx = nttc->nttc_v4tx;
494 sc->ndis_v4rx = nttc->nttc_v4rx;
496 if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_IP_CSUM)
497 sc->ndis_hwassist |= CSUM_IP;
498 if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_TCP_CSUM)
499 sc->ndis_hwassist |= CSUM_TCP;
500 if (nttc->nttc_v4tx & NDIS_TCPSUM_FLAGS_UDP_CSUM)
501 sc->ndis_hwassist |= CSUM_UDP;
503 if (sc->ndis_hwassist)
504 ifp->if_capabilities |= IFCAP_TXCSUM;
506 if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_IP_CSUM)
507 ifp->if_capabilities |= IFCAP_RXCSUM;
508 if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_TCP_CSUM)
509 ifp->if_capabilities |= IFCAP_RXCSUM;
510 if (nttc->nttc_v4rx & NDIS_TCPSUM_FLAGS_UDP_CSUM)
511 ifp->if_capabilities |= IFCAP_RXCSUM;
518 ndis_nettype_chan(uint32_t type)
521 case NDIS_80211_NETTYPE_11FH: return (IEEE80211_CHAN_FHSS);
522 case NDIS_80211_NETTYPE_11DS: return (IEEE80211_CHAN_B);
523 case NDIS_80211_NETTYPE_11OFDM5: return (IEEE80211_CHAN_A);
524 case NDIS_80211_NETTYPE_11OFDM24: return (IEEE80211_CHAN_G);
526 DPRINTF(("unknown channel nettype %d\n", type));
527 return (IEEE80211_CHAN_B); /* Default to 11B chan */
531 ndis_nettype_mode(uint32_t type)
534 case NDIS_80211_NETTYPE_11FH: return (IEEE80211_MODE_FH);
535 case NDIS_80211_NETTYPE_11DS: return (IEEE80211_MODE_11B);
536 case NDIS_80211_NETTYPE_11OFDM5: return (IEEE80211_MODE_11A);
537 case NDIS_80211_NETTYPE_11OFDM24: return (IEEE80211_MODE_11G);
539 DPRINTF(("unknown mode nettype %d\n", type));
540 return (IEEE80211_MODE_AUTO);
544 * Attach the interface. Allocate softc structures, do ifmedia
545 * setup and ethernet/BPF attach.
548 ndis_attach(device_t dev)
550 u_char eaddr[ETHER_ADDR_LEN];
551 struct ndis_softc *sc;
554 struct ifnet *ifp = NULL;
555 int error = 0, len, mode;
559 sc = device_get_softc(dev);
561 lockinit(&sc->ndis_lock, "network driver", 0, LK_CANRECURSE);
562 KeInitializeSpinLock(&sc->ndis_rxlock);
564 KeInitializeSpinLock(&sc->ndisusb_tasklock);
565 KeInitializeSpinLock(&sc->ndisusb_xferdonelock);
567 KeInitializeSpinLock(&sc->ndisusb_xferlock);
569 InitializeListHead(&sc->ndis_shlist);
571 InitializeListHead(&sc->ndisusb_tasklist);
572 InitializeListHead(&sc->ndisusb_xferdonelist);
574 InitializeListHead(&sc->ndisusb_xferlist);
576 callout_init_mp(&sc->ndis_stat_callout);
578 if (sc->ndis_iftype == PCMCIABus) {
579 error = ndis_alloc_amem(sc);
581 device_printf(dev, "failed to allocate "
582 "attribute memory\n");
587 /* Create sysctl registry nodes */
588 ndis_create_sysctls(sc);
590 /* Find the PDO for this device instance. */
592 if (sc->ndis_iftype == PCIBus)
593 pdrv = windrv_lookup(0, "PCI Bus");
594 else if (sc->ndis_iftype == PCMCIABus)
595 pdrv = windrv_lookup(0, "PCCARD Bus");
597 pdrv = windrv_lookup(0, "USB Bus");
598 pdo = windrv_find_pdo(pdrv, dev);
601 * Create a new functional device object for this
602 * device. This is what creates the miniport block
603 * for this device instance.
606 if (NdisAddDevice(sc->ndis_dobj, pdo) != STATUS_SUCCESS) {
607 device_printf(dev, "failed to create FDO!\n");
612 /* Tell the user what version of the API the driver is using. */
613 device_printf(dev, "NDIS API version: %d.%d\n",
614 sc->ndis_chars->nmc_version_major,
615 sc->ndis_chars->nmc_version_minor);
617 /* Do resource conversion. */
618 if (sc->ndis_iftype == PCMCIABus || sc->ndis_iftype == PCIBus)
619 ndis_convert_res(sc);
621 sc->ndis_block->nmb_rlist = NULL;
623 /* Install our RX and TX interrupt handlers. */
624 sc->ndis_block->nmb_senddone_func = ndis_txeof_wrap;
625 sc->ndis_block->nmb_pktind_func = ndis_rxeof_wrap;
626 sc->ndis_block->nmb_ethrxindicate_func = ndis_rxeof_eth_wrap;
627 sc->ndis_block->nmb_ethrxdone_func = ndis_rxeof_done_wrap;
628 sc->ndis_block->nmb_tdcond_func = ndis_rxeof_xfr_done_wrap;
630 /* Override the status handler so we can detect link changes. */
631 sc->ndis_block->nmb_status_func = ndis_linksts_wrap;
632 sc->ndis_block->nmb_statusdone_func = ndis_linksts_done_wrap;
634 /* Set up work item handlers. */
635 sc->ndis_tickitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
636 sc->ndis_startitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
637 sc->ndis_resetitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
638 sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
640 sc->ndisusb_xferdoneitem =
641 IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
642 sc->ndisusb_taskitem =
643 IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
645 sc->ndisusb_xferitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
647 KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block);
649 /* Call driver's init routine. */
650 if (ndis_init_nic(sc)) {
651 device_printf(dev, "init handler failed\n");
657 * Get station address from the driver.
660 ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len);
663 * Figure out how big to make the TX buffer pool.
666 len = sizeof(sc->ndis_maxpkts);
667 if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS,
668 &sc->ndis_maxpkts, &len)) {
669 device_printf(dev, "failed to get max TX packets\n");
675 * If this is a deserialized miniport, we don't have
676 * to honor the OID_GEN_MAXIMUM_SEND_PACKETS result.
678 if (!NDIS_SERIALIZED(sc->ndis_block))
679 sc->ndis_maxpkts = NDIS_TXPKTS;
681 /* Enforce some sanity, just in case. */
683 if (sc->ndis_maxpkts == 0)
684 sc->ndis_maxpkts = 10;
686 sc->ndis_txarray = kmalloc(sizeof(ndis_packet *) *
687 sc->ndis_maxpkts, M_DEVBUF, M_WAITOK|M_ZERO);
689 /* Allocate a pool of ndis_packets for TX encapsulation. */
691 NdisAllocatePacketPool(&i, &sc->ndis_txpool,
692 sc->ndis_maxpkts, PROTOCOL_RESERVED_SIZE_IN_PACKET);
694 if (i != NDIS_STATUS_SUCCESS) {
695 sc->ndis_txpool = NULL;
696 device_printf(dev, "failed to allocate TX packet pool");
701 sc->ndis_txpending = sc->ndis_maxpkts;
704 /* Get supported oid list. */
705 ndis_get_supported_oids(sc, &sc->ndis_oids, &sc->ndis_oidcnt);
707 /* If the NDIS module requested scatter/gather, init maps. */
712 * See if the OID_802_11_CONFIGURATION OID is
713 * supported by this driver. If it is, then this an 802.11
714 * wireless driver, and we should set up media for wireless.
716 for (i = 0; i < sc->ndis_oidcnt; i++)
717 if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) {
723 ifp = if_alloc(IFT_IEEE80211);
725 ifp = if_alloc(IFT_ETHER);
733 /* Check for task offload support. */
734 ndis_probe_offload(sc);
736 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
737 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
739 if (sc->ndis_iftype == PNPBus)
740 ifp->if_flags |= IFF_NEEDSGIANT;
742 ifp->if_ioctl = ndis_ioctl;
743 ifp->if_start = ndis_start;
744 ifp->if_init = ndis_init;
745 ifp->if_baudrate = 10000000;
746 ifq_set_maxlen(&ifp->if_snd, 50);
748 ifq_set_ready(&ifp->if_snd);
750 ifp->if_capenable = ifp->if_capabilities;
751 ifp->if_hwassist = sc->ndis_hwassist;
754 if (sc->ndis_80211) {
755 struct ieee80211com *ic = ifp->if_l2com;
756 ndis_80211_rates_ex rates;
757 struct ndis_80211_nettype_list *ntl;
761 callout_init_mp(&sc->ndis_scan_callout);
763 ifp->if_ioctl = ndis_ioctl_80211;
765 ic->ic_opmode = IEEE80211_M_STA;
766 ic->ic_phytype = IEEE80211_T_DS;
767 ic->ic_caps = IEEE80211_C_8023ENCAP |
768 IEEE80211_C_STA | IEEE80211_C_IBSS;
769 setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
771 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
775 ntl = kmalloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
776 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
779 kfree(ntl, M_DEVBUF);
783 for (i = 0; i < ntl->ntl_items; i++) {
784 mode = ndis_nettype_mode(ntl->ntl_type[i]);
786 setbit(ic->ic_modecaps, mode);
787 setbit(&bands, mode);
789 device_printf(dev, "Unknown nettype %d\n",
792 kfree(ntl, M_DEVBUF);
794 /* Default to 11b channels if the card did not supply any */
796 setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
797 setbit(&bands, IEEE80211_MODE_11B);
800 bzero((char *)&rates, len);
801 r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
802 (void *)rates, &len);
804 device_printf(dev, "get rates failed: 0x%x\n", r);
806 * Since the supported rates only up to 8 can be supported,
807 * if this is not 802.11b we're just going to be faking it
811 #define TESTSETRATE(x, y) \
814 for (i = 0; i < ic->ic_sup_rates[x].rs_nrates; i++) { \
815 if (ic->ic_sup_rates[x].rs_rates[i] == (y)) \
818 if (i == ic->ic_sup_rates[x].rs_nrates) { \
819 ic->ic_sup_rates[x].rs_rates[i] = (y); \
820 ic->ic_sup_rates[x].rs_nrates++; \
824 #define SETRATE(x, y) \
825 ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y)
827 ic->ic_sup_rates[x].rs_nrates++
829 ic->ic_curmode = IEEE80211_MODE_AUTO;
830 if (isset(ic->ic_modecaps, IEEE80211_MODE_11A))
831 ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0;
832 if (isset(ic->ic_modecaps, IEEE80211_MODE_11B))
833 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0;
834 if (isset(ic->ic_modecaps, IEEE80211_MODE_11G))
835 ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0;
836 for (i = 0; i < len; i++) {
837 switch (rates[i] & IEEE80211_RATE_VAL) {
843 if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) {
844 /* Lazy-init 802.11b. */
845 setbit(ic->ic_modecaps,
847 ic->ic_sup_rates[IEEE80211_MODE_11B].
850 SETRATE(IEEE80211_MODE_11B, rates[i]);
851 INCRATE(IEEE80211_MODE_11B);
854 if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
855 SETRATE(IEEE80211_MODE_11A, rates[i]);
856 INCRATE(IEEE80211_MODE_11A);
858 if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
859 SETRATE(IEEE80211_MODE_11G, rates[i]);
860 INCRATE(IEEE80211_MODE_11G);
867 * If the hardware supports 802.11g, it most
868 * likely supports 802.11b and all of the
869 * 802.11b and 802.11g speeds, so maybe we can
870 * just cheat here. Just how in the heck do
871 * we detect turbo modes, though?
873 if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
874 TESTSETRATE(IEEE80211_MODE_11B,
875 IEEE80211_RATE_BASIC|2);
876 TESTSETRATE(IEEE80211_MODE_11B,
877 IEEE80211_RATE_BASIC|4);
878 TESTSETRATE(IEEE80211_MODE_11B,
879 IEEE80211_RATE_BASIC|11);
880 TESTSETRATE(IEEE80211_MODE_11B,
881 IEEE80211_RATE_BASIC|22);
883 if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
884 TESTSETRATE(IEEE80211_MODE_11G, 48);
885 TESTSETRATE(IEEE80211_MODE_11G, 72);
886 TESTSETRATE(IEEE80211_MODE_11G, 96);
887 TESTSETRATE(IEEE80211_MODE_11G, 108);
889 if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
890 TESTSETRATE(IEEE80211_MODE_11A, 48);
891 TESTSETRATE(IEEE80211_MODE_11A, 72);
892 TESTSETRATE(IEEE80211_MODE_11A, 96);
893 TESTSETRATE(IEEE80211_MODE_11A, 108);
897 ieee80211_init_channels(ic, NULL, &bands);
900 * To test for WPA support, we need to see if we can
901 * set AUTHENTICATION_MODE to WPA and read it back
905 arg = NDIS_80211_AUTHMODE_WPA;
906 r = ndis_set_info(sc,
907 OID_802_11_AUTHENTICATION_MODE, &arg, &i);
909 r = ndis_get_info(sc,
910 OID_802_11_AUTHENTICATION_MODE, &arg, &i);
911 if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA)
912 ic->ic_caps |= IEEE80211_C_WPA;
916 * To test for supported ciphers, we set each
917 * available encryption type in descending order.
918 * If ENC3 works, then we have WEP, TKIP and AES.
919 * If only ENC2 works, then we have WEP and TKIP.
920 * If only ENC1 works, then we have just WEP.
923 arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
924 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
926 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
927 | IEEE80211_CRYPTO_TKIP
928 | IEEE80211_CRYPTO_AES_CCM;
931 arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
932 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
934 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
935 | IEEE80211_CRYPTO_TKIP;
938 arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
939 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
941 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
944 r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
946 ic->ic_caps |= IEEE80211_C_PMGT;
948 r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i);
950 ic->ic_caps |= IEEE80211_C_TXPMGT;
952 ieee80211_ifattach(ic, eaddr);
953 ic->ic_raw_xmit = ndis_raw_xmit;
954 ic->ic_scan_start = ndis_scan_start;
955 ic->ic_scan_end = ndis_scan_end;
956 ic->ic_set_channel = ndis_set_channel;
957 ic->ic_scan_curchan = ndis_scan_curchan;
958 ic->ic_scan_mindwell = ndis_scan_mindwell;
959 ic->ic_bsschan = IEEE80211_CHAN_ANYC;
960 //ic->ic_bss->ni_chan = ic->ic_bsschan;
961 ic->ic_vap_create = ndis_vap_create;
962 ic->ic_vap_delete = ndis_vap_delete;
963 ic->ic_update_mcast = ndis_update_mcast;
964 ic->ic_update_promisc = ndis_update_promisc;
967 ieee80211_announce(ic);
970 ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
972 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
973 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
974 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
975 ifmedia_add(&sc->ifmedia,
976 IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
977 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
978 ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
979 ether_ifattach(ifp, eaddr, NULL);
988 if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
991 DPRINTF(("attach done.\n"));
992 /* We're done talking to the NIC for now; halt it. */
994 DPRINTF(("halting done.\n"));
999 static struct ieee80211vap *
1000 ndis_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
1001 enum ieee80211_opmode opmode, int flags,
1002 const uint8_t bssid[IEEE80211_ADDR_LEN],
1003 const uint8_t mac[IEEE80211_ADDR_LEN])
1005 struct ndis_vap *nvp;
1006 struct ieee80211vap *vap;
1008 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1010 nvp = (struct ndis_vap *) kmalloc(sizeof(struct ndis_vap),
1011 M_80211_VAP, M_NOWAIT | M_ZERO);
1015 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
1016 /* override with driver methods */
1017 nvp->newstate = vap->iv_newstate;
1018 vap->iv_newstate = ndis_newstate;
1020 /* complete setup */
1021 ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status);
1022 ic->ic_opmode = opmode;
1023 /* install key handing routines */
1024 vap->iv_key_set = ndis_add_key;
1025 vap->iv_key_delete = ndis_del_key;
1030 ndis_vap_delete(struct ieee80211vap *vap)
1032 struct ndis_vap *nvp = NDIS_VAP(vap);
1033 struct ieee80211com *ic = vap->iv_ic;
1034 struct ifnet *ifp = ic->ic_ifp;
1035 struct ndis_softc *sc = ifp->if_softc;
1038 callout_stop_sync(&sc->ndis_scan_callout);
1039 ieee80211_vap_detach(vap);
1040 kfree(nvp, M_80211_VAP);
1044 * Shutdown hardware and free up resources. This can be called any
1045 * time after the mutex has been initialized. It is called in both
1046 * the error case in attach and the normal detach case so it needs
1047 * to be careful about only freeing resources that have actually been
1051 ndis_detach(device_t dev)
1053 struct ndis_softc *sc;
1057 sc = device_get_softc(dev);
1060 ifp->if_flags &= ~IFF_UP;
1062 if (device_is_attached(dev)) {
1066 ieee80211_ifdetach(ifp->if_l2com);
1068 ether_ifdetach(ifp);
1072 if (sc->ndis_tickitem != NULL)
1073 IoFreeWorkItem(sc->ndis_tickitem);
1074 if (sc->ndis_startitem != NULL)
1075 IoFreeWorkItem(sc->ndis_startitem);
1076 if (sc->ndis_resetitem != NULL)
1077 IoFreeWorkItem(sc->ndis_resetitem);
1078 if (sc->ndis_inputitem != NULL)
1079 IoFreeWorkItem(sc->ndis_inputitem);
1081 if (sc->ndisusb_xferdoneitem != NULL)
1082 IoFreeWorkItem(sc->ndisusb_xferdoneitem);
1083 if (sc->ndisusb_taskitem != NULL)
1084 IoFreeWorkItem(sc->ndisusb_taskitem);
1086 if (sc->ndisusb_xferitem != NULL)
1087 IoFreeWorkItem(sc->ndisusb_xferitem);
1090 bus_generic_detach(dev);
1091 ndis_unload_driver(sc);
1094 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ndis_irq);
1095 if (sc->ndis_res_io)
1096 bus_release_resource(dev, SYS_RES_IOPORT,
1097 sc->ndis_io_rid, sc->ndis_res_io);
1098 if (sc->ndis_res_mem)
1099 bus_release_resource(dev, SYS_RES_MEMORY,
1100 sc->ndis_mem_rid, sc->ndis_res_mem);
1101 if (sc->ndis_res_altmem)
1102 bus_release_resource(dev, SYS_RES_MEMORY,
1103 sc->ndis_altmem_rid, sc->ndis_res_altmem);
1108 if (sc->ndis_iftype == PCMCIABus)
1112 ndis_destroy_dma(sc);
1114 if (sc->ndis_txarray)
1115 kfree(sc->ndis_txarray, M_DEVBUF);
1117 if (!sc->ndis_80211)
1118 ifmedia_removeall(&sc->ifmedia);
1120 if (sc->ndis_txpool != NULL)
1121 NdisFreePacketPool(sc->ndis_txpool);
1123 /* Destroy the PDO for this device. */
1125 if (sc->ndis_iftype == PCIBus)
1126 drv = windrv_lookup(0, "PCI Bus");
1127 else if (sc->ndis_iftype == PCMCIABus)
1128 drv = windrv_lookup(0, "PCCARD Bus");
1130 drv = windrv_lookup(0, "USB Bus");
1132 panic("couldn't find driver object");
1133 windrv_destroy_pdo(drv, dev);
1135 if (sc->ndis_iftype == PCIBus)
1136 bus_dma_tag_destroy(sc->ndis_parent_tag);
1142 ndis_suspend(device_t dev)
1145 struct ndis_softc *sc;
1147 wlan_serialize_enter();
1148 sc = device_get_softc(dev);
1150 if (NDIS_INITIALIZED(sc))
1153 wlan_serialize_exit();
1159 ndis_resume(device_t dev)
1161 struct ndis_softc *sc;
1163 wlan_serialize_enter();
1164 sc = device_get_softc(dev);
1166 if (NDIS_INITIALIZED(sc))
1169 wlan_serialize_exit();
1174 * The following bunch of routines are here to support drivers that
1175 * use the NdisMEthIndicateReceive()/MiniportTransferData() mechanism.
1176 * The NdisMEthIndicateReceive() handler runs at DISPATCH_LEVEL for
1177 * serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
1181 ndis_rxeof_eth(ndis_handle adapter, ndis_handle ctx, char *addr, void *hdr,
1182 uint32_t hdrlen, void *lookahead, uint32_t lookaheadlen, uint32_t pktlen)
1184 ndis_miniport_block *block;
1194 m = m_getcl(MB_DONTWAIT, MT_DATA, M_PKTHDR);
1198 /* Save the data provided to us so far. */
1200 m->m_len = lookaheadlen + hdrlen;
1201 m->m_pkthdr.len = pktlen + hdrlen;
1203 m_copyback(m, 0, hdrlen, hdr);
1204 m_copyback(m, hdrlen, lookaheadlen, lookahead);
1206 /* Now create a fake NDIS_PACKET to hold the data */
1208 NdisAllocatePacket(&status, &p, block->nmb_rxpool);
1210 if (status != NDIS_STATUS_SUCCESS) {
1217 b = IoAllocateMdl(m->m_data, m->m_pkthdr.len, FALSE, FALSE, NULL);
1225 p->np_private.npp_head = p->np_private.npp_tail = b;
1226 p->np_private.npp_totlen = m->m_pkthdr.len;
1228 /* Save the packet RX context somewhere. */
1229 priv = (ndis_ethpriv *)&p->np_protocolreserved;
1230 priv->nep_ctx = ctx;
1232 if (!NDIS_SERIALIZED(block))
1233 KeAcquireSpinLock(&block->nmb_lock, &irql);
1235 InsertTailList((&block->nmb_packetlist), (&p->np_list));
1237 if (!NDIS_SERIALIZED(block))
1238 KeReleaseSpinLock(&block->nmb_lock, irql);
1242 * NdisMEthIndicateReceiveComplete() handler, runs at DISPATCH_LEVEL
1243 * for serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
1247 ndis_rxeof_done(ndis_handle adapter)
1249 struct ndis_softc *sc;
1250 ndis_miniport_block *block;
1254 /* Schedule transfer/RX of queued packets. */
1256 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1258 KeInsertQueueDpc(&sc->ndis_rxdpc, NULL, NULL);
1262 * MiniportTransferData() handler, runs at DISPATCH_LEVEL.
1265 ndis_rxeof_xfr(kdpc *dpc, ndis_handle adapter, void *sysarg1, void *sysarg2)
1267 ndis_miniport_block *block;
1268 struct ndis_softc *sc;
1277 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1280 KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
1282 l = block->nmb_packetlist.nle_flink;
1283 while(!IsListEmpty(&block->nmb_packetlist)) {
1284 l = RemoveHeadList((&block->nmb_packetlist));
1285 p = CONTAINING_RECORD(l, ndis_packet, np_list);
1286 InitializeListHead((&p->np_list));
1288 priv = (ndis_ethpriv *)&p->np_protocolreserved;
1293 KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
1295 status = MSCALL6(sc->ndis_chars->nmc_transferdata_func,
1296 p, &p->np_private.npp_totlen, block, priv->nep_ctx,
1297 m->m_len, m->m_pkthdr.len - m->m_len);
1299 KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
1302 * If status is NDIS_STATUS_PENDING, do nothing and
1303 * wait for a callback to the ndis_rxeof_xfr_done()
1307 m->m_len = m->m_pkthdr.len;
1308 m->m_pkthdr.rcvif = ifp;
1310 if (status == NDIS_STATUS_SUCCESS) {
1311 IoFreeMdl(p->np_private.npp_head);
1313 KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1314 IF_ENQUEUE(&sc->ndis_rxqueue, m);
1315 KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1316 IoQueueWorkItem(sc->ndis_inputitem,
1317 (io_workitem_func)ndis_inputtask_wrap,
1318 WORKQUEUE_CRITICAL, ifp);
1321 if (status == NDIS_STATUS_FAILURE)
1324 /* Advance to next packet */
1325 l = block->nmb_packetlist.nle_flink;
1328 KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
1332 * NdisMTransferDataComplete() handler, runs at DISPATCH_LEVEL.
1335 ndis_rxeof_xfr_done(ndis_handle adapter, ndis_packet *packet, uint32_t status,
1338 ndis_miniport_block *block;
1339 struct ndis_softc *sc;
1344 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1348 IoFreeMdl(packet->np_private.npp_head);
1349 NdisFreePacket(packet);
1351 if (status != NDIS_STATUS_SUCCESS) {
1356 m->m_len = m->m_pkthdr.len;
1357 m->m_pkthdr.rcvif = ifp;
1358 KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1359 IF_ENQUEUE(&sc->ndis_rxqueue, m);
1360 KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1361 IoQueueWorkItem(sc->ndis_inputitem,
1362 (io_workitem_func)ndis_inputtask_wrap,
1363 WORKQUEUE_CRITICAL, ifp);
1366 * A frame has been uploaded: pass the resulting mbuf chain up to
1367 * the higher level protocols.
1369 * When handling received NDIS packets, the 'status' field in the
1370 * out-of-band portion of the ndis_packet has special meaning. In the
1371 * most common case, the underlying NDIS driver will set this field
1372 * to NDIS_STATUS_SUCCESS, which indicates that it's ok for us to
1373 * take posession of it. We then change the status field to
1374 * NDIS_STATUS_PENDING to tell the driver that we now own the packet,
1375 * and that we will return it at some point in the future via the
1376 * return packet handler.
1378 * If the driver hands us a packet with a status of NDIS_STATUS_RESOURCES,
1379 * this means the driver is running out of packet/buffer resources and
1380 * wants to maintain ownership of the packet. In this case, we have to
1381 * copy the packet data into local storage and let the driver keep the
1385 ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt)
1387 struct ndis_softc *sc;
1388 ndis_miniport_block *block;
1391 ndis_tcpip_csum *csum;
1393 struct mbuf *m0, *m;
1396 block = (ndis_miniport_block *)adapter;
1397 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1401 * There's a slim chance the driver may indicate some packets
1402 * before we're completely ready to handle them. If we detect this,
1403 * we need to return them to the miniport and ignore them.
1405 if (!(ifp->if_flags & IFF_RUNNING)) {
1406 for (i = 0; i < pktcnt; i++) {
1408 if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) {
1410 ndis_return_packet(p);
1416 for (i = 0; i < pktcnt; i++) {
1418 /* Stash the softc here so ptom can use it. */
1420 if (ndis_ptom(&m0, p)) {
1421 device_printf(sc->ndis_dev, "ptom failed\n");
1422 if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS)
1423 ndis_return_packet(p);
1426 if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) {
1427 m = m_dup(m0, MB_DONTWAIT);
1429 * NOTE: we want to destroy the mbuf here, but
1430 * we don't actually want to return it to the
1431 * driver via the return packet handler. By
1432 * bumping np_refcnt, we can prevent the
1433 * ndis_return_packet() routine from actually
1443 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1445 m = m_dup(m0, MB_DONTWAIT);
1446 if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES)
1449 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1452 IFNET_STAT_INC(ifp, ierrors, 1);
1456 m0->m_pkthdr.rcvif = ifp;
1458 /* Deal with checksum offload. */
1460 if (ifp->if_capenable & IFCAP_RXCSUM &&
1461 p->np_ext.npe_info[ndis_tcpipcsum_info] != NULL) {
1463 p->np_ext.npe_info[ndis_tcpipcsum_info];
1464 csum = (ndis_tcpip_csum *)&s;
1465 if (csum->u.ntc_rxflags &
1466 NDIS_RXCSUM_IP_PASSED)
1467 m0->m_pkthdr.csum_flags |=
1468 CSUM_IP_CHECKED|CSUM_IP_VALID;
1469 if (csum->u.ntc_rxflags &
1470 (NDIS_RXCSUM_TCP_PASSED |
1471 NDIS_RXCSUM_UDP_PASSED)) {
1472 m0->m_pkthdr.csum_flags |=
1473 CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
1474 m0->m_pkthdr.csum_data = 0xFFFF;
1478 KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
1479 IF_ENQUEUE(&sc->ndis_rxqueue, m0);
1480 KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
1481 IoQueueWorkItem(sc->ndis_inputitem,
1482 (io_workitem_func)ndis_inputtask_wrap,
1483 WORKQUEUE_CRITICAL, ifp);
1489 * This routine is run at PASSIVE_LEVEL. We use this routine to pass
1490 * packets into the stack in order to avoid calling ifp->if_input()
1491 * with any locks held (at DISPATCH_LEVEL, we'll be holding the
1492 * 'dispatch level' per-cpu sleep lock).
1495 ndis_inputtask(device_object *dobj, void *arg)
1498 struct ndis_softc *sc;
1500 struct ieee80211com *ic;
1501 struct ieee80211vap *vap;
1507 vap = TAILQ_FIRST(&ic->ic_vaps);
1509 KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1511 IF_DEQUEUE(&sc->ndis_rxqueue, m);
1514 KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1515 if ((sc->ndis_80211 != 0) && (vap != NULL))
1516 vap->iv_deliver_data(vap, vap->iv_bss, m);
1518 ifp->if_input(ifp, m, NULL, -1);
1519 KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1521 KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1525 * A frame was downloaded to the chip. It's safe for us to clean up
1529 ndis_txeof(ndis_handle adapter, ndis_packet *packet, ndis_status status)
1531 struct ndis_softc *sc;
1532 ndis_miniport_block *block;
1537 block = (ndis_miniport_block *)adapter;
1538 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1542 idx = packet->np_txidx;
1544 bus_dmamap_unload(sc->ndis_ttag, sc->ndis_tmaps[idx]);
1546 ndis_free_packet(packet);
1550 sc->ndis_txarray[idx] = NULL;
1551 sc->ndis_txpending++;
1553 if (status == NDIS_STATUS_SUCCESS)
1554 IFNET_STAT_INC(ifp, opackets, 1);
1556 IFNET_STAT_INC(ifp, oerrors, 1);
1558 sc->ndis_tx_timer = 0;
1559 ifq_clr_oactive(&ifp->if_snd);
1563 IoQueueWorkItem(sc->ndis_startitem,
1564 (io_workitem_func)ndis_starttask_wrap,
1565 WORKQUEUE_CRITICAL, ifp);
1569 ndis_linksts(ndis_handle adapter, ndis_status status, void *sbuf,
1572 ndis_miniport_block *block;
1573 struct ndis_softc *sc;
1576 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1577 sc->ndis_sts = status;
1579 /* Event list is all full up, drop this one. */
1582 if (sc->ndis_evt[sc->ndis_evtpidx].ne_sts) {
1587 /* Cache the event. */
1590 sc->ndis_evt[sc->ndis_evtpidx].ne_buf = kmalloc(slen,
1592 if (sc->ndis_evt[sc->ndis_evtpidx].ne_buf == NULL) {
1597 sc->ndis_evt[sc->ndis_evtpidx].ne_buf, slen);
1599 sc->ndis_evt[sc->ndis_evtpidx].ne_sts = status;
1600 sc->ndis_evt[sc->ndis_evtpidx].ne_len = slen;
1601 NDIS_EVTINC(sc->ndis_evtpidx);
1606 ndis_linksts_done(ndis_handle adapter)
1608 ndis_miniport_block *block;
1609 struct ndis_softc *sc;
1613 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1616 if (!NDIS_INITIALIZED(sc))
1619 switch (sc->ndis_sts) {
1620 case NDIS_STATUS_MEDIA_CONNECT:
1621 IoQueueWorkItem(sc->ndis_tickitem,
1622 (io_workitem_func)ndis_ticktask_wrap,
1623 WORKQUEUE_CRITICAL, sc);
1624 IoQueueWorkItem(sc->ndis_startitem,
1625 (io_workitem_func)ndis_starttask_wrap,
1626 WORKQUEUE_CRITICAL, ifp);
1628 case NDIS_STATUS_MEDIA_DISCONNECT:
1630 IoQueueWorkItem(sc->ndis_tickitem,
1631 (io_workitem_func)ndis_ticktask_wrap,
1632 WORKQUEUE_CRITICAL, sc);
1640 ndis_tick(void *xsc)
1642 struct ndis_softc *sc;
1646 if (sc->ndis_hang_timer && --sc->ndis_hang_timer == 0) {
1647 IoQueueWorkItem(sc->ndis_tickitem,
1648 (io_workitem_func)ndis_ticktask_wrap,
1649 WORKQUEUE_CRITICAL, sc);
1650 sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
1653 if (sc->ndis_tx_timer && --sc->ndis_tx_timer == 0) {
1654 IFNET_STAT_INC(sc->ifp, oerrors, 1);
1655 device_printf(sc->ndis_dev, "watchdog timeout\n");
1657 IoQueueWorkItem(sc->ndis_resetitem,
1658 (io_workitem_func)ndis_resettask_wrap,
1659 WORKQUEUE_CRITICAL, sc);
1660 IoQueueWorkItem(sc->ndis_startitem,
1661 (io_workitem_func)ndis_starttask_wrap,
1662 WORKQUEUE_CRITICAL, sc->ifp);
1665 callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
1669 ndis_ticktask(device_object *d, void *xsc)
1671 struct ndis_softc *sc;
1672 struct ieee80211com *ic;
1673 struct ieee80211vap *vap;
1674 ndis_checkforhang_handler hangfunc;
1678 ic = sc->ifp->if_l2com;
1679 vap = TAILQ_FIRST(&ic->ic_vaps);
1682 if (!NDIS_INITIALIZED(sc)) {
1688 hangfunc = sc->ndis_chars->nmc_checkhang_func;
1690 if (hangfunc != NULL) {
1691 rval = MSCALL1(hangfunc,
1692 sc->ndis_block->nmb_miniportadapterctx);
1700 if (sc->ndis_link == 0 &&
1701 sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) {
1704 if ((sc->ndis_80211 != 0) && (vap != NULL)) {
1705 ndis_getstate_80211(sc);
1706 ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
1709 sc->ifp->if_link_state = LINK_STATE_UP;
1710 if_link_state_change(sc->ifp);
1713 if (sc->ndis_link == 1 &&
1714 sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
1717 if ((sc->ndis_80211 != 0) && (vap != NULL))
1718 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1720 sc->ifp->if_link_state = LINK_STATE_DOWN;
1721 if_link_state_change(sc->ifp);
1728 ndis_map_sclist(void *arg, bus_dma_segment_t *segs, int nseg,
1729 bus_size_t mapsize, int error)
1731 struct ndis_sc_list *sclist;
1734 if (error || arg == NULL)
1739 sclist->nsl_frags = nseg;
1741 for (i = 0; i < nseg; i++) {
1742 sclist->nsl_elements[i].nse_addr.np_quad = segs[i].ds_addr;
1743 sclist->nsl_elements[i].nse_len = segs[i].ds_len;
1748 ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1749 const struct ieee80211_bpf_params *params)
1751 /* no support; just discard */
1753 ieee80211_free_node(ni);
1758 ndis_update_mcast(struct ifnet *ifp)
1760 struct ndis_softc *sc = ifp->if_softc;
1766 ndis_update_promisc(struct ifnet *ifp)
1772 ndis_starttask(device_object *d, void *arg)
1778 lwkt_serialize_enter(ifp->if_serializer);
1779 if (!ifq_is_empty(&ifp->if_snd))
1781 lwkt_serialize_exit(ifp->if_serializer);
1785 * Main transmit routine. To make NDIS drivers happy, we need to
1786 * transform mbuf chains into NDIS packets and feed them to the
1787 * send packet routines. Most drivers allow you to send several
1788 * packets at once (up to the maxpkts limit). Unfortunately, rather
1789 * that accepting them in the form of a linked list, they expect
1790 * a contiguous array of pointers to packets.
1792 * For those drivers which use the NDIS scatter/gather DMA mechanism,
1793 * we need to perform busdma work here. Those that use map registers
1794 * will do the mapping themselves on a buffer by buffer basis.
1797 ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1799 struct ndis_softc *sc;
1800 struct mbuf *m = NULL;
1801 ndis_packet **p0 = NULL, *p = NULL;
1802 ndis_tcpip_csum *csum;
1803 int pcnt = 0, status;
1805 ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
1810 if (!sc->ndis_link) {
1811 ifq_purge(&ifp->if_snd);
1816 if (ifq_is_oactive(&ifp->if_snd)) {
1821 p0 = &sc->ndis_txarray[sc->ndis_txidx];
1823 while(sc->ndis_txpending) {
1824 m = ifq_dequeue(&ifp->if_snd);
1828 NdisAllocatePacket(&status,
1829 &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool);
1831 if (status != NDIS_STATUS_SUCCESS)
1834 if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) {
1835 ifq_prepend(&ifp->if_snd, m);
1841 * Save pointer to original mbuf
1842 * so we can free it later.
1845 p = sc->ndis_txarray[sc->ndis_txidx];
1846 p->np_txidx = sc->ndis_txidx;
1848 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1851 * Do scatter/gather processing, if driver requested it.
1854 bus_dmamap_load_mbuf(sc->ndis_ttag,
1855 sc->ndis_tmaps[sc->ndis_txidx], m,
1856 ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT);
1857 bus_dmamap_sync(sc->ndis_ttag,
1858 sc->ndis_tmaps[sc->ndis_txidx],
1859 BUS_DMASYNC_PREREAD);
1860 p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist;
1863 /* Handle checksum offload. */
1865 if (ifp->if_capenable & IFCAP_TXCSUM &&
1866 m->m_pkthdr.csum_flags) {
1867 csum = (ndis_tcpip_csum *)
1868 &p->np_ext.npe_info[ndis_tcpipcsum_info];
1869 csum->u.ntc_txflags = NDIS_TXCSUM_DO_IPV4;
1870 if (m->m_pkthdr.csum_flags & CSUM_IP)
1871 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_IP;
1872 if (m->m_pkthdr.csum_flags & CSUM_TCP)
1873 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_TCP;
1874 if (m->m_pkthdr.csum_flags & CSUM_UDP)
1875 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_UDP;
1876 p->np_private.npp_flags = NDIS_PROTOCOL_ID_TCP_IP;
1880 sc->ndis_txpending--;
1885 * If there's a BPF listener, bounce a copy of this frame
1888 if (!sc->ndis_80211) /* XXX handle 80211 */
1892 * The array that p0 points to must appear contiguous,
1893 * so we must not wrap past the end of sc->ndis_txarray[].
1894 * If it looks like we're about to wrap, break out here
1895 * so the this batch of packets can be transmitted, then
1896 * wait for txeof to ask us to send the rest.
1898 if (sc->ndis_txidx == 0)
1907 if (sc->ndis_txpending == 0)
1908 ifq_set_oactive(&ifp->if_snd);
1911 * Set a timeout in case the chip goes out to lunch.
1913 sc->ndis_tx_timer = 5;
1918 * According to NDIS documentation, if a driver exports
1919 * a MiniportSendPackets() routine, we prefer that over
1920 * a MiniportSend() routine (which sends just a single
1923 if (sc->ndis_chars->nmc_sendmulti_func != NULL)
1924 ndis_send_packets(sc, p0, pcnt);
1926 ndis_send_packet(sc, p);
1932 ndis_init(void *xsc)
1934 struct ndis_softc *sc = xsc;
1935 struct ifnet *ifp = sc->ifp;
1936 struct ieee80211com *ic = ifp->if_l2com;
1940 * Avoid reintializing the link unnecessarily.
1941 * This should be dealt with in a better way by
1942 * fixing the upper layer modules so they don't
1943 * call ifp->if_init() quite as often.
1949 * Cancel pending I/O and free all RX/TX buffers.
1953 if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0)) {
1954 error = ndis_init_nic(sc);
1956 device_printf(sc->ndis_dev,
1957 "failed to initialize the device: %d\n", error);
1962 /* Init our MAC address */
1964 /* Program the packet filter */
1966 sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
1968 if (ifp->if_flags & IFF_BROADCAST)
1969 sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
1971 if (ifp->if_flags & IFF_PROMISC)
1972 sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
1974 len = sizeof(sc->ndis_filter);
1976 error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
1977 &sc->ndis_filter, &len);
1980 device_printf(sc->ndis_dev, "set filter failed: %d\n", error);
1987 ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len);
1990 * Program the multicast filter, if necessary.
1994 /* Setup task offload. */
1995 ndis_set_offload(sc);
2000 sc->ndis_txpending = sc->ndis_maxpkts;
2003 sc->ifp->if_link_state = LINK_STATE_UNKNOWN;
2004 if_link_state_change(sc->ifp);
2006 ifp->if_flags |= IFF_RUNNING;
2007 ifq_clr_oactive(&ifp->if_snd);
2008 sc->ndis_tx_timer = 0;
2011 * Some drivers don't set this value. The NDIS spec says
2012 * the default checkforhang timeout is "approximately 2
2013 * seconds." We use 3 seconds, because it seems for some
2014 * drivers, exactly 2 seconds is too fast.
2016 if (sc->ndis_block->nmb_checkforhangsecs == 0)
2017 sc->ndis_block->nmb_checkforhangsecs = 3;
2019 sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
2020 callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
2023 /* XXX force handling */
2025 ieee80211_start_all(ic); /* start all vap's */
2029 * Set media options.
2032 ndis_ifmedia_upd(struct ifnet *ifp)
2034 struct ndis_softc *sc;
2038 if (NDIS_INITIALIZED(sc))
2045 * Report current media status.
2048 ndis_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
2050 struct ndis_softc *sc;
2051 uint32_t media_info;
2052 ndis_media_state linkstate;
2055 ifmr->ifm_status = IFM_AVALID;
2056 ifmr->ifm_active = IFM_ETHER;
2059 if (!NDIS_INITIALIZED(sc))
2062 len = sizeof(linkstate);
2063 ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
2064 (void *)&linkstate, &len);
2066 len = sizeof(media_info);
2067 ndis_get_info(sc, OID_GEN_LINK_SPEED,
2068 (void *)&media_info, &len);
2070 if (linkstate == nmc_connected)
2071 ifmr->ifm_status |= IFM_ACTIVE;
2073 switch (media_info) {
2075 ifmr->ifm_active |= IFM_10_T;
2078 ifmr->ifm_active |= IFM_100_TX;
2081 ifmr->ifm_active |= IFM_1000_T;
2084 device_printf(sc->ndis_dev, "unknown speed: %d\n", media_info);
2090 ndis_set_cipher(struct ndis_softc *sc, int cipher)
2092 struct ieee80211com *ic;
2096 ic = sc->ifp->if_l2com;
2100 if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) {
2101 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP))
2103 arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
2106 if (cipher == WPA_CSE_TKIP) {
2107 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP))
2109 arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
2112 if (cipher == WPA_CSE_CCMP) {
2113 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM))
2115 arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
2118 DPRINTF(("Setting cipher to %d\n", arg));
2120 rval = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2125 /* Check that the cipher was set correctly. */
2128 rval = ndis_get_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2130 if (rval != 0 || arg != save)
2137 * WPA is hairy to set up. Do the work in a separate routine
2138 * so we don't clutter the setstate function too much.
2139 * Important yet undocumented fact: first we have to set the
2140 * authentication mode, _then_ we enable the ciphers. If one
2141 * of the WPA authentication modes isn't enabled, the driver
2142 * might not permit the TKIP or AES ciphers to be selected.
2145 ndis_set_wpa(struct ndis_softc *sc, void *ie, int ielen)
2147 struct ieee80211_ie_wpa *w;
2154 * Apparently, the only way for us to know what ciphers
2155 * and key management/authentication mode to use is for
2156 * us to inspect the optional information element (IE)
2157 * stored in the 802.11 state machine. This IE should be
2158 * supplied by the WPA supplicant.
2161 w = (struct ieee80211_ie_wpa *)ie;
2163 /* Check for the right kind of IE. */
2164 if (w->wpa_id != IEEE80211_ELEMID_VENDOR) {
2165 DPRINTF(("Incorrect IE type %d\n", w->wpa_id));
2169 /* Skip over the ucast cipher OIDs. */
2170 pos = (char *)&w->wpa_uciphers[0];
2171 pos += w->wpa_uciphercnt * sizeof(struct ndis_ie);
2173 /* Skip over the authmode count. */
2174 pos += sizeof(u_int16_t);
2177 * Check for the authentication modes. I'm
2178 * pretty sure there's only supposed to be one.
2181 n = (struct ndis_ie *)pos;
2182 if (n->ni_val == WPA_ASE_NONE)
2183 arg = NDIS_80211_AUTHMODE_WPANONE;
2185 if (n->ni_val == WPA_ASE_8021X_UNSPEC)
2186 arg = NDIS_80211_AUTHMODE_WPA;
2188 if (n->ni_val == WPA_ASE_8021X_PSK)
2189 arg = NDIS_80211_AUTHMODE_WPAPSK;
2191 DPRINTF(("Setting WPA auth mode to %d\n", arg));
2193 if (ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i))
2196 ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
2198 /* Now configure the desired ciphers. */
2200 /* First, set up the multicast group cipher. */
2201 n = (struct ndis_ie *)&w->wpa_mcipher[0];
2203 if (ndis_set_cipher(sc, n->ni_val))
2206 /* Now start looking around for the unicast ciphers. */
2207 pos = (char *)&w->wpa_uciphers[0];
2208 n = (struct ndis_ie *)pos;
2210 for (i = 0; i < w->wpa_uciphercnt; i++) {
2211 if (ndis_set_cipher(sc, n->ni_val))
2220 ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
2222 struct ieee80211vap *vap = ifp->if_softc;
2223 struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc;
2227 if (!NDIS_INITIALIZED(sc))
2230 len = sizeof(txrate);
2231 if (ndis_get_info(sc, OID_GEN_LINK_SPEED, &txrate, &len) == 0)
2232 vap->iv_bss->ni_txrate = txrate / 5000;
2233 ieee80211_media_status(ifp, imr);
2237 ndis_setstate_80211(struct ndis_softc *sc)
2239 struct ieee80211com *ic;
2240 struct ieee80211vap *vap;
2241 ndis_80211_macaddr bssid;
2242 ndis_80211_config config;
2246 char ethstr[ETHER_ADDRSTRLEN + 1];
2250 vap = TAILQ_FIRST(&ic->ic_vaps);
2252 if (!NDIS_INITIALIZED(sc)) {
2253 DPRINTF(("%s: NDIS not initialized\n", __func__));
2257 /* Disassociate and turn off radio. */
2260 ndis_set_info(sc, OID_802_11_DISASSOCIATE, &arg, &len);
2262 /* Set network infrastructure mode. */
2265 if (ic->ic_opmode == IEEE80211_M_IBSS)
2266 arg = NDIS_80211_NET_INFRA_IBSS;
2268 arg = NDIS_80211_NET_INFRA_BSS;
2270 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2273 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2275 /* Set power management */
2277 if (vap->iv_flags & IEEE80211_F_PMGTON)
2278 arg = NDIS_80211_POWERMODE_FAST_PSP;
2280 arg = NDIS_80211_POWERMODE_CAM;
2281 ndis_set_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2284 if ((ic->ic_caps & IEEE80211_C_TXPMGT) &&
2285 ic->ic_txpowlimit < NELEM(dBm2mW)) {
2286 arg = dBm2mW[ic->ic_txpowlimit];
2288 ndis_set_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2292 * Default encryption mode to off, authentication
2293 * to open and privacy to 'accept everything.'
2296 arg = NDIS_80211_WEPSTAT_DISABLED;
2297 ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2300 arg = NDIS_80211_AUTHMODE_OPEN;
2301 ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2304 * Note that OID_802_11_PRIVACY_FILTER is optional:
2305 * not all drivers implement it.
2308 arg = NDIS_80211_PRIVFILT_8021XWEP;
2309 ndis_set_info(sc, OID_802_11_PRIVACY_FILTER, &arg, &len);
2311 len = sizeof(config);
2312 bzero((char *)&config, len);
2313 config.nc_length = len;
2314 config.nc_fhconfig.ncf_length = sizeof(ndis_80211_config_fh);
2315 rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len);
2318 * Some drivers expect us to initialize these values, so
2319 * provide some defaults.
2322 if (config.nc_beaconperiod == 0)
2323 config.nc_beaconperiod = 100;
2324 if (config.nc_atimwin == 0)
2325 config.nc_atimwin = 100;
2326 if (config.nc_fhconfig.ncf_dwelltime == 0)
2327 config.nc_fhconfig.ncf_dwelltime = 200;
2328 if (rval == 0 && ic->ic_bsschan != IEEE80211_CHAN_ANYC) {
2331 chan = ieee80211_chan2ieee(ic, ic->ic_bsschan);
2332 if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) {
2333 config.nc_dsconfig =
2334 ic->ic_bsschan->ic_freq * 1000;
2335 len = sizeof(config);
2336 config.nc_length = len;
2337 config.nc_fhconfig.ncf_length =
2338 sizeof(ndis_80211_config_fh);
2339 DPRINTF(("Setting channel to %ukHz\n", config.nc_dsconfig));
2340 rval = ndis_set_info(sc, OID_802_11_CONFIGURATION,
2343 device_printf(sc->ndis_dev, "couldn't change "
2344 "DS config to %ukHz: %d\n",
2345 config.nc_dsconfig, rval);
2348 device_printf(sc->ndis_dev, "couldn't retrieve "
2349 "channel info: %d\n", rval);
2351 /* Set the BSSID to our value so the driver doesn't associate */
2352 len = IEEE80211_ADDR_LEN;
2353 bcopy(IF_LLADDR(ifp), bssid, len);
2354 DPRINTF(("Setting BSSID to %s\n", kether_ntoa((uint8_t *)&bssid, ethstr)));
2355 rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2357 device_printf(sc->ndis_dev,
2358 "setting BSSID failed: %d\n", rval);
2362 ndis_auth_and_assoc(struct ndis_softc *sc, struct ieee80211vap *vap)
2364 struct ieee80211_node *ni;
2365 ndis_80211_ssid ssid;
2366 ndis_80211_macaddr bssid;
2368 int i, rval = 0, len, error;
2371 char ethstr[ETHER_ADDRSTRLEN + 1];
2376 if (!NDIS_INITIALIZED(sc)) {
2377 DPRINTF(("%s: NDIS not initialized\n", __func__));
2382 ndis_setstate_80211(sc);
2384 /* Set network infrastructure mode. */
2387 if (vap->iv_opmode == IEEE80211_M_IBSS)
2388 arg = NDIS_80211_NET_INFRA_IBSS;
2390 arg = NDIS_80211_NET_INFRA_BSS;
2392 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2395 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2397 /* Set RTS threshold */
2400 arg = vap->iv_rtsthreshold;
2401 ndis_set_info(sc, OID_802_11_RTS_THRESHOLD, &arg, &len);
2403 /* Set fragmentation threshold */
2406 arg = vap->iv_fragthreshold;
2407 ndis_set_info(sc, OID_802_11_FRAGMENTATION_THRESHOLD, &arg, &len);
2411 if (vap->iv_flags & IEEE80211_F_PRIVACY &&
2412 !(vap->iv_flags & IEEE80211_F_WPA)) {
2415 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
2417 arg = NDIS_80211_AUTHMODE_SHARED;
2418 DPRINTF(("Setting shared auth\n"));
2419 ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE,
2422 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2423 if (vap->iv_nw_keys[i].wk_keylen) {
2424 if (vap->iv_nw_keys[i].wk_cipher->ic_cipher !=
2425 IEEE80211_CIPHER_WEP)
2427 bzero((char *)&wep, sizeof(wep));
2428 wep.nw_keylen = vap->iv_nw_keys[i].wk_keylen;
2431 * 5, 13 and 16 are the only valid
2432 * key lengths. Anything in between
2433 * will be zero padded out to the
2434 * next highest boundary.
2436 if (vap->iv_nw_keys[i].wk_keylen < 5)
2438 else if (vap->iv_nw_keys[i].wk_keylen > 5 &&
2439 vap->iv_nw_keys[i].wk_keylen < 13)
2441 else if (vap->iv_nw_keys[i].wk_keylen > 13 &&
2442 vap->iv_nw_keys[i].wk_keylen < 16)
2446 wep.nw_length = (sizeof(uint32_t) * 3)
2448 if (i == vap->iv_def_txkey)
2449 wep.nw_keyidx |= NDIS_80211_WEPKEY_TX;
2450 bcopy(vap->iv_nw_keys[i].wk_key,
2451 wep.nw_keydata, wep.nw_length);
2453 DPRINTF(("Setting WEP key %d\n", i));
2454 rval = ndis_set_info(sc,
2455 OID_802_11_ADD_WEP, &wep, &len);
2457 device_printf(sc->ndis_dev,
2458 "set wepkey failed: %d\n", rval);
2463 DPRINTF(("Setting WEP on\n"));
2464 arg = NDIS_80211_WEPSTAT_ENABLED;
2466 rval = ndis_set_info(sc,
2467 OID_802_11_WEP_STATUS, &arg, &len);
2469 device_printf(sc->ndis_dev,
2470 "enable WEP failed: %d\n", rval);
2471 if (vap->iv_flags & IEEE80211_F_DROPUNENC)
2472 arg = NDIS_80211_PRIVFILT_8021XWEP;
2474 arg = NDIS_80211_PRIVFILT_ACCEPTALL;
2478 OID_802_11_PRIVACY_FILTER, &arg, &len);
2483 if ((vap->iv_flags & IEEE80211_F_WPA) &&
2484 vap->iv_appie_assocreq != NULL) {
2485 struct ieee80211_appie *ie = vap->iv_appie_assocreq;
2486 error = ndis_set_wpa(sc, ie->ie_data, ie->ie_len);
2488 device_printf(sc->ndis_dev, "WPA setup failed\n");
2492 /* Set network type. */
2496 switch (vap->iv_curmode) {
2497 case IEEE80211_MODE_11A:
2498 arg = NDIS_80211_NETTYPE_11OFDM5;
2500 case IEEE80211_MODE_11B:
2501 arg = NDIS_80211_NETTYPE_11DS;
2503 case IEEE80211_MODE_11G:
2504 arg = NDIS_80211_NETTYPE_11OFDM24;
2507 device_printf(sc->ndis_dev, "unknown mode: %d\n",
2512 DPRINTF(("Setting network type to %d\n", arg));
2514 rval = ndis_set_info(sc, OID_802_11_NETWORK_TYPE_IN_USE,
2517 device_printf(sc->ndis_dev,
2518 "set nettype failed: %d\n", rval);
2523 * If the user selected a specific BSSID, try
2524 * to use that one. This is useful in the case where
2525 * there are several APs in range with the same network
2526 * name. To delete the BSSID, we use the broadcast
2527 * address as the BSSID.
2528 * Note that some drivers seem to allow setting a BSSID
2529 * in ad-hoc mode, which has the effect of forcing the
2530 * NIC to create an ad-hoc cell with a specific BSSID,
2531 * instead of a randomly chosen one. However, the net80211
2532 * code makes the assumtion that the BSSID setting is invalid
2533 * when you're in ad-hoc mode, so we don't allow that here.
2536 len = IEEE80211_ADDR_LEN;
2537 if (vap->iv_flags & IEEE80211_F_DESBSSID &&
2538 vap->iv_opmode != IEEE80211_M_IBSS)
2539 bcopy(ni->ni_bssid, bssid, len);
2541 bcopy(ifp->if_broadcastaddr, bssid, len);
2543 DPRINTF(("Setting BSSID to %s\n", kether_ntoa((uint8_t *)&bssid, ethstr)));
2544 rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2546 device_printf(sc->ndis_dev,
2547 "setting BSSID failed: %d\n", rval);
2549 /* Set SSID -- always do this last. */
2552 if (ndis_debug > 0) {
2553 kprintf("Setting ESSID to ");
2554 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2560 bzero((char *)&ssid, len);
2561 ssid.ns_ssidlen = ni->ni_esslen;
2562 if (ssid.ns_ssidlen == 0) {
2563 ssid.ns_ssidlen = 1;
2565 bcopy(ni->ni_essid, ssid.ns_ssid, ssid.ns_ssidlen);
2567 rval = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
2570 device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval);
2576 ndis_get_bssid_list(struct ndis_softc *sc, ndis_80211_bssid_list_ex **bl)
2580 len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16);
2581 *bl = kmalloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2585 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2586 if (error == ENOSPC) {
2587 kfree(*bl, M_DEVBUF);
2588 *bl = kmalloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2592 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2595 DPRINTF(("%s: failed to read\n", __func__));
2596 kfree(*bl, M_DEVBUF);
2604 ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc)
2606 struct ifnet *ifp = sc->ifp;
2607 struct ieee80211com *ic = ifp->if_l2com;
2608 struct ieee80211vap *vap;
2609 struct ieee80211_node *ni;
2610 ndis_80211_bssid_list_ex *bl;
2611 ndis_wlan_bssid_ex *bs;
2612 ndis_80211_macaddr bssid;
2618 len = sizeof(bssid);
2619 error = ndis_get_info(sc, OID_802_11_BSSID, &bssid, &len);
2621 device_printf(sc->ndis_dev, "failed to get bssid\n");
2625 vap = TAILQ_FIRST(&ic->ic_vaps);
2628 error = ndis_get_bssid_list(sc, &bl);
2632 bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0];
2633 for (i = 0; i < bl->nblx_items; i++) {
2634 if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) {
2635 *assoc = kmalloc(bs->nwbx_len, M_TEMP, M_NOWAIT);
2636 if (*assoc == NULL) {
2640 bcopy((char *)bs, (char *)*assoc, bs->nwbx_len);
2642 if (ic->ic_opmode == IEEE80211_M_STA)
2643 ni->ni_associd = 1 | 0xc000; /* fake associd */
2646 bs = (ndis_wlan_bssid_ex *)((char *)bs + bs->nwbx_len);
2654 ndis_getstate_80211(struct ndis_softc *sc)
2656 struct ieee80211com *ic;
2657 struct ieee80211vap *vap;
2658 struct ieee80211_node *ni;
2659 ndis_wlan_bssid_ex *bs;
2660 int rval, len, i = 0;
2667 vap = TAILQ_FIRST(&ic->ic_vaps);
2670 if (!NDIS_INITIALIZED(sc))
2673 if ((rval = ndis_get_assoc(sc, &bs)) != 0)
2676 /* We're associated, retrieve info on the current bssid. */
2677 ic->ic_curmode = ndis_nettype_mode(bs->nwbx_nettype);
2678 chanflag = ndis_nettype_chan(bs->nwbx_nettype);
2679 IEEE80211_ADDR_COPY(ni->ni_bssid, bs->nwbx_macaddr);
2681 /* Get SSID from current association info. */
2682 bcopy(bs->nwbx_ssid.ns_ssid, ni->ni_essid,
2683 bs->nwbx_ssid.ns_ssidlen);
2684 ni->ni_esslen = bs->nwbx_ssid.ns_ssidlen;
2686 if (ic->ic_caps & IEEE80211_C_PMGT) {
2688 rval = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2691 device_printf(sc->ndis_dev,
2692 "get power mode failed: %d\n", rval);
2693 if (arg == NDIS_80211_POWERMODE_CAM)
2694 vap->iv_flags &= ~IEEE80211_F_PMGTON;
2696 vap->iv_flags |= IEEE80211_F_PMGTON;
2700 if (ic->ic_caps & IEEE80211_C_TXPMGT) {
2702 ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2703 for (i = 0; i < NELEM(dBm2mW); i++)
2704 if (dBm2mW[i] >= arg)
2706 ic->ic_txpowlimit = i;
2710 * Use the current association information to reflect
2711 * what channel we're on.
2713 ic->ic_curchan = ieee80211_find_channel(ic,
2714 bs->nwbx_config.nc_dsconfig / 1000, chanflag);
2715 if (ic->ic_curchan == NULL)
2716 ic->ic_curchan = &ic->ic_channels[0];
2717 ni->ni_chan = ic->ic_curchan;
2718 ic->ic_bsschan = ic->ic_curchan;
2723 * Determine current authentication mode.
2726 rval = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2728 device_printf(sc->ndis_dev,
2729 "get authmode status failed: %d\n", rval);
2731 vap->iv_flags &= ~IEEE80211_F_WPA;
2733 case NDIS_80211_AUTHMODE_OPEN:
2734 ni->ni_authmode = IEEE80211_AUTH_OPEN;
2736 case NDIS_80211_AUTHMODE_SHARED:
2737 ni->ni_authmode = IEEE80211_AUTH_SHARED;
2739 case NDIS_80211_AUTHMODE_AUTO:
2740 ni->ni_authmode = IEEE80211_AUTH_AUTO;
2742 case NDIS_80211_AUTHMODE_WPA:
2743 case NDIS_80211_AUTHMODE_WPAPSK:
2744 case NDIS_80211_AUTHMODE_WPANONE:
2745 ni->ni_authmode = IEEE80211_AUTH_WPA;
2746 vap->iv_flags |= IEEE80211_F_WPA1;
2748 case NDIS_80211_AUTHMODE_WPA2:
2749 case NDIS_80211_AUTHMODE_WPA2PSK:
2750 ni->ni_authmode = IEEE80211_AUTH_WPA;
2751 vap->iv_flags |= IEEE80211_F_WPA2;
2754 ni->ni_authmode = IEEE80211_AUTH_NONE;
2760 rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len);
2763 device_printf(sc->ndis_dev,
2764 "get wep status failed: %d\n", rval);
2766 if (arg == NDIS_80211_WEPSTAT_ENABLED)
2767 vap->iv_flags |= IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC;
2769 vap->iv_flags &= ~(IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC);
2773 ndis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
2775 struct ndis_softc *sc = ifp->if_softc;
2776 struct ifreq *ifr = (struct ifreq *) data;
2783 if (ifp->if_flags & IFF_UP) {
2784 if (ifp->if_flags & IFF_RUNNING &&
2785 ifp->if_flags & IFF_PROMISC &&
2786 !(sc->ndis_if_flags & IFF_PROMISC)) {
2788 NDIS_PACKET_TYPE_PROMISCUOUS;
2789 i = sizeof(sc->ndis_filter);
2790 error = ndis_set_info(sc,
2791 OID_GEN_CURRENT_PACKET_FILTER,
2792 &sc->ndis_filter, &i);
2793 } else if (ifp->if_flags & IFF_RUNNING &&
2794 !(ifp->if_flags & IFF_PROMISC) &&
2795 sc->ndis_if_flags & IFF_PROMISC) {
2797 ~NDIS_PACKET_TYPE_PROMISCUOUS;
2798 i = sizeof(sc->ndis_filter);
2799 error = ndis_set_info(sc,
2800 OID_GEN_CURRENT_PACKET_FILTER,
2801 &sc->ndis_filter, &i);
2805 if (ifp->if_flags & IFF_RUNNING)
2808 sc->ndis_if_flags = ifp->if_flags;
2818 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
2821 ifp->if_capenable = ifr->ifr_reqcap;
2822 if (ifp->if_capenable & IFCAP_TXCSUM)
2823 ifp->if_hwassist = sc->ndis_hwassist;
2825 ifp->if_hwassist = 0;
2826 ndis_set_offload(sc);
2829 error = ether_ioctl(ifp, command, data);
2833 /*NDIS_UNLOCK(sc);*/
2839 ndis_ioctl_80211(struct ifnet *ifp, u_long command, caddr_t data,
2842 struct ndis_softc *sc = ifp->if_softc;
2843 struct ieee80211com *ic = ifp->if_l2com;
2844 struct ifreq *ifr = (struct ifreq *) data;
2845 struct ndis_oid_data oid;
2846 struct ndis_evt evt;
2853 if (ifp->if_flags & IFF_UP) {
2854 if (!(ifp->if_flags & IFF_RUNNING))
2857 if (ifp->if_flags & IFF_RUNNING)
2860 sc->ndis_if_flags = ifp->if_flags;
2862 /*NDIS_UNLOCK(sc);*/
2865 if ((error = priv_check(curthread, PRIV_DRIVER)))
2867 error = copyin(ifr->ifr_data, &oid, sizeof(oid));
2870 oidbuf = kmalloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2871 if (oidbuf == NULL) {
2875 error = copyin((caddr_t)ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2877 kfree(oidbuf, M_TEMP);
2880 error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len);
2882 kfree(oidbuf, M_TEMP);
2885 error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2887 kfree(oidbuf, M_TEMP);
2890 error = copyout(oidbuf, (caddr_t)ifr->ifr_data + sizeof(oid), oid.len);
2891 kfree(oidbuf, M_TEMP);
2894 if ((error = priv_check(curthread, PRIV_DRIVER)))
2896 error = copyin(ifr->ifr_data, &oid, sizeof(oid));
2899 oidbuf = kmalloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2900 if (oidbuf == NULL) {
2904 error = copyin((caddr_t)ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2906 kfree(oidbuf, M_TEMP);
2909 error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len);
2911 kfree(oidbuf, M_TEMP);
2914 error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2916 kfree(oidbuf, M_TEMP);
2919 error = copyout(oidbuf, (caddr_t)ifr->ifr_data + sizeof(oid), oid.len);
2920 kfree(oidbuf, M_TEMP);
2922 case SIOCGPRIVATE_0:
2923 if ((error = priv_check(curthread, PRIV_DRIVER)))
2926 if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) {
2931 error = copyin(ifr->ifr_data, &evt, sizeof(evt));
2936 if (evt.ne_len < sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2941 error = copyout(&sc->ndis_evt[sc->ndis_evtcidx],
2942 ifr->ifr_data, sizeof(uint32_t) * 2);
2947 if (sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2948 error = copyout(sc->ndis_evt[sc->ndis_evtcidx].ne_buf,
2949 (caddr_t)ifr->ifr_data + (sizeof(uint32_t) * 2),
2950 sc->ndis_evt[sc->ndis_evtcidx].ne_len);
2955 kfree(sc->ndis_evt[sc->ndis_evtcidx].ne_buf, M_TEMP);
2956 sc->ndis_evt[sc->ndis_evtcidx].ne_buf = NULL;
2958 sc->ndis_evt[sc->ndis_evtcidx].ne_len = 0;
2959 sc->ndis_evt[sc->ndis_evtcidx].ne_sts = 0;
2960 NDIS_EVTINC(sc->ndis_evtcidx);
2964 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
2967 error = ether_ioctl(ifp, command, data);
2977 ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key)
2979 struct ndis_softc *sc;
2980 ndis_80211_key rkey;
2983 sc = vap->iv_ic->ic_ifp->if_softc;
2985 bzero((char *)&rkey, sizeof(rkey));
2989 rkey.nk_keyidx = key->wk_keyix;
2991 bcopy(vap->iv_ifp->if_broadcastaddr,
2992 rkey.nk_bssid, IEEE80211_ADDR_LEN);
2994 error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len);
3003 * In theory this could be called for any key, but we'll
3004 * only use it for WPA TKIP or AES keys. These need to be
3005 * set after initial authentication with the AP.
3008 ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key,
3009 const uint8_t mac[IEEE80211_ADDR_LEN])
3011 struct ndis_softc *sc;
3013 ndis_80211_key rkey;
3016 ifp = vap->iv_ic->ic_ifp;
3019 switch (key->wk_cipher->ic_cipher) {
3020 case IEEE80211_CIPHER_TKIP:
3022 len = sizeof(ndis_80211_key);
3023 bzero((char *)&rkey, sizeof(rkey));
3026 rkey.nk_keylen = key->wk_keylen;
3028 if (key->wk_flags & IEEE80211_KEY_SWMIC)
3029 rkey.nk_keylen += 16;
3031 /* key index - gets weird in NDIS */
3033 if (key->wk_keyix != IEEE80211_KEYIX_NONE)
3034 rkey.nk_keyidx = key->wk_keyix;
3038 if (key->wk_flags & IEEE80211_KEY_XMIT)
3039 rkey.nk_keyidx |= 1 << 31;
3041 if (key->wk_flags & IEEE80211_KEY_GROUP) {
3042 bcopy(ifp->if_broadcastaddr,
3043 rkey.nk_bssid, IEEE80211_ADDR_LEN);
3045 bcopy(vap->iv_bss->ni_bssid,
3046 rkey.nk_bssid, IEEE80211_ADDR_LEN);
3048 rkey.nk_keyidx |= 1 << 30;
3051 /* need to set bit 29 based on keyrsc */
3052 rkey.nk_keyrsc = key->wk_keyrsc[0]; /* XXX need tid */
3055 rkey.nk_keyidx |= 1 << 29;
3057 if (key->wk_flags & IEEE80211_KEY_SWMIC) {
3058 bcopy(key->wk_key, rkey.nk_keydata, 16);
3059 bcopy(key->wk_key + 24, rkey.nk_keydata + 16, 8);
3060 bcopy(key->wk_key + 16, rkey.nk_keydata + 24, 8);
3062 bcopy(key->wk_key, rkey.nk_keydata, key->wk_keylen);
3064 error = ndis_set_info(sc, OID_802_11_ADD_KEY, &rkey, &len);
3066 case IEEE80211_CIPHER_WEP:
3070 * I don't know how to set up keys for the AES
3071 * cipher yet. Is it the same as TKIP?
3073 case IEEE80211_CIPHER_AES_CCM:
3079 /* We need to return 1 for success, 0 for failure. */
3088 ndis_resettask(device_object *d, void *arg)
3090 struct ndis_softc *sc;
3097 * Stop the adapter and free any mbufs allocated to the
3101 ndis_stop(struct ndis_softc *sc)
3107 callout_stop_sync(&sc->ndis_stat_callout);
3110 sc->ndis_tx_timer = 0;
3112 ifp->if_flags &= ~IFF_RUNNING;
3113 ifq_clr_oactive(&ifp->if_snd);
3116 if (sc->ndis_iftype != PNPBus ||
3117 (sc->ndis_iftype == PNPBus &&
3118 !(sc->ndisusb_status & NDISUSB_STATUS_DETACH) &&
3123 for (i = 0; i < NDIS_EVENTS; i++) {
3124 if (sc->ndis_evt[i].ne_sts && sc->ndis_evt[i].ne_buf != NULL) {
3125 kfree(sc->ndis_evt[i].ne_buf, M_TEMP);
3126 sc->ndis_evt[i].ne_buf = NULL;
3128 sc->ndis_evt[i].ne_sts = 0;
3129 sc->ndis_evt[i].ne_len = 0;
3131 sc->ndis_evtcidx = 0;
3132 sc->ndis_evtpidx = 0;
3137 * Stop all chip I/O so that the kernel's probe routines don't
3138 * get confused by errant DMAs when rebooting.
3141 ndis_shutdown(device_t dev)
3143 struct ndis_softc *sc;
3145 wlan_serialize_enter();
3146 sc = device_get_softc(dev);
3148 wlan_serialize_exit();
3152 ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3154 struct ndis_vap *nvp = NDIS_VAP(vap);
3155 struct ieee80211com *ic = vap->iv_ic;
3156 struct ifnet *ifp = ic->ic_ifp;
3157 struct ndis_softc *sc = ifp->if_softc;
3158 enum ieee80211_state ostate;
3160 DPRINTF(("%s: %s -> %s\n", __func__,
3161 ieee80211_state_name[vap->iv_state],
3162 ieee80211_state_name[nstate]));
3164 ostate = vap->iv_state;
3165 vap->iv_state = nstate;
3168 /* pass on to net80211 */
3169 case IEEE80211_S_INIT:
3170 case IEEE80211_S_SCAN:
3171 return nvp->newstate(vap, nstate, arg);
3172 case IEEE80211_S_ASSOC:
3173 if (ostate != IEEE80211_S_AUTH) {
3174 wlan_serialize_exit();
3175 ndis_auth_and_assoc(sc, vap);
3176 wlan_serialize_enter();
3179 case IEEE80211_S_AUTH:
3180 wlan_serialize_exit();
3181 ndis_auth_and_assoc(sc, vap);
3182 if (vap->iv_state == IEEE80211_S_AUTH) /* XXX */
3183 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
3184 wlan_serialize_enter();
3193 ndis_scan(void *arg)
3195 struct ieee80211vap *vap = arg;
3197 ieee80211_scan_done(vap);
3201 ndis_scan_results(struct ndis_softc *sc)
3203 struct ieee80211com *ic;
3204 struct ieee80211vap *vap;
3205 ndis_80211_bssid_list_ex *bl;
3206 ndis_wlan_bssid_ex *wb;
3207 struct ieee80211_scanparams sp;
3208 struct ieee80211_frame wh;
3209 struct ieee80211_channel *saved_chan;
3211 int rssi, noise, freq, chanflag;
3212 uint8_t ssid[2+IEEE80211_NWID_LEN];
3213 uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
3214 uint8_t *frm, *efrm;
3215 char ethstr[ETHER_ADDRSTRLEN + 1];
3217 ic = sc->ifp->if_l2com;
3218 vap = TAILQ_FIRST(&ic->ic_vaps);
3219 saved_chan = ic->ic_curchan;
3222 if (ndis_get_bssid_list(sc, &bl))
3225 DPRINTF(("%s: %d results\n", __func__, bl->nblx_items));
3226 wb = &bl->nblx_bssid[0];
3227 for (i = 0; i < bl->nblx_items; i++) {
3228 memset(&sp, 0, sizeof(sp));
3230 memcpy(wh.i_addr2, wb->nwbx_macaddr, sizeof(wh.i_addr2));
3231 memcpy(wh.i_addr3, wb->nwbx_macaddr, sizeof(wh.i_addr3));
3232 rssi = 100 * (wb->nwbx_rssi - noise) / (-32 - noise);
3233 rssi = max(0, min(rssi, 100)); /* limit 0 <= rssi <= 100 */
3234 if (wb->nwbx_privacy)
3235 sp.capinfo |= IEEE80211_CAPINFO_PRIVACY;
3236 sp.bintval = wb->nwbx_config.nc_beaconperiod;
3237 switch (wb->nwbx_netinfra) {
3238 case NDIS_80211_NET_INFRA_IBSS:
3239 sp.capinfo |= IEEE80211_CAPINFO_IBSS;
3241 case NDIS_80211_NET_INFRA_BSS:
3242 sp.capinfo |= IEEE80211_CAPINFO_ESS;
3245 sp.rates = &rates[0];
3246 for (j = 0; j < IEEE80211_RATE_MAXSIZE; j++) {
3247 /* XXX - check units */
3248 if (wb->nwbx_supportedrates[j] == 0)
3251 wb->nwbx_supportedrates[j] & 0x7f;
3255 memcpy(sp.ssid + 2, &wb->nwbx_ssid.ns_ssid,
3256 wb->nwbx_ssid.ns_ssidlen);
3257 sp.ssid[1] = wb->nwbx_ssid.ns_ssidlen;
3259 chanflag = ndis_nettype_chan(wb->nwbx_nettype);
3260 freq = wb->nwbx_config.nc_dsconfig / 1000;
3261 sp.chan = sp.bchan = ieee80211_mhz2ieee(freq, chanflag);
3262 /* Hack ic->ic_curchan to be in sync with the scan result */
3263 ic->ic_curchan = ieee80211_find_channel(ic, freq, chanflag);
3264 if (ic->ic_curchan == NULL)
3265 ic->ic_curchan = &ic->ic_channels[0];
3267 /* Process extended info from AP */
3268 if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) {
3269 frm = (uint8_t *)&wb->nwbx_ies;
3270 efrm = frm + wb->nwbx_ielen;
3271 if (efrm - frm < 12)
3273 sp.tstamp = frm; frm += 8;
3274 sp.bintval = le16toh(*(uint16_t *)frm); frm += 2;
3275 sp.capinfo = le16toh(*(uint16_t *)frm); frm += 2;
3277 sp.ies_len = efrm - frm;
3280 DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n",
3281 kether_ntoa(wb->nwbx_macaddr, ethstr), freq, sp.bchan, chanflag,
3283 ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise);
3284 wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len);
3286 kfree(bl, M_DEVBUF);
3287 /* Restore the channel after messing with it */
3288 ic->ic_curchan = saved_chan;
3292 ndis_scan_start(struct ieee80211com *ic)
3294 struct ifnet *ifp = ic->ic_ifp;
3295 struct ndis_softc *sc = ifp->if_softc;
3296 struct ieee80211vap *vap;
3297 struct ieee80211_scan_state *ss;
3298 ndis_80211_ssid ssid;
3302 vap = TAILQ_FIRST(&ic->ic_vaps);
3304 if (!NDIS_INITIALIZED(sc)) {
3305 DPRINTF(("%s: scan aborted\n", __func__));
3306 ieee80211_cancel_scan(vap);
3311 bzero((char *)&ssid, len);
3312 if (ss->ss_nssid == 0)
3313 ssid.ns_ssidlen = 1;
3315 /* Perform a directed scan */
3316 ssid.ns_ssidlen = ss->ss_ssid[0].len;
3317 bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
3320 error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
3322 DPRINTF(("%s: set ESSID failed\n", __func__));
3325 error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, NULL, &len);
3327 DPRINTF(("%s: scan command failed\n", __func__));
3328 ieee80211_cancel_scan(vap);
3331 /* Set a timer to collect the results */
3332 callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, vap);
3336 ndis_set_channel(struct ieee80211com *ic)
3342 ndis_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
3348 ndis_scan_mindwell(struct ieee80211_scan_state *ss)
3350 /* NB: don't try to abort scan; wait for firmware to finish */
3354 ndis_scan_end(struct ieee80211com *ic)
3356 struct ndis_softc *sc = ic->ic_ifp->if_softc;
3358 ndis_scan_results(sc);