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