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 * WPA support originally contributed by Arvind Srinivasan <arvind@celar.us>
33 * then hacked upon mercilessly by my.
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/sockio.h>
43 #include <sys/malloc.h>
44 #include <sys/endian.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48 #include <sys/queue.h>
49 #include <sys/module.h>
51 #include <sys/sysctl.h>
52 #include <sys/kthread.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>
64 #include <machine/bus.h>
65 #include <machine/resource.h>
69 #include <net80211/ieee80211_var.h>
70 #include <net80211/ieee80211_ioctl.h>
71 #include <net80211/ieee80211_regdomain.h>
73 #include <dev/pci/pcireg.h>
74 #include <dev/pci/pcivar.h>
75 #include <dev/usb/usb.h>
76 #include <dev/usb/usbdi.h>
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>
89 #define DPRINTF(x) do { if (ndis_debug > 0) printf x; } while (0)
91 SYSCTL_INT(_debug, OID_AUTO, ndis, CTLFLAG_RW, &ndis_debug, 0,
92 "if_ndis debug level");
97 SYSCTL_DECL(_hw_ndisusb);
99 SYSCTL_INT(_hw_ndisusb, OID_AUTO, halt, CTLFLAG_RW, &ndisusb_halt, 0,
100 "Halt NDIS USB driver when it's attached");
102 /* 0 - 30 dBm to mW conversion table */
103 static const uint16_t dBm2mW[] = {
104 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
105 3, 4, 4, 4, 5, 6, 6, 7, 8, 9,
106 10, 11, 13, 14, 16, 18, 20, 22, 25, 28,
107 32, 35, 40, 45, 50, 56, 63, 71, 79, 89,
108 100, 112, 126, 141, 158, 178, 200, 224, 251, 282,
109 316, 355, 398, 447, 501, 562, 631, 708, 794, 891,
113 MODULE_DEPEND(ndis, ether, 1, 1, 1);
114 MODULE_DEPEND(ndis, wlan, 1, 1, 1);
115 MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
117 MODULE_VERSION(ndis, 1);
119 int ndis_attach (device_t);
120 int ndis_detach (device_t);
121 int ndis_suspend (device_t);
122 int ndis_resume (device_t);
123 void ndis_shutdown (device_t);
125 int ndisdrv_modevent (module_t, int, void *);
127 static void ndis_txeof (ndis_handle, ndis_packet *, ndis_status);
128 static void ndis_rxeof (ndis_handle, ndis_packet **, uint32_t);
129 static void ndis_rxeof_eth (ndis_handle, ndis_handle, char *, void *,
130 uint32_t, void *, uint32_t, uint32_t);
131 static void ndis_rxeof_done (ndis_handle);
132 static void ndis_rxeof_xfr (kdpc *, ndis_handle, void *, void *);
133 static void ndis_rxeof_xfr_done (ndis_handle, ndis_packet *,
135 static void ndis_linksts (ndis_handle, ndis_status, void *, uint32_t);
136 static void ndis_linksts_done (ndis_handle);
138 /* We need to wrap these functions for amd64. */
139 static funcptr ndis_txeof_wrap;
140 static funcptr ndis_rxeof_wrap;
141 static funcptr ndis_rxeof_eth_wrap;
142 static funcptr ndis_rxeof_done_wrap;
143 static funcptr ndis_rxeof_xfr_wrap;
144 static funcptr ndis_rxeof_xfr_done_wrap;
145 static funcptr ndis_linksts_wrap;
146 static funcptr ndis_linksts_done_wrap;
147 static funcptr ndis_ticktask_wrap;
148 static funcptr ndis_starttask_wrap;
149 static funcptr ndis_resettask_wrap;
150 static funcptr ndis_inputtask_wrap;
152 static struct ieee80211vap *ndis_vap_create(struct ieee80211com *,
153 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
154 const uint8_t [IEEE80211_ADDR_LEN],
155 const uint8_t [IEEE80211_ADDR_LEN]);
156 static void ndis_vap_delete (struct ieee80211vap *);
157 static void ndis_tick (void *);
158 static void ndis_ticktask (device_object *, void *);
159 static int ndis_raw_xmit (struct ieee80211_node *, struct mbuf *,
160 const struct ieee80211_bpf_params *);
161 static void ndis_update_mcast (struct ifnet *ifp);
162 static void ndis_update_promisc (struct ifnet *ifp);
163 static void ndis_start (struct ifnet *);
164 static void ndis_starttask (device_object *, void *);
165 static void ndis_resettask (device_object *, void *);
166 static void ndis_inputtask (device_object *, void *);
167 static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
168 static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t);
169 static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
171 static int ndis_nettype_chan (uint32_t);
172 static int ndis_nettype_mode (uint32_t);
173 static void ndis_scan (void *);
174 static void ndis_scan_results (struct ndis_softc *);
175 static void ndis_scan_start (struct ieee80211com *);
176 static void ndis_scan_end (struct ieee80211com *);
177 static void ndis_set_channel (struct ieee80211com *);
178 static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long);
179 static void ndis_scan_mindwell (struct ieee80211_scan_state *);
180 static void ndis_init (void *);
181 static void ndis_stop (struct ndis_softc *);
182 static int ndis_ifmedia_upd (struct ifnet *);
183 static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *);
184 static int ndis_get_bssid_list (struct ndis_softc *,
185 ndis_80211_bssid_list_ex **);
186 static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex **);
187 static int ndis_probe_offload (struct ndis_softc *);
188 static int ndis_set_offload (struct ndis_softc *);
189 static void ndis_getstate_80211 (struct ndis_softc *);
190 static void ndis_setstate_80211 (struct ndis_softc *);
191 static void ndis_auth_and_assoc (struct ndis_softc *, struct ieee80211vap *);
192 static void ndis_media_status (struct ifnet *, struct ifmediareq *);
193 static int ndis_set_cipher (struct ndis_softc *, int);
194 static int ndis_set_wpa (struct ndis_softc *, void *, int);
195 static int ndis_add_key (struct ieee80211vap *,
196 const struct ieee80211_key *, const u_int8_t []);
197 static int ndis_del_key (struct ieee80211vap *,
198 const struct ieee80211_key *);
200 static void ndis_setmulti (struct ndis_softc *);
201 static void ndis_map_sclist (void *, bus_dma_segment_t *,
202 int, bus_size_t, int);
204 static int ndisdrv_loaded = 0;
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.
213 ndisdrv_modevent(mod, cmd, arg)
223 if (ndisdrv_loaded > 1)
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);
252 if (ndisdrv_loaded > 0)
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);
278 * Program the 64-bit multicast hash filter.
282 struct ndis_softc *sc;
285 struct ifmultiaddr *ifma;
286 int len, mclistsz, error;
291 if (!NDIS_INITIALIZED(sc))
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);
300 device_printf(sc->ndis_dev,
301 "set allmulti failed: %d\n", error);
305 if (TAILQ_EMPTY(&ifp->if_multiaddrs))
308 len = sizeof(mclistsz);
309 ndis_get_info(sc, OID_802_3_MAXIMUM_LIST_SIZE, &mclistsz, &len);
311 mclist = malloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_NOWAIT|M_ZERO);
313 if (mclist == NULL) {
314 sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
318 sc->ndis_filter |= NDIS_PACKET_TYPE_MULTICAST;
322 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
323 if (ifma->ifma_addr->sa_family != AF_LINK)
325 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
326 mclist + (ETHER_ADDR_LEN * len), ETHER_ADDR_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;
335 if_maddr_runlock(ifp);
337 len = len * ETHER_ADDR_LEN;
338 error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len);
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;
346 free(mclist, M_TEMP);
348 len = sizeof(sc->ndis_filter);
349 error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
350 &sc->ndis_filter, &len);
352 device_printf(sc->ndis_dev, "set multi failed: %d\n", error);
357 struct ndis_softc *sc;
359 ndis_task_offload *nto;
360 ndis_task_offload_hdr *ntoh;
361 ndis_task_tcpip_csum *nttc;
367 if (!NDIS_INITIALIZED(sc))
370 /* See if there's anything to set. */
372 error = ndis_probe_offload(sc);
376 if (sc->ndis_hwassist == 0 && ifp->if_capabilities == 0)
379 len = sizeof(ndis_task_offload_hdr) + sizeof(ndis_task_offload) +
380 sizeof(ndis_task_tcpip_csum);
382 ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
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;
394 nto = (ndis_task_offload *)((char *)ntoh +
395 ntoh->ntoh_offset_firsttask);
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);
403 nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
405 if (ifp->if_capenable & IFCAP_TXCSUM)
406 nttc->nttc_v4tx = sc->ndis_v4tx;
408 if (ifp->if_capenable & IFCAP_RXCSUM)
409 nttc->nttc_v4rx = sc->ndis_v4rx;
411 error = ndis_set_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
418 ndis_probe_offload(sc)
419 struct ndis_softc *sc;
421 ndis_task_offload *nto;
422 ndis_task_offload_hdr *ntoh;
423 ndis_task_tcpip_csum *nttc = NULL;
425 int len, error, dummy;
430 error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, &dummy, &len);
435 ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
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;
446 error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
453 if (ntoh->ntoh_vers != NDIS_TASK_OFFLOAD_VERSION) {
458 nto = (ndis_task_offload *)((char *)ntoh +
459 ntoh->ntoh_offset_firsttask);
462 switch (nto->nto_task) {
463 case NDIS_TASK_TCPIP_CSUM:
464 nttc = (ndis_task_tcpip_csum *)nto->nto_taskbuf;
466 /* Don't handle these yet. */
467 case NDIS_TASK_IPSEC:
468 case NDIS_TASK_TCP_LARGESEND:
472 if (nto->nto_offset_nexttask == 0)
474 nto = (ndis_task_offload *)((char *)nto +
475 nto->nto_offset_nexttask);
483 sc->ndis_v4tx = nttc->nttc_v4tx;
484 sc->ndis_v4rx = nttc->nttc_v4rx;
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;
493 if (sc->ndis_hwassist)
494 ifp->if_capabilities |= IFCAP_TXCSUM;
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;
508 ndis_nettype_chan(uint32_t 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);
516 DPRINTF(("unknown channel nettype %d\n", type));
517 return (IEEE80211_CHAN_B); /* Default to 11B chan */
521 ndis_nettype_mode(uint32_t 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);
529 DPRINTF(("unknown mode nettype %d\n", type));
530 return (IEEE80211_MODE_AUTO);
534 * Attach the interface. Allocate softc structures, do ifmedia
535 * setup and ethernet/BPF attach.
541 u_char eaddr[ETHER_ADDR_LEN];
542 struct ndis_softc *sc;
545 struct ifnet *ifp = NULL;
546 int error = 0, len, mode;
550 sc = device_get_softc(dev);
552 mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
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);
562 if (sc->ndis_iftype == PCMCIABus) {
563 error = ndis_alloc_amem(sc);
565 device_printf(dev, "failed to allocate "
566 "attribute memory\n");
571 /* Create sysctl registry nodes */
572 ndis_create_sysctls(sc);
574 /* Find the PDO for this device instance. */
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");
581 pdrv = windrv_lookup(0, "USB Bus");
582 pdo = windrv_find_pdo(pdrv, dev);
585 * Create a new functional device object for this
586 * device. This is what creates the miniport block
587 * for this device instance.
590 if (NdisAddDevice(sc->ndis_dobj, pdo) != STATUS_SUCCESS) {
591 device_printf(dev, "failed to create FDO!\n");
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);
601 /* Do resource conversion. */
602 if (sc->ndis_iftype == PCMCIABus || sc->ndis_iftype == PCIBus)
603 ndis_convert_res(sc);
605 sc->ndis_block->nmb_rlist = NULL;
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;
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;
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);
629 /* Call driver's init routine. */
630 if (ndis_init_nic(sc)) {
631 device_printf(dev, "init handler failed\n");
637 * Get station address from the driver.
640 ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len);
643 * Figure out how big to make the TX buffer pool.
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");
655 * If this is a deserialized miniport, we don't have
656 * to honor the OID_GEN_MAXIMUM_SEND_PACKETS result.
658 if (!NDIS_SERIALIZED(sc->ndis_block))
659 sc->ndis_maxpkts = NDIS_TXPKTS;
661 /* Enforce some sanity, just in case. */
663 if (sc->ndis_maxpkts == 0)
664 sc->ndis_maxpkts = 10;
666 sc->ndis_txarray = malloc(sizeof(ndis_packet *) *
667 sc->ndis_maxpkts, M_DEVBUF, M_NOWAIT|M_ZERO);
669 /* Allocate a pool of ndis_packets for TX encapsulation. */
671 NdisAllocatePacketPool(&i, &sc->ndis_txpool,
672 sc->ndis_maxpkts, PROTOCOL_RESERVED_SIZE_IN_PACKET);
674 if (i != NDIS_STATUS_SUCCESS) {
675 sc->ndis_txpool = NULL;
676 device_printf(dev, "failed to allocate TX packet pool");
681 sc->ndis_txpending = sc->ndis_maxpkts;
684 /* Get supported oid list. */
685 ndis_get_supported_oids(sc, &sc->ndis_oids, &sc->ndis_oidcnt);
687 /* If the NDIS module requested scatter/gather, init maps. */
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.
696 for (i = 0; i < sc->ndis_oidcnt; i++)
697 if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) {
703 ifp = if_alloc(IFT_IEEE80211);
705 ifp = if_alloc(IFT_ETHER);
713 /* Check for task offload support. */
714 ndis_probe_offload(sc);
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;
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;
737 callout_init(&sc->ndis_scan_callout, CALLOUT_MPSAFE);
739 ifp->if_ioctl = ndis_ioctl_80211;
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);
747 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
751 ntl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
752 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
759 for (i = 0; i < ntl->ntl_items; i++) {
760 mode = ndis_nettype_mode(ntl->ntl_type[i]);
762 setbit(ic->ic_modecaps, mode);
763 setbit(&bands, mode);
765 device_printf(dev, "Unknown nettype %d\n",
770 /* Default to 11b channels if the card did not supply any */
772 setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
773 setbit(&bands, IEEE80211_MODE_11B);
776 bzero((char *)&rates, len);
777 r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
778 (void *)rates, &len);
780 device_printf(dev, "get rates failed: 0x%x\n", r);
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
787 #define TESTSETRATE(x, y) \
790 for (i = 0; i < ic->ic_sup_rates[x].rs_nrates; i++) { \
791 if (ic->ic_sup_rates[x].rs_rates[i] == (y)) \
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++; \
800 #define SETRATE(x, y) \
801 ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y)
803 ic->ic_sup_rates[x].rs_nrates++
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) {
819 if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) {
820 /* Lazy-init 802.11b. */
821 setbit(ic->ic_modecaps,
823 ic->ic_sup_rates[IEEE80211_MODE_11B].
826 SETRATE(IEEE80211_MODE_11B, rates[i]);
827 INCRATE(IEEE80211_MODE_11B);
830 if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
831 SETRATE(IEEE80211_MODE_11A, rates[i]);
832 INCRATE(IEEE80211_MODE_11A);
834 if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
835 SETRATE(IEEE80211_MODE_11G, rates[i]);
836 INCRATE(IEEE80211_MODE_11G);
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?
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);
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);
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);
873 ieee80211_init_channels(ic, NULL, &bands);
876 * To test for WPA support, we need to see if we can
877 * set AUTHENTICATION_MODE to WPA and read it back
881 arg = NDIS_80211_AUTHMODE_WPA;
882 r = ndis_set_info(sc,
883 OID_802_11_AUTHENTICATION_MODE, &arg, &i);
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;
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.
899 arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
900 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
902 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
903 | IEEE80211_CRYPTO_TKIP
904 | IEEE80211_CRYPTO_AES_CCM;
907 arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
908 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
910 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
911 | IEEE80211_CRYPTO_TKIP;
914 arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
915 r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
917 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
920 r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
922 ic->ic_caps |= IEEE80211_C_PMGT;
924 r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i);
926 ic->ic_caps |= IEEE80211_C_TXPMGT;
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;
943 ieee80211_announce(ic);
946 ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
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);
964 if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
967 DPRINTF(("attach done.\n"));
968 /* We're done talking to the NIC for now; halt it. */
970 DPRINTF(("halting done.\n"));
975 static struct ieee80211vap *
976 ndis_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])
981 struct ndis_vap *nvp;
982 struct ieee80211vap *vap;
984 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
986 nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap),
987 M_80211_VAP, M_NOWAIT | M_ZERO);
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;
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;
1006 ndis_vap_delete(struct ieee80211vap *vap)
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;
1014 callout_drain(&sc->ndis_scan_callout);
1015 ieee80211_vap_detach(vap);
1016 free(nvp, M_80211_VAP);
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
1030 struct ndis_softc *sc;
1034 sc = device_get_softc(dev);
1038 ifp->if_flags &= ~IFF_UP;
1040 if (device_is_attached(dev)) {
1045 ieee80211_ifdetach(ifp->if_l2com);
1047 ether_ifdetach(ifp);
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);
1065 bus_generic_detach(dev);
1066 ndis_unload_driver(sc);
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);
1083 if (sc->ndis_iftype == PCMCIABus)
1087 ndis_destroy_dma(sc);
1089 if (sc->ndis_txarray)
1090 free(sc->ndis_txarray, M_DEVBUF);
1092 if (!sc->ndis_80211)
1093 ifmedia_removeall(&sc->ifmedia);
1095 if (sc->ndis_txpool != NULL)
1096 NdisFreePacketPool(sc->ndis_txpool);
1098 /* Destroy the PDO for this device. */
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");
1105 drv = windrv_lookup(0, "USB Bus");
1107 panic("couldn't find driver object");
1108 windrv_destroy_pdo(drv, dev);
1110 if (sc->ndis_iftype == PCIBus)
1111 bus_dma_tag_destroy(sc->ndis_parent_tag);
1120 struct ndis_softc *sc;
1123 sc = device_get_softc(dev);
1127 if (NDIS_INITIALIZED(sc))
1138 struct ndis_softc *sc;
1141 sc = device_get_softc(dev);
1144 if (NDIS_INITIALIZED(sc))
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
1158 ndis_rxeof_eth(adapter, ctx, addr, hdr, hdrlen, lookahead, lookaheadlen, pktlen)
1159 ndis_handle adapter;
1165 uint32_t lookaheadlen;
1168 ndis_miniport_block *block;
1178 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1182 /* Save the data provided to us so far. */
1184 m->m_len = lookaheadlen + hdrlen;
1185 m->m_pkthdr.len = pktlen + hdrlen;
1187 m_copyback(m, 0, hdrlen, hdr);
1188 m_copyback(m, hdrlen, lookaheadlen, lookahead);
1190 /* Now create a fake NDIS_PACKET to hold the data */
1192 NdisAllocatePacket(&status, &p, block->nmb_rxpool);
1194 if (status != NDIS_STATUS_SUCCESS) {
1201 b = IoAllocateMdl(m->m_data, m->m_pkthdr.len, FALSE, FALSE, NULL);
1209 p->np_private.npp_head = p->np_private.npp_tail = b;
1210 p->np_private.npp_totlen = m->m_pkthdr.len;
1212 /* Save the packet RX context somewhere. */
1213 priv = (ndis_ethpriv *)&p->np_protocolreserved;
1214 priv->nep_ctx = ctx;
1216 if (!NDIS_SERIALIZED(block))
1217 KeAcquireSpinLock(&block->nmb_lock, &irql);
1219 InsertTailList((&block->nmb_packetlist), (&p->np_list));
1221 if (!NDIS_SERIALIZED(block))
1222 KeReleaseSpinLock(&block->nmb_lock, irql);
1226 * NdisMEthIndicateReceiveComplete() handler, runs at DISPATCH_LEVEL
1227 * for serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
1231 ndis_rxeof_done(adapter)
1232 ndis_handle adapter;
1234 struct ndis_softc *sc;
1235 ndis_miniport_block *block;
1239 /* Schedule transfer/RX of queued packets. */
1241 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1243 KeInsertQueueDpc(&sc->ndis_rxdpc, NULL, NULL);
1247 * MiniportTransferData() handler, runs at DISPATCH_LEVEL.
1250 ndis_rxeof_xfr(dpc, adapter, sysarg1, sysarg2)
1252 ndis_handle adapter;
1256 ndis_miniport_block *block;
1257 struct ndis_softc *sc;
1266 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1269 KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
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));
1277 priv = (ndis_ethpriv *)&p->np_protocolreserved;
1282 KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
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);
1288 KeAcquireSpinLockAtDpcLevel(&block->nmb_lock);
1291 * If status is NDIS_STATUS_PENDING, do nothing and
1292 * wait for a callback to the ndis_rxeof_xfr_done()
1296 m->m_len = m->m_pkthdr.len;
1297 m->m_pkthdr.rcvif = ifp;
1299 if (status == NDIS_STATUS_SUCCESS) {
1300 IoFreeMdl(p->np_private.npp_head);
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);
1310 if (status == NDIS_STATUS_FAILURE)
1313 /* Advance to next packet */
1314 l = block->nmb_packetlist.nle_flink;
1317 KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
1321 * NdisMTransferDataComplete() handler, runs at DISPATCH_LEVEL.
1324 ndis_rxeof_xfr_done(adapter, packet, status, len)
1325 ndis_handle adapter;
1326 ndis_packet *packet;
1330 ndis_miniport_block *block;
1331 struct ndis_softc *sc;
1336 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1340 IoFreeMdl(packet->np_private.npp_head);
1341 NdisFreePacket(packet);
1343 if (status != NDIS_STATUS_SUCCESS) {
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);
1358 * A frame has been uploaded: pass the resulting mbuf chain up to
1359 * the higher level protocols.
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.
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
1377 ndis_rxeof(adapter, packets, pktcnt)
1378 ndis_handle adapter;
1379 ndis_packet **packets;
1382 struct ndis_softc *sc;
1383 ndis_miniport_block *block;
1386 ndis_tcpip_csum *csum;
1388 struct mbuf *m0, *m;
1391 block = (ndis_miniport_block *)adapter;
1392 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
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.
1400 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1401 for (i = 0; i < pktcnt; i++) {
1403 if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) {
1405 ndis_return_packet(p, block);
1411 for (i = 0; i < pktcnt; i++) {
1413 /* Stash the softc here so ptom can use it. */
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);
1421 if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) {
1422 m = m_dup(m0, M_NOWAIT);
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
1438 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1440 m = m_dup(m0, M_NOWAIT);
1441 if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES)
1444 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1451 m0->m_pkthdr.rcvif = ifp;
1453 /* Deal with checksum offload. */
1455 if (ifp->if_capenable & IFCAP_RXCSUM &&
1456 p->np_ext.npe_info[ndis_tcpipcsum_info] != NULL) {
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;
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);
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).
1490 ndis_inputtask(dobj, arg)
1491 device_object *dobj;
1494 ndis_miniport_block *block;
1496 struct ndis_softc *sc;
1498 struct ieee80211com *ic;
1499 struct ieee80211vap *vap;
1505 vap = TAILQ_FIRST(&ic->ic_vaps);
1506 block = dobj->do_devext;
1508 KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1510 _IF_DEQUEUE(&sc->ndis_rxqueue, m);
1513 KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1514 if ((sc->ndis_80211 != 0) && (vap != NULL))
1515 vap->iv_deliver_data(vap, vap->iv_bss, m);
1517 (*ifp->if_input)(ifp, m);
1518 KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
1520 KeReleaseSpinLock(&sc->ndis_rxlock, irql);
1524 * A frame was downloaded to the chip. It's safe for us to clean up
1528 ndis_txeof(adapter, packet, status)
1529 ndis_handle adapter;
1530 ndis_packet *packet;
1534 struct ndis_softc *sc;
1535 ndis_miniport_block *block;
1540 block = (ndis_miniport_block *)adapter;
1541 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1545 idx = packet->np_txidx;
1547 bus_dmamap_unload(sc->ndis_ttag, sc->ndis_tmaps[idx]);
1549 ndis_free_packet(packet);
1553 sc->ndis_txarray[idx] = NULL;
1554 sc->ndis_txpending++;
1556 if (status == NDIS_STATUS_SUCCESS)
1561 sc->ndis_tx_timer = 0;
1562 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1566 IoQueueWorkItem(sc->ndis_startitem,
1567 (io_workitem_func)ndis_starttask_wrap,
1568 WORKQUEUE_CRITICAL, ifp);
1572 ndis_linksts(adapter, status, sbuf, slen)
1573 ndis_handle adapter;
1578 ndis_miniport_block *block;
1579 struct ndis_softc *sc;
1582 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1583 sc->ndis_sts = status;
1585 /* Event list is all full up, drop this one. */
1588 if (sc->ndis_evt[sc->ndis_evtpidx].ne_sts) {
1593 /* Cache the event. */
1596 sc->ndis_evt[sc->ndis_evtpidx].ne_buf = malloc(slen,
1598 if (sc->ndis_evt[sc->ndis_evtpidx].ne_buf == NULL) {
1603 sc->ndis_evt[sc->ndis_evtpidx].ne_buf, slen);
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);
1612 ndis_linksts_done(adapter)
1613 ndis_handle adapter;
1615 ndis_miniport_block *block;
1616 struct ndis_softc *sc;
1620 sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
1623 if (!NDIS_INITIALIZED(sc))
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);
1635 case NDIS_STATUS_MEDIA_DISCONNECT:
1637 IoQueueWorkItem(sc->ndis_tickitem,
1638 (io_workitem_func)ndis_ticktask_wrap,
1639 WORKQUEUE_CRITICAL, sc);
1650 struct ndis_softc *sc;
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;
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");
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);
1673 callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
1677 ndis_ticktask(d, xsc)
1681 struct ndis_softc *sc;
1682 struct ieee80211com *ic;
1683 struct ieee80211vap *vap;
1684 ndis_checkforhang_handler hangfunc;
1688 ic = sc->ifp->if_l2com;
1689 vap = TAILQ_FIRST(&ic->ic_vaps);
1692 if (!NDIS_INITIALIZED(sc)) {
1698 hangfunc = sc->ndis_chars->nmc_checkhang_func;
1700 if (hangfunc != NULL) {
1701 rval = MSCALL1(hangfunc,
1702 sc->ndis_block->nmb_miniportadapterctx);
1710 if (sc->ndis_link == 0 &&
1711 sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) {
1713 if ((sc->ndis_80211 != 0) && (vap != NULL)) {
1715 ndis_getstate_80211(sc);
1716 ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
1718 if_link_state_change(vap->iv_ifp, LINK_STATE_UP);
1720 if_link_state_change(sc->ifp, LINK_STATE_UP);
1723 if (sc->ndis_link == 1 &&
1724 sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
1726 if ((sc->ndis_80211 != 0) && (vap != NULL)) {
1728 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1730 if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN);
1732 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
1739 ndis_map_sclist(arg, segs, nseg, mapsize, error)
1741 bus_dma_segment_t *segs;
1747 struct ndis_sc_list *sclist;
1750 if (error || arg == NULL)
1755 sclist->nsl_frags = nseg;
1757 for (i = 0; i < nseg; i++) {
1758 sclist->nsl_elements[i].nse_addr.np_quad = segs[i].ds_addr;
1759 sclist->nsl_elements[i].nse_len = segs[i].ds_len;
1764 ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1765 const struct ieee80211_bpf_params *params)
1767 /* no support; just discard */
1769 ieee80211_free_node(ni);
1774 ndis_update_mcast(struct ifnet *ifp)
1776 struct ndis_softc *sc = ifp->if_softc;
1782 ndis_update_promisc(struct ifnet *ifp)
1788 ndis_starttask(d, arg)
1796 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1801 * Main transmit routine. To make NDIS drivers happy, we need to
1802 * transform mbuf chains into NDIS packets and feed them to the
1803 * send packet routines. Most drivers allow you to send several
1804 * packets at once (up to the maxpkts limit). Unfortunately, rather
1805 * that accepting them in the form of a linked list, they expect
1806 * a contiguous array of pointers to packets.
1808 * For those drivers which use the NDIS scatter/gather DMA mechanism,
1809 * we need to perform busdma work here. Those that use map registers
1810 * will do the mapping themselves on a buffer by buffer basis.
1816 struct ndis_softc *sc;
1817 struct mbuf *m = NULL;
1818 ndis_packet **p0 = NULL, *p = NULL;
1819 ndis_tcpip_csum *csum;
1820 int pcnt = 0, status;
1825 if (!sc->ndis_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1830 p0 = &sc->ndis_txarray[sc->ndis_txidx];
1832 while(sc->ndis_txpending) {
1833 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1837 NdisAllocatePacket(&status,
1838 &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool);
1840 if (status != NDIS_STATUS_SUCCESS)
1843 if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) {
1844 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1850 * Save pointer to original mbuf
1851 * so we can free it later.
1854 p = sc->ndis_txarray[sc->ndis_txidx];
1855 p->np_txidx = sc->ndis_txidx;
1857 p->np_oob.npo_status = NDIS_STATUS_PENDING;
1860 * Do scatter/gather processing, if driver requested it.
1863 bus_dmamap_load_mbuf(sc->ndis_ttag,
1864 sc->ndis_tmaps[sc->ndis_txidx], m,
1865 ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT);
1866 bus_dmamap_sync(sc->ndis_ttag,
1867 sc->ndis_tmaps[sc->ndis_txidx],
1868 BUS_DMASYNC_PREREAD);
1869 p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist;
1872 /* Handle checksum offload. */
1874 if (ifp->if_capenable & IFCAP_TXCSUM &&
1875 m->m_pkthdr.csum_flags) {
1876 csum = (ndis_tcpip_csum *)
1877 &p->np_ext.npe_info[ndis_tcpipcsum_info];
1878 csum->u.ntc_txflags = NDIS_TXCSUM_DO_IPV4;
1879 if (m->m_pkthdr.csum_flags & CSUM_IP)
1880 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_IP;
1881 if (m->m_pkthdr.csum_flags & CSUM_TCP)
1882 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_TCP;
1883 if (m->m_pkthdr.csum_flags & CSUM_UDP)
1884 csum->u.ntc_txflags |= NDIS_TXCSUM_DO_UDP;
1885 p->np_private.npp_flags = NDIS_PROTOCOL_ID_TCP_IP;
1889 sc->ndis_txpending--;
1894 * If there's a BPF listener, bounce a copy of this frame
1897 if (!sc->ndis_80211) /* XXX handle 80211 */
1901 * The array that p0 points to must appear contiguous,
1902 * so we must not wrap past the end of sc->ndis_txarray[].
1903 * If it looks like we're about to wrap, break out here
1904 * so the this batch of packets can be transmitted, then
1905 * wait for txeof to ask us to send the rest.
1907 if (sc->ndis_txidx == 0)
1916 if (sc->ndis_txpending == 0)
1917 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1920 * Set a timeout in case the chip goes out to lunch.
1922 sc->ndis_tx_timer = 5;
1927 * According to NDIS documentation, if a driver exports
1928 * a MiniportSendPackets() routine, we prefer that over
1929 * a MiniportSend() routine (which sends just a single
1932 if (sc->ndis_chars->nmc_sendmulti_func != NULL)
1933 ndis_send_packets(sc, p0, pcnt);
1935 ndis_send_packet(sc, p);
1944 struct ndis_softc *sc = xsc;
1945 struct ifnet *ifp = sc->ifp;
1946 struct ieee80211com *ic = ifp->if_l2com;
1950 * Avoid reintializing the link unnecessarily.
1951 * This should be dealt with in a better way by
1952 * fixing the upper layer modules so they don't
1953 * call ifp->if_init() quite as often.
1959 * Cancel pending I/O and free all RX/TX buffers.
1963 if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0)) {
1964 error = ndis_init_nic(sc);
1966 device_printf(sc->ndis_dev,
1967 "failed to initialize the device: %d\n", error);
1972 /* Init our MAC address */
1974 /* Program the packet filter */
1976 sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
1978 if (ifp->if_flags & IFF_BROADCAST)
1979 sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
1981 if (ifp->if_flags & IFF_PROMISC)
1982 sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
1984 len = sizeof(sc->ndis_filter);
1986 error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
1987 &sc->ndis_filter, &len);
1990 device_printf(sc->ndis_dev, "set filter failed: %d\n", error);
1997 ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len);
2000 * Program the multicast filter, if necessary.
2004 /* Setup task offload. */
2005 ndis_set_offload(sc);
2010 sc->ndis_txpending = sc->ndis_maxpkts;
2013 if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN);
2015 ifp->if_drv_flags |= IFF_DRV_RUNNING;
2016 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2017 sc->ndis_tx_timer = 0;
2020 * Some drivers don't set this value. The NDIS spec says
2021 * the default checkforhang timeout is "approximately 2
2022 * seconds." We use 3 seconds, because it seems for some
2023 * drivers, exactly 2 seconds is too fast.
2025 if (sc->ndis_block->nmb_checkforhangsecs == 0)
2026 sc->ndis_block->nmb_checkforhangsecs = 3;
2028 sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
2029 callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
2032 /* XXX force handling */
2034 ieee80211_start_all(ic); /* start all vap's */
2038 * Set media options.
2041 ndis_ifmedia_upd(ifp)
2044 struct ndis_softc *sc;
2048 if (NDIS_INITIALIZED(sc))
2055 * Report current media status.
2058 ndis_ifmedia_sts(ifp, ifmr)
2060 struct ifmediareq *ifmr;
2062 struct ndis_softc *sc;
2063 uint32_t media_info;
2064 ndis_media_state linkstate;
2067 ifmr->ifm_status = IFM_AVALID;
2068 ifmr->ifm_active = IFM_ETHER;
2071 if (!NDIS_INITIALIZED(sc))
2074 len = sizeof(linkstate);
2075 ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
2076 (void *)&linkstate, &len);
2078 len = sizeof(media_info);
2079 ndis_get_info(sc, OID_GEN_LINK_SPEED,
2080 (void *)&media_info, &len);
2082 if (linkstate == nmc_connected)
2083 ifmr->ifm_status |= IFM_ACTIVE;
2085 switch (media_info) {
2087 ifmr->ifm_active |= IFM_10_T;
2090 ifmr->ifm_active |= IFM_100_TX;
2093 ifmr->ifm_active |= IFM_1000_T;
2096 device_printf(sc->ndis_dev, "unknown speed: %d\n", media_info);
2102 ndis_set_cipher(sc, cipher)
2103 struct ndis_softc *sc;
2106 struct ieee80211com *ic;
2110 ic = sc->ifp->if_l2com;
2114 if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) {
2115 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP))
2117 arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
2120 if (cipher == WPA_CSE_TKIP) {
2121 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP))
2123 arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
2126 if (cipher == WPA_CSE_CCMP) {
2127 if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM))
2129 arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
2132 DPRINTF(("Setting cipher to %d\n", arg));
2134 rval = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2139 /* Check that the cipher was set correctly. */
2142 rval = ndis_get_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2144 if (rval != 0 || arg != save)
2151 * WPA is hairy to set up. Do the work in a separate routine
2152 * so we don't clutter the setstate function too much.
2153 * Important yet undocumented fact: first we have to set the
2154 * authentication mode, _then_ we enable the ciphers. If one
2155 * of the WPA authentication modes isn't enabled, the driver
2156 * might not permit the TKIP or AES ciphers to be selected.
2159 ndis_set_wpa(sc, ie, ielen)
2160 struct ndis_softc *sc;
2164 struct ieee80211_ie_wpa *w;
2171 * Apparently, the only way for us to know what ciphers
2172 * and key management/authentication mode to use is for
2173 * us to inspect the optional information element (IE)
2174 * stored in the 802.11 state machine. This IE should be
2175 * supplied by the WPA supplicant.
2178 w = (struct ieee80211_ie_wpa *)ie;
2180 /* Check for the right kind of IE. */
2181 if (w->wpa_id != IEEE80211_ELEMID_VENDOR) {
2182 DPRINTF(("Incorrect IE type %d\n", w->wpa_id));
2186 /* Skip over the ucast cipher OIDs. */
2187 pos = (char *)&w->wpa_uciphers[0];
2188 pos += w->wpa_uciphercnt * sizeof(struct ndis_ie);
2190 /* Skip over the authmode count. */
2191 pos += sizeof(u_int16_t);
2194 * Check for the authentication modes. I'm
2195 * pretty sure there's only supposed to be one.
2198 n = (struct ndis_ie *)pos;
2199 if (n->ni_val == WPA_ASE_NONE)
2200 arg = NDIS_80211_AUTHMODE_WPANONE;
2202 if (n->ni_val == WPA_ASE_8021X_UNSPEC)
2203 arg = NDIS_80211_AUTHMODE_WPA;
2205 if (n->ni_val == WPA_ASE_8021X_PSK)
2206 arg = NDIS_80211_AUTHMODE_WPAPSK;
2208 DPRINTF(("Setting WPA auth mode to %d\n", arg));
2210 if (ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i))
2213 ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
2215 /* Now configure the desired ciphers. */
2217 /* First, set up the multicast group cipher. */
2218 n = (struct ndis_ie *)&w->wpa_mcipher[0];
2220 if (ndis_set_cipher(sc, n->ni_val))
2223 /* Now start looking around for the unicast ciphers. */
2224 pos = (char *)&w->wpa_uciphers[0];
2225 n = (struct ndis_ie *)pos;
2227 for (i = 0; i < w->wpa_uciphercnt; i++) {
2228 if (ndis_set_cipher(sc, n->ni_val))
2237 ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
2239 struct ieee80211vap *vap = ifp->if_softc;
2240 struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc;
2244 if (!NDIS_INITIALIZED(sc))
2247 len = sizeof(txrate);
2248 if (ndis_get_info(sc, OID_GEN_LINK_SPEED, &txrate, &len) == 0)
2249 vap->iv_bss->ni_txrate = txrate / 5000;
2250 ieee80211_media_status(ifp, imr);
2254 ndis_setstate_80211(sc)
2255 struct ndis_softc *sc;
2257 struct ieee80211com *ic;
2258 struct ieee80211vap *vap;
2259 ndis_80211_macaddr bssid;
2260 ndis_80211_config config;
2267 vap = TAILQ_FIRST(&ic->ic_vaps);
2269 if (!NDIS_INITIALIZED(sc)) {
2270 DPRINTF(("%s: NDIS not initialized\n", __func__));
2274 /* Disassociate and turn off radio. */
2277 ndis_set_info(sc, OID_802_11_DISASSOCIATE, &arg, &len);
2279 /* Set network infrastructure mode. */
2282 if (ic->ic_opmode == IEEE80211_M_IBSS)
2283 arg = NDIS_80211_NET_INFRA_IBSS;
2285 arg = NDIS_80211_NET_INFRA_BSS;
2287 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2290 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2292 /* Set power management */
2294 if (vap->iv_flags & IEEE80211_F_PMGTON)
2295 arg = NDIS_80211_POWERMODE_FAST_PSP;
2297 arg = NDIS_80211_POWERMODE_CAM;
2298 ndis_set_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2301 if ((ic->ic_caps & IEEE80211_C_TXPMGT) &&
2302 ic->ic_txpowlimit < (sizeof(dBm2mW) / sizeof(dBm2mW[0]))) {
2303 arg = dBm2mW[ic->ic_txpowlimit];
2305 ndis_set_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2309 * Default encryption mode to off, authentication
2310 * to open and privacy to 'accept everything.'
2313 arg = NDIS_80211_WEPSTAT_DISABLED;
2314 ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
2317 arg = NDIS_80211_AUTHMODE_OPEN;
2318 ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2321 * Note that OID_802_11_PRIVACY_FILTER is optional:
2322 * not all drivers implement it.
2325 arg = NDIS_80211_PRIVFILT_8021XWEP;
2326 ndis_set_info(sc, OID_802_11_PRIVACY_FILTER, &arg, &len);
2328 len = sizeof(config);
2329 bzero((char *)&config, len);
2330 config.nc_length = len;
2331 config.nc_fhconfig.ncf_length = sizeof(ndis_80211_config_fh);
2332 rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len);
2335 * Some drivers expect us to initialize these values, so
2336 * provide some defaults.
2339 if (config.nc_beaconperiod == 0)
2340 config.nc_beaconperiod = 100;
2341 if (config.nc_atimwin == 0)
2342 config.nc_atimwin = 100;
2343 if (config.nc_fhconfig.ncf_dwelltime == 0)
2344 config.nc_fhconfig.ncf_dwelltime = 200;
2345 if (rval == 0 && ic->ic_bsschan != IEEE80211_CHAN_ANYC) {
2348 chan = ieee80211_chan2ieee(ic, ic->ic_bsschan);
2349 chanflag = config.nc_dsconfig > 2500000 ? IEEE80211_CHAN_2GHZ :
2350 IEEE80211_CHAN_5GHZ;
2351 if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) {
2352 config.nc_dsconfig =
2353 ic->ic_bsschan->ic_freq * 1000;
2354 len = sizeof(config);
2355 config.nc_length = len;
2356 config.nc_fhconfig.ncf_length =
2357 sizeof(ndis_80211_config_fh);
2358 DPRINTF(("Setting channel to %ukHz\n", config.nc_dsconfig));
2359 rval = ndis_set_info(sc, OID_802_11_CONFIGURATION,
2362 device_printf(sc->ndis_dev, "couldn't change "
2363 "DS config to %ukHz: %d\n",
2364 config.nc_dsconfig, rval);
2367 device_printf(sc->ndis_dev, "couldn't retrieve "
2368 "channel info: %d\n", rval);
2370 /* Set the BSSID to our value so the driver doesn't associate */
2371 len = IEEE80211_ADDR_LEN;
2372 bcopy(IF_LLADDR(ifp), bssid, len);
2373 DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
2374 rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2376 device_printf(sc->ndis_dev,
2377 "setting BSSID failed: %d\n", rval);
2381 ndis_auth_and_assoc(sc, vap)
2382 struct ndis_softc *sc;
2383 struct ieee80211vap *vap;
2385 struct ieee80211com *ic;
2386 struct ieee80211_node *ni;
2387 ndis_80211_ssid ssid;
2388 ndis_80211_macaddr bssid;
2390 int i, rval = 0, len, error;
2398 if (!NDIS_INITIALIZED(sc)) {
2399 DPRINTF(("%s: NDIS not initialized\n", __func__));
2404 ndis_setstate_80211(sc);
2406 /* Set network infrastructure mode. */
2409 if (vap->iv_opmode == IEEE80211_M_IBSS)
2410 arg = NDIS_80211_NET_INFRA_IBSS;
2412 arg = NDIS_80211_NET_INFRA_BSS;
2414 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len);
2417 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
2419 /* Set RTS threshold */
2422 arg = vap->iv_rtsthreshold;
2423 ndis_set_info(sc, OID_802_11_RTS_THRESHOLD, &arg, &len);
2425 /* Set fragmentation threshold */
2428 arg = vap->iv_fragthreshold;
2429 ndis_set_info(sc, OID_802_11_FRAGMENTATION_THRESHOLD, &arg, &len);
2433 if (vap->iv_flags & IEEE80211_F_PRIVACY &&
2434 !(vap->iv_flags & IEEE80211_F_WPA)) {
2437 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
2439 arg = NDIS_80211_AUTHMODE_SHARED;
2440 DPRINTF(("Setting shared auth\n"));
2441 ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE,
2444 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2445 if (vap->iv_nw_keys[i].wk_keylen) {
2446 if (vap->iv_nw_keys[i].wk_cipher->ic_cipher !=
2447 IEEE80211_CIPHER_WEP)
2449 bzero((char *)&wep, sizeof(wep));
2450 wep.nw_keylen = vap->iv_nw_keys[i].wk_keylen;
2453 * 5, 13 and 16 are the only valid
2454 * key lengths. Anything in between
2455 * will be zero padded out to the
2456 * next highest boundary.
2458 if (vap->iv_nw_keys[i].wk_keylen < 5)
2460 else if (vap->iv_nw_keys[i].wk_keylen > 5 &&
2461 vap->iv_nw_keys[i].wk_keylen < 13)
2463 else if (vap->iv_nw_keys[i].wk_keylen > 13 &&
2464 vap->iv_nw_keys[i].wk_keylen < 16)
2468 wep.nw_length = (sizeof(uint32_t) * 3)
2470 if (i == vap->iv_def_txkey)
2471 wep.nw_keyidx |= NDIS_80211_WEPKEY_TX;
2472 bcopy(vap->iv_nw_keys[i].wk_key,
2473 wep.nw_keydata, wep.nw_length);
2475 DPRINTF(("Setting WEP key %d\n", i));
2476 rval = ndis_set_info(sc,
2477 OID_802_11_ADD_WEP, &wep, &len);
2479 device_printf(sc->ndis_dev,
2480 "set wepkey failed: %d\n", rval);
2485 DPRINTF(("Setting WEP on\n"));
2486 arg = NDIS_80211_WEPSTAT_ENABLED;
2488 rval = ndis_set_info(sc,
2489 OID_802_11_WEP_STATUS, &arg, &len);
2491 device_printf(sc->ndis_dev,
2492 "enable WEP failed: %d\n", rval);
2493 if (vap->iv_flags & IEEE80211_F_DROPUNENC)
2494 arg = NDIS_80211_PRIVFILT_8021XWEP;
2496 arg = NDIS_80211_PRIVFILT_ACCEPTALL;
2500 OID_802_11_PRIVACY_FILTER, &arg, &len);
2505 if ((vap->iv_flags & IEEE80211_F_WPA) &&
2506 vap->iv_appie_assocreq != NULL) {
2507 struct ieee80211_appie *ie = vap->iv_appie_assocreq;
2508 error = ndis_set_wpa(sc, ie->ie_data, ie->ie_len);
2510 device_printf(sc->ndis_dev, "WPA setup failed\n");
2514 /* Set network type. */
2518 switch (vap->iv_curmode) {
2519 case IEEE80211_MODE_11A:
2520 arg = NDIS_80211_NETTYPE_11OFDM5;
2522 case IEEE80211_MODE_11B:
2523 arg = NDIS_80211_NETTYPE_11DS;
2525 case IEEE80211_MODE_11G:
2526 arg = NDIS_80211_NETTYPE_11OFDM24;
2529 device_printf(sc->ndis_dev, "unknown mode: %d\n",
2534 DPRINTF(("Setting network type to %d\n", arg));
2536 rval = ndis_set_info(sc, OID_802_11_NETWORK_TYPE_IN_USE,
2539 device_printf(sc->ndis_dev,
2540 "set nettype failed: %d\n", rval);
2545 * If the user selected a specific BSSID, try
2546 * to use that one. This is useful in the case where
2547 * there are several APs in range with the same network
2548 * name. To delete the BSSID, we use the broadcast
2549 * address as the BSSID.
2550 * Note that some drivers seem to allow setting a BSSID
2551 * in ad-hoc mode, which has the effect of forcing the
2552 * NIC to create an ad-hoc cell with a specific BSSID,
2553 * instead of a randomly chosen one. However, the net80211
2554 * code makes the assumtion that the BSSID setting is invalid
2555 * when you're in ad-hoc mode, so we don't allow that here.
2558 len = IEEE80211_ADDR_LEN;
2559 if (vap->iv_flags & IEEE80211_F_DESBSSID &&
2560 vap->iv_opmode != IEEE80211_M_IBSS)
2561 bcopy(ni->ni_bssid, bssid, len);
2563 bcopy(ifp->if_broadcastaddr, bssid, len);
2565 DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
2566 rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
2568 device_printf(sc->ndis_dev,
2569 "setting BSSID failed: %d\n", rval);
2571 /* Set SSID -- always do this last. */
2574 if (ndis_debug > 0) {
2575 printf("Setting ESSID to ");
2576 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2582 bzero((char *)&ssid, len);
2583 ssid.ns_ssidlen = ni->ni_esslen;
2584 if (ssid.ns_ssidlen == 0) {
2585 ssid.ns_ssidlen = 1;
2587 bcopy(ni->ni_essid, ssid.ns_ssid, ssid.ns_ssidlen);
2589 rval = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
2592 device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval);
2598 ndis_get_bssid_list(sc, bl)
2599 struct ndis_softc *sc;
2600 ndis_80211_bssid_list_ex **bl;
2604 len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16);
2605 *bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2609 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2610 if (error == ENOSPC) {
2611 free(*bl, M_DEVBUF);
2612 *bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
2616 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len);
2619 DPRINTF(("%s: failed to read\n", __func__));
2620 free(*bl, M_DEVBUF);
2628 ndis_get_assoc(sc, assoc)
2629 struct ndis_softc *sc;
2630 ndis_wlan_bssid_ex **assoc;
2632 struct ifnet *ifp = sc->ifp;
2633 struct ieee80211com *ic = ifp->if_l2com;
2634 struct ieee80211vap *vap;
2635 struct ieee80211_node *ni;
2636 ndis_80211_bssid_list_ex *bl;
2637 ndis_wlan_bssid_ex *bs;
2638 ndis_80211_macaddr bssid;
2644 len = sizeof(bssid);
2645 error = ndis_get_info(sc, OID_802_11_BSSID, &bssid, &len);
2647 device_printf(sc->ndis_dev, "failed to get bssid\n");
2651 vap = TAILQ_FIRST(&ic->ic_vaps);
2654 error = ndis_get_bssid_list(sc, &bl);
2658 bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0];
2659 for (i = 0; i < bl->nblx_items; i++) {
2660 if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) {
2661 *assoc = malloc(bs->nwbx_len, M_TEMP, M_NOWAIT);
2662 if (*assoc == NULL) {
2666 bcopy((char *)bs, (char *)*assoc, bs->nwbx_len);
2668 if (ic->ic_opmode == IEEE80211_M_STA)
2669 ni->ni_associd = 1 | 0xc000; /* fake associd */
2672 bs = (ndis_wlan_bssid_ex *)((char *)bs + bs->nwbx_len);
2680 ndis_getstate_80211(sc)
2681 struct ndis_softc *sc;
2683 struct ieee80211com *ic;
2684 struct ieee80211vap *vap;
2685 struct ieee80211_node *ni;
2686 ndis_wlan_bssid_ex *bs;
2687 int rval, len, i = 0;
2694 vap = TAILQ_FIRST(&ic->ic_vaps);
2697 if (!NDIS_INITIALIZED(sc))
2700 if ((rval = ndis_get_assoc(sc, &bs)) != 0)
2703 /* We're associated, retrieve info on the current bssid. */
2704 ic->ic_curmode = ndis_nettype_mode(bs->nwbx_nettype);
2705 chanflag = ndis_nettype_chan(bs->nwbx_nettype);
2706 IEEE80211_ADDR_COPY(ni->ni_bssid, bs->nwbx_macaddr);
2708 /* Get SSID from current association info. */
2709 bcopy(bs->nwbx_ssid.ns_ssid, ni->ni_essid,
2710 bs->nwbx_ssid.ns_ssidlen);
2711 ni->ni_esslen = bs->nwbx_ssid.ns_ssidlen;
2713 if (ic->ic_caps & IEEE80211_C_PMGT) {
2715 rval = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &len);
2718 device_printf(sc->ndis_dev,
2719 "get power mode failed: %d\n", rval);
2720 if (arg == NDIS_80211_POWERMODE_CAM)
2721 vap->iv_flags &= ~IEEE80211_F_PMGTON;
2723 vap->iv_flags |= IEEE80211_F_PMGTON;
2727 if (ic->ic_caps & IEEE80211_C_TXPMGT) {
2729 ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
2730 for (i = 0; i < (sizeof(dBm2mW) / sizeof(dBm2mW[0])); i++)
2731 if (dBm2mW[i] >= arg)
2733 ic->ic_txpowlimit = i;
2737 * Use the current association information to reflect
2738 * what channel we're on.
2740 ic->ic_curchan = ieee80211_find_channel(ic,
2741 bs->nwbx_config.nc_dsconfig / 1000, chanflag);
2742 if (ic->ic_curchan == NULL)
2743 ic->ic_curchan = &ic->ic_channels[0];
2744 ni->ni_chan = ic->ic_curchan;
2745 ic->ic_bsschan = ic->ic_curchan;
2750 * Determine current authentication mode.
2753 rval = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
2755 device_printf(sc->ndis_dev,
2756 "get authmode status failed: %d\n", rval);
2758 vap->iv_flags &= ~IEEE80211_F_WPA;
2760 case NDIS_80211_AUTHMODE_OPEN:
2761 ni->ni_authmode = IEEE80211_AUTH_OPEN;
2763 case NDIS_80211_AUTHMODE_SHARED:
2764 ni->ni_authmode = IEEE80211_AUTH_SHARED;
2766 case NDIS_80211_AUTHMODE_AUTO:
2767 ni->ni_authmode = IEEE80211_AUTH_AUTO;
2769 case NDIS_80211_AUTHMODE_WPA:
2770 case NDIS_80211_AUTHMODE_WPAPSK:
2771 case NDIS_80211_AUTHMODE_WPANONE:
2772 ni->ni_authmode = IEEE80211_AUTH_WPA;
2773 vap->iv_flags |= IEEE80211_F_WPA1;
2775 case NDIS_80211_AUTHMODE_WPA2:
2776 case NDIS_80211_AUTHMODE_WPA2PSK:
2777 ni->ni_authmode = IEEE80211_AUTH_WPA;
2778 vap->iv_flags |= IEEE80211_F_WPA2;
2781 ni->ni_authmode = IEEE80211_AUTH_NONE;
2787 rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len);
2790 device_printf(sc->ndis_dev,
2791 "get wep status failed: %d\n", rval);
2793 if (arg == NDIS_80211_WEPSTAT_ENABLED)
2794 vap->iv_flags |= IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC;
2796 vap->iv_flags &= ~(IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC);
2800 ndis_ioctl(ifp, command, data)
2805 struct ndis_softc *sc = ifp->if_softc;
2806 struct ifreq *ifr = (struct ifreq *) data;
2813 if (ifp->if_flags & IFF_UP) {
2814 if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
2815 ifp->if_flags & IFF_PROMISC &&
2816 !(sc->ndis_if_flags & IFF_PROMISC)) {
2818 NDIS_PACKET_TYPE_PROMISCUOUS;
2819 i = sizeof(sc->ndis_filter);
2820 error = ndis_set_info(sc,
2821 OID_GEN_CURRENT_PACKET_FILTER,
2822 &sc->ndis_filter, &i);
2823 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
2824 !(ifp->if_flags & IFF_PROMISC) &&
2825 sc->ndis_if_flags & IFF_PROMISC) {
2827 ~NDIS_PACKET_TYPE_PROMISCUOUS;
2828 i = sizeof(sc->ndis_filter);
2829 error = ndis_set_info(sc,
2830 OID_GEN_CURRENT_PACKET_FILTER,
2831 &sc->ndis_filter, &i);
2835 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2838 sc->ndis_if_flags = ifp->if_flags;
2848 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
2851 ifp->if_capenable = ifr->ifr_reqcap;
2852 if (ifp->if_capenable & IFCAP_TXCSUM)
2853 ifp->if_hwassist = sc->ndis_hwassist;
2855 ifp->if_hwassist = 0;
2856 ndis_set_offload(sc);
2859 error = ether_ioctl(ifp, command, data);
2863 /*NDIS_UNLOCK(sc);*/
2869 ndis_ioctl_80211(ifp, command, data)
2874 struct ndis_softc *sc = ifp->if_softc;
2875 struct ieee80211com *ic = ifp->if_l2com;
2876 struct ifreq *ifr = (struct ifreq *) data;
2877 struct ndis_oid_data oid;
2878 struct ndis_evt evt;
2885 if (ifp->if_flags & IFF_UP) {
2886 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2889 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2892 sc->ndis_if_flags = ifp->if_flags;
2894 /*NDIS_UNLOCK(sc);*/
2897 if ((error = priv_check(curthread, PRIV_DRIVER)))
2899 error = copyin(ifr->ifr_data, &oid, sizeof(oid));
2902 oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2903 if (oidbuf == NULL) {
2907 error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2909 free(oidbuf, M_TEMP);
2912 error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len);
2914 free(oidbuf, M_TEMP);
2917 error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2919 free(oidbuf, M_TEMP);
2922 error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
2923 free(oidbuf, M_TEMP);
2926 if ((error = priv_check(curthread, PRIV_DRIVER)))
2928 error = copyin(ifr->ifr_data, &oid, sizeof(oid));
2931 oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
2932 if (oidbuf == NULL) {
2936 error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
2938 free(oidbuf, M_TEMP);
2941 error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len);
2943 free(oidbuf, M_TEMP);
2946 error = copyout(&oid, ifr->ifr_data, sizeof(oid));
2948 free(oidbuf, M_TEMP);
2951 error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
2952 free(oidbuf, M_TEMP);
2954 case SIOCGPRIVATE_0:
2955 if ((error = priv_check(curthread, PRIV_DRIVER)))
2958 if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) {
2963 error = copyin(ifr->ifr_data, &evt, sizeof(evt));
2968 if (evt.ne_len < sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2973 error = copyout(&sc->ndis_evt[sc->ndis_evtcidx],
2974 ifr->ifr_data, sizeof(uint32_t) * 2);
2979 if (sc->ndis_evt[sc->ndis_evtcidx].ne_len) {
2980 error = copyout(sc->ndis_evt[sc->ndis_evtcidx].ne_buf,
2981 ifr->ifr_data + (sizeof(uint32_t) * 2),
2982 sc->ndis_evt[sc->ndis_evtcidx].ne_len);
2987 free(sc->ndis_evt[sc->ndis_evtcidx].ne_buf, M_TEMP);
2988 sc->ndis_evt[sc->ndis_evtcidx].ne_buf = NULL;
2990 sc->ndis_evt[sc->ndis_evtcidx].ne_len = 0;
2991 sc->ndis_evt[sc->ndis_evtcidx].ne_sts = 0;
2992 NDIS_EVTINC(sc->ndis_evtcidx);
2996 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
2999 error = ether_ioctl(ifp, command, data);
3009 ndis_del_key(vap, key)
3010 struct ieee80211vap *vap;
3011 const struct ieee80211_key *key;
3013 struct ndis_softc *sc;
3014 ndis_80211_key rkey;
3017 sc = vap->iv_ic->ic_ifp->if_softc;
3019 bzero((char *)&rkey, sizeof(rkey));
3023 rkey.nk_keyidx = key->wk_keyix;
3025 bcopy(vap->iv_ifp->if_broadcastaddr,
3026 rkey.nk_bssid, IEEE80211_ADDR_LEN);
3028 error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len);
3037 * In theory this could be called for any key, but we'll
3038 * only use it for WPA TKIP or AES keys. These need to be
3039 * set after initial authentication with the AP.
3042 ndis_add_key(vap, key, mac)
3043 struct ieee80211vap *vap;
3044 const struct ieee80211_key *key;
3045 const uint8_t mac[IEEE80211_ADDR_LEN];
3047 struct ndis_softc *sc;
3049 ndis_80211_key rkey;
3052 ifp = vap->iv_ic->ic_ifp;
3055 switch (key->wk_cipher->ic_cipher) {
3056 case IEEE80211_CIPHER_TKIP:
3058 len = sizeof(ndis_80211_key);
3059 bzero((char *)&rkey, sizeof(rkey));
3062 rkey.nk_keylen = key->wk_keylen;
3064 if (key->wk_flags & IEEE80211_KEY_SWMIC)
3065 rkey.nk_keylen += 16;
3067 /* key index - gets weird in NDIS */
3069 if (key->wk_keyix != IEEE80211_KEYIX_NONE)
3070 rkey.nk_keyidx = key->wk_keyix;
3074 if (key->wk_flags & IEEE80211_KEY_XMIT)
3075 rkey.nk_keyidx |= 1 << 31;
3077 if (key->wk_flags & IEEE80211_KEY_GROUP) {
3078 bcopy(ifp->if_broadcastaddr,
3079 rkey.nk_bssid, IEEE80211_ADDR_LEN);
3081 bcopy(vap->iv_bss->ni_bssid,
3082 rkey.nk_bssid, IEEE80211_ADDR_LEN);
3084 rkey.nk_keyidx |= 1 << 30;
3087 /* need to set bit 29 based on keyrsc */
3088 rkey.nk_keyrsc = key->wk_keyrsc[0]; /* XXX need tid */
3091 rkey.nk_keyidx |= 1 << 29;
3093 if (key->wk_flags & IEEE80211_KEY_SWMIC) {
3094 bcopy(key->wk_key, rkey.nk_keydata, 16);
3095 bcopy(key->wk_key + 24, rkey.nk_keydata + 16, 8);
3096 bcopy(key->wk_key + 16, rkey.nk_keydata + 24, 8);
3098 bcopy(key->wk_key, rkey.nk_keydata, key->wk_keylen);
3100 error = ndis_set_info(sc, OID_802_11_ADD_KEY, &rkey, &len);
3102 case IEEE80211_CIPHER_WEP:
3106 * I don't know how to set up keys for the AES
3107 * cipher yet. Is it the same as TKIP?
3109 case IEEE80211_CIPHER_AES_CCM:
3115 /* We need to return 1 for success, 0 for failure. */
3124 ndis_resettask(d, arg)
3128 struct ndis_softc *sc;
3135 * Stop the adapter and free any mbufs allocated to the
3140 struct ndis_softc *sc;
3146 callout_drain(&sc->ndis_stat_callout);
3149 sc->ndis_tx_timer = 0;
3151 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3154 if (sc->ndis_iftype != PNPBus ||
3155 (sc->ndis_iftype == PNPBus &&
3156 !(sc->ndisusb_status & NDISUSB_STATUS_DETACH) &&
3161 for (i = 0; i < NDIS_EVENTS; i++) {
3162 if (sc->ndis_evt[i].ne_sts && sc->ndis_evt[i].ne_buf != NULL) {
3163 free(sc->ndis_evt[i].ne_buf, M_TEMP);
3164 sc->ndis_evt[i].ne_buf = NULL;
3166 sc->ndis_evt[i].ne_sts = 0;
3167 sc->ndis_evt[i].ne_len = 0;
3169 sc->ndis_evtcidx = 0;
3170 sc->ndis_evtpidx = 0;
3175 * Stop all chip I/O so that the kernel's probe routines don't
3176 * get confused by errant DMAs when rebooting.
3182 struct ndis_softc *sc;
3184 sc = device_get_softc(dev);
3189 ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3191 struct ndis_vap *nvp = NDIS_VAP(vap);
3192 struct ieee80211com *ic = vap->iv_ic;
3193 struct ifnet *ifp = ic->ic_ifp;
3194 struct ndis_softc *sc = ifp->if_softc;
3195 enum ieee80211_state ostate;
3197 DPRINTF(("%s: %s -> %s\n", __func__,
3198 ieee80211_state_name[vap->iv_state],
3199 ieee80211_state_name[nstate]));
3201 ostate = vap->iv_state;
3202 vap->iv_state = nstate;
3205 /* pass on to net80211 */
3206 case IEEE80211_S_INIT:
3207 case IEEE80211_S_SCAN:
3208 return nvp->newstate(vap, nstate, arg);
3209 case IEEE80211_S_ASSOC:
3210 if (ostate != IEEE80211_S_AUTH) {
3211 IEEE80211_UNLOCK(ic);
3212 ndis_auth_and_assoc(sc, vap);
3216 case IEEE80211_S_AUTH:
3217 IEEE80211_UNLOCK(ic);
3218 ndis_auth_and_assoc(sc, vap);
3219 if (vap->iv_state == IEEE80211_S_AUTH) /* XXX */
3220 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
3230 ndis_scan(void *arg)
3232 struct ieee80211vap *vap = arg;
3234 ieee80211_scan_done(vap);
3238 ndis_scan_results(struct ndis_softc *sc)
3240 struct ieee80211com *ic;
3241 struct ieee80211vap *vap;
3242 ndis_80211_bssid_list_ex *bl;
3243 ndis_wlan_bssid_ex *wb;
3244 struct ieee80211_scanparams sp;
3245 struct ieee80211_frame wh;
3246 struct ieee80211_channel *saved_chan;
3248 int rssi, noise, freq, chanflag;
3249 uint8_t ssid[2+IEEE80211_NWID_LEN];
3250 uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
3251 uint8_t *frm, *efrm;
3253 ic = sc->ifp->if_l2com;
3254 vap = TAILQ_FIRST(&ic->ic_vaps);
3255 saved_chan = ic->ic_curchan;
3258 if (ndis_get_bssid_list(sc, &bl))
3261 DPRINTF(("%s: %d results\n", __func__, bl->nblx_items));
3262 wb = &bl->nblx_bssid[0];
3263 for (i = 0; i < bl->nblx_items; i++) {
3264 memset(&sp, 0, sizeof(sp));
3266 memcpy(wh.i_addr2, wb->nwbx_macaddr, sizeof(wh.i_addr2));
3267 memcpy(wh.i_addr3, wb->nwbx_macaddr, sizeof(wh.i_addr3));
3268 rssi = 100 * (wb->nwbx_rssi - noise) / (-32 - noise);
3269 rssi = max(0, min(rssi, 100)); /* limit 0 <= rssi <= 100 */
3270 if (wb->nwbx_privacy)
3271 sp.capinfo |= IEEE80211_CAPINFO_PRIVACY;
3272 sp.bintval = wb->nwbx_config.nc_beaconperiod;
3273 switch (wb->nwbx_netinfra) {
3274 case NDIS_80211_NET_INFRA_IBSS:
3275 sp.capinfo |= IEEE80211_CAPINFO_IBSS;
3277 case NDIS_80211_NET_INFRA_BSS:
3278 sp.capinfo |= IEEE80211_CAPINFO_ESS;
3281 sp.rates = &rates[0];
3282 for (j = 0; j < IEEE80211_RATE_MAXSIZE; j++) {
3283 /* XXX - check units */
3284 if (wb->nwbx_supportedrates[j] == 0)
3287 wb->nwbx_supportedrates[j] & 0x7f;
3290 sp.ssid = (uint8_t *)&ssid[0];
3291 memcpy(sp.ssid + 2, &wb->nwbx_ssid.ns_ssid,
3292 wb->nwbx_ssid.ns_ssidlen);
3293 sp.ssid[1] = wb->nwbx_ssid.ns_ssidlen;
3295 chanflag = ndis_nettype_chan(wb->nwbx_nettype);
3296 freq = wb->nwbx_config.nc_dsconfig / 1000;
3297 sp.chan = sp.bchan = ieee80211_mhz2ieee(freq, chanflag);
3298 /* Hack ic->ic_curchan to be in sync with the scan result */
3299 ic->ic_curchan = ieee80211_find_channel(ic, freq, chanflag);
3300 if (ic->ic_curchan == NULL)
3301 ic->ic_curchan = &ic->ic_channels[0];
3303 /* Process extended info from AP */
3304 if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) {
3305 frm = (uint8_t *)&wb->nwbx_ies;
3306 efrm = frm + wb->nwbx_ielen;
3307 if (efrm - frm < 12)
3309 sp.tstamp = frm; frm += 8;
3310 sp.bintval = le16toh(*(uint16_t *)frm); frm += 2;
3311 sp.capinfo = le16toh(*(uint16_t *)frm); frm += 2;
3313 sp.ies_len = efrm - frm;
3316 DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n",
3317 ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag,
3319 ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise);
3320 wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len);
3323 /* Restore the channel after messing with it */
3324 ic->ic_curchan = saved_chan;
3328 ndis_scan_start(struct ieee80211com *ic)
3330 struct ifnet *ifp = ic->ic_ifp;
3331 struct ndis_softc *sc = ifp->if_softc;
3332 struct ieee80211vap *vap;
3333 struct ieee80211_scan_state *ss;
3334 ndis_80211_ssid ssid;
3338 vap = TAILQ_FIRST(&ic->ic_vaps);
3340 if (!NDIS_INITIALIZED(sc)) {
3341 DPRINTF(("%s: scan aborted\n", __func__));
3342 ieee80211_cancel_scan(vap);
3347 bzero((char *)&ssid, len);
3348 if (ss->ss_nssid == 0)
3349 ssid.ns_ssidlen = 1;
3351 /* Perform a directed scan */
3352 ssid.ns_ssidlen = ss->ss_ssid[0].len;
3353 bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
3356 error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
3358 DPRINTF(("%s: set ESSID failed\n", __func__));
3361 error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, NULL, &len);
3363 DPRINTF(("%s: scan command failed\n", __func__));
3364 ieee80211_cancel_scan(vap);
3367 /* Set a timer to collect the results */
3368 callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, vap);
3372 ndis_set_channel(struct ieee80211com *ic)
3378 ndis_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
3384 ndis_scan_mindwell(struct ieee80211_scan_state *ss)
3386 /* NB: don't try to abort scan; wait for firmware to finish */
3390 ndis_scan_end(struct ieee80211com *ic)
3392 struct ndis_softc *sc = ic->ic_ifp->if_softc;
3394 ndis_scan_results(sc);