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