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