1 /* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. 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 * $FreeBSD: src/sys/dev/wi/if_wi.c,v 1.103.2.2 2002/08/02 07:11:34 imp Exp $ 33 * $DragonFly: src/sys/dev/netif/wi/if_wi.c,v 1.2 2003/06/17 04:28:33 dillon Exp $ 34 */ 35 36 /* 37 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 38 * 39 * Written by Bill Paul <wpaul@ctr.columbia.edu> 40 * Electrical Engineering Department 41 * Columbia University, New York City 42 */ 43 44 /* 45 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 46 * from Lucent. Unlike the older cards, the new ones are programmed 47 * entirely via a firmware-driven controller called the Hermes. 48 * Unfortunately, Lucent will not release the Hermes programming manual 49 * without an NDA (if at all). What they do release is an API library 50 * called the HCF (Hardware Control Functions) which is supposed to 51 * do the device-specific operations of a device driver for you. The 52 * publically available version of the HCF library (the 'HCF Light') is 53 * a) extremely gross, b) lacks certain features, particularly support 54 * for 802.11 frames, and c) is contaminated by the GNU Public License. 55 * 56 * This driver does not use the HCF or HCF Light at all. Instead, it 57 * programs the Hermes controller directly, using information gleaned 58 * from the HCF Light code and corresponding documentation. 59 * 60 * This driver supports the ISA, PCMCIA and PCI versions of the Lucent 61 * WaveLan cards (based on the Hermes chipset), as well as the newer 62 * Prism 2 chipsets with firmware from Intersil and Symbol. 63 */ 64 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #if __FreeBSD_version >= 500033 68 #include <sys/endian.h> 69 #endif 70 #include <sys/sockio.h> 71 #include <sys/mbuf.h> 72 #include <sys/proc.h> 73 #include <sys/kernel.h> 74 #include <sys/socket.h> 75 #include <sys/module.h> 76 #include <sys/bus.h> 77 #include <sys/random.h> 78 #include <sys/syslog.h> 79 #include <sys/sysctl.h> 80 81 #include <machine/bus.h> 82 #include <machine/resource.h> 83 #include <machine/clock.h> 84 #include <sys/rman.h> 85 86 #include <net/if.h> 87 #include <net/if_arp.h> 88 #include <net/ethernet.h> 89 #include <net/if_dl.h> 90 #include <net/if_media.h> 91 #include <net/if_types.h> 92 #include <net/if_ieee80211.h> 93 94 #include <netinet/in.h> 95 #include <netinet/in_systm.h> 96 #include <netinet/in_var.h> 97 #include <netinet/ip.h> 98 #include <netinet/if_ether.h> 99 100 #include <net/bpf.h> 101 102 #include <dev/wi/if_wavelan_ieee.h> 103 #include <dev/wi/wi_hostap.h> 104 #include <dev/wi/if_wivar.h> 105 #include <dev/wi/if_wireg.h> 106 107 static void wi_intr(void *); 108 static void wi_reset(struct wi_softc *); 109 static int wi_ioctl(struct ifnet *, u_long, caddr_t); 110 static void wi_init(void *); 111 static void wi_start(struct ifnet *); 112 static void wi_stop(struct wi_softc *); 113 static void wi_watchdog(struct ifnet *); 114 static void wi_rxeof(struct wi_softc *); 115 static void wi_txeof(struct wi_softc *, int); 116 static void wi_update_stats(struct wi_softc *); 117 static void wi_setmulti(struct wi_softc *); 118 119 static int wi_cmd(struct wi_softc *, int, int, int, int); 120 static int wi_read_record(struct wi_softc *, struct wi_ltv_gen *); 121 static int wi_write_record(struct wi_softc *, struct wi_ltv_gen *); 122 static int wi_read_data(struct wi_softc *, int, int, caddr_t, int); 123 static int wi_write_data(struct wi_softc *, int, int, caddr_t, int); 124 static int wi_seek(struct wi_softc *, int, int, int); 125 static int wi_alloc_nicmem(struct wi_softc *, int, int *); 126 static void wi_inquire(void *); 127 static void wi_setdef(struct wi_softc *, struct wi_req *); 128 129 #ifdef WICACHE 130 static 131 void wi_cache_store(struct wi_softc *, struct ether_header *, 132 struct mbuf *, unsigned short); 133 #endif 134 135 static int wi_get_cur_ssid(struct wi_softc *, char *, int *); 136 static void wi_get_id(struct wi_softc *); 137 static int wi_media_change(struct ifnet *); 138 static void wi_media_status(struct ifnet *, struct ifmediareq *); 139 140 static int wi_get_debug(struct wi_softc *, struct wi_req *); 141 static int wi_set_debug(struct wi_softc *, struct wi_req *); 142 143 devclass_t wi_devclass; 144 145 struct wi_card_ident wi_card_ident[] = { 146 /* CARD_ID CARD_NAME FIRM_TYPE */ 147 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT }, 148 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT }, 149 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT }, 150 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL }, 151 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL }, 152 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL }, 153 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL }, 154 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL }, 155 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL }, 156 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL }, 157 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL }, 158 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL }, 159 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 160 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 161 { WI_NIC_3842_PCMCIA_ATM_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 162 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 163 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 164 { WI_NIC_3842_MINI_ATM_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 165 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 166 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 167 { WI_NIC_3842_PCI_ATM_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 168 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 169 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 170 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 171 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 172 { 0, NULL, 0 }, 173 }; 174 175 int 176 wi_generic_detach(dev) 177 device_t dev; 178 { 179 struct wi_softc *sc; 180 struct ifnet *ifp; 181 int s; 182 183 sc = device_get_softc(dev); 184 WI_LOCK(sc, s); 185 ifp = &sc->arpcom.ac_if; 186 187 if (sc->wi_gone) { 188 device_printf(dev, "already unloaded\n"); 189 WI_UNLOCK(sc, s); 190 return(ENODEV); 191 } 192 193 wi_stop(sc); 194 195 /* Delete all remaining media. */ 196 ifmedia_removeall(&sc->ifmedia); 197 198 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); 199 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); 200 wi_free(dev); 201 sc->wi_gone = 1; 202 203 WI_UNLOCK(sc, s); 204 #if __FreeBSD_version >= 500000 205 mtx_destroy(&sc->wi_mtx); 206 #endif 207 208 return(0); 209 } 210 211 int 212 wi_generic_attach(device_t dev) 213 { 214 struct wi_softc *sc; 215 struct wi_ltv_macaddr mac; 216 struct wi_ltv_gen gen; 217 struct ifnet *ifp; 218 int error; 219 int s; 220 221 /* XXX maybe we need the splimp stuff here XXX */ 222 sc = device_get_softc(dev); 223 ifp = &sc->arpcom.ac_if; 224 225 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 226 wi_intr, sc, &sc->wi_intrhand); 227 228 if (error) { 229 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 230 wi_free(dev); 231 return (error); 232 } 233 234 #if __FreeBSD_version >= 500000 235 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 236 MTX_DEF | MTX_RECURSE); 237 #endif 238 WI_LOCK(sc, s); 239 240 /* Reset the NIC. */ 241 wi_reset(sc); 242 243 /* 244 * Read the station address. 245 * And do it twice. I've seen PRISM-based cards that return 246 * an error when trying to read it the first time, which causes 247 * the probe to fail. 248 */ 249 mac.wi_type = WI_RID_MAC_NODE; 250 mac.wi_len = 4; 251 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 252 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) { 253 device_printf(dev, "mac read failed %d\n", error); 254 wi_free(dev); 255 return (error); 256 } 257 bcopy((char *)&mac.wi_mac_addr, 258 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 259 260 device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":"); 261 262 wi_get_id(sc); 263 264 ifp->if_softc = sc; 265 ifp->if_unit = sc->wi_unit; 266 ifp->if_name = "wi"; 267 ifp->if_mtu = ETHERMTU; 268 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 269 ifp->if_ioctl = wi_ioctl; 270 ifp->if_output = ether_output; 271 ifp->if_start = wi_start; 272 ifp->if_watchdog = wi_watchdog; 273 ifp->if_init = wi_init; 274 ifp->if_baudrate = 10000000; 275 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 276 277 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 278 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name, 279 sizeof(WI_DEFAULT_NODENAME) - 1); 280 281 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 282 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name, 283 sizeof(WI_DEFAULT_NETNAME) - 1); 284 285 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 286 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name, 287 sizeof(WI_DEFAULT_IBSS) - 1); 288 289 sc->wi_portnum = WI_DEFAULT_PORT; 290 sc->wi_ptype = WI_PORTTYPE_BSS; 291 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 292 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 293 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 294 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 295 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 296 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 297 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 298 sc->wi_roaming = WI_DEFAULT_ROAMING; 299 sc->wi_authtype = WI_DEFAULT_AUTHTYPE; 300 sc->wi_authmode = IEEE80211_AUTH_OPEN; 301 302 /* 303 * Read the default channel from the NIC. This may vary 304 * depending on the country where the NIC was purchased, so 305 * we can't hard-code a default and expect it to work for 306 * everyone. 307 */ 308 gen.wi_type = WI_RID_OWN_CHNL; 309 gen.wi_len = 2; 310 wi_read_record(sc, &gen); 311 sc->wi_channel = gen.wi_val; 312 313 /* 314 * Set flags based on firmware version. 315 */ 316 switch (sc->sc_firmware_type) { 317 case WI_LUCENT: 318 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 319 if (sc->sc_sta_firmware_ver >= 60000) 320 sc->wi_flags |= WI_FLAGS_HAS_MOR; 321 if (sc->sc_sta_firmware_ver >= 60006) { 322 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 323 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 324 } 325 sc->wi_ibss_port = htole16(1); 326 break; 327 case WI_INTERSIL: 328 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 329 if (sc->sc_sta_firmware_ver >= 800) { 330 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 331 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 332 } 333 /* 334 * version 0.8.3 and newer are the only ones that are known 335 * to currently work. Earlier versions can be made to work, 336 * at least according to the Linux driver. 337 */ 338 if (sc->sc_sta_firmware_ver >= 803) 339 sc->wi_flags |= WI_FLAGS_HAS_HOSTAP; 340 sc->wi_ibss_port = htole16(0); 341 break; 342 case WI_SYMBOL: 343 sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY; 344 if (sc->sc_sta_firmware_ver >= 20000) 345 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 346 /* Older Symbol firmware does not support IBSS creation. */ 347 if (sc->sc_sta_firmware_ver >= 25000) 348 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 349 sc->wi_ibss_port = htole16(4); 350 break; 351 } 352 353 /* 354 * Find out if we support WEP on this card. 355 */ 356 gen.wi_type = WI_RID_WEP_AVAIL; 357 gen.wi_len = 2; 358 wi_read_record(sc, &gen); 359 sc->wi_has_wep = gen.wi_val; 360 361 if (bootverbose) 362 device_printf(sc->dev, "wi_has_wep = %d\n", sc->wi_has_wep); 363 364 /* 365 * Find supported rates. 366 */ 367 gen.wi_type = WI_RID_DATA_RATES; 368 gen.wi_len = 2; 369 if (wi_read_record(sc, &gen)) 370 sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M | 371 WI_SUPPRATES_5M | WI_SUPPRATES_11M; 372 else 373 sc->wi_supprates = gen.wi_val; 374 375 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 376 377 wi_init(sc); 378 wi_stop(sc); 379 380 ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status); 381 #define ADD(m, c) ifmedia_add(&sc->ifmedia, (m), (c), NULL) 382 if (sc->wi_supprates & WI_SUPPRATES_1M) { 383 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 384 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 385 IFM_IEEE80211_ADHOC, 0), 0); 386 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 387 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 388 IFM_IEEE80211_IBSS, 0), 0); 389 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 390 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 391 IFM_IEEE80211_IBSSMASTER, 0), 0); 392 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 393 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 394 IFM_IEEE80211_HOSTAP, 0), 0); 395 } 396 if (sc->wi_supprates & WI_SUPPRATES_2M) { 397 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 398 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 399 IFM_IEEE80211_ADHOC, 0), 0); 400 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 401 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 402 IFM_IEEE80211_IBSS, 0), 0); 403 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 404 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 405 IFM_IEEE80211_IBSSMASTER, 0), 0); 406 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 407 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 408 IFM_IEEE80211_HOSTAP, 0), 0); 409 } 410 if (sc->wi_supprates & WI_SUPPRATES_5M) { 411 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 412 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 413 IFM_IEEE80211_ADHOC, 0), 0); 414 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 415 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 416 IFM_IEEE80211_IBSS, 0), 0); 417 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 418 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 419 IFM_IEEE80211_IBSSMASTER, 0), 0); 420 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 421 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 422 IFM_IEEE80211_HOSTAP, 0), 0); 423 } 424 if (sc->wi_supprates & WI_SUPPRATES_11M) { 425 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 426 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 427 IFM_IEEE80211_ADHOC, 0), 0); 428 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 429 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 430 IFM_IEEE80211_IBSS, 0), 0); 431 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 432 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 433 IFM_IEEE80211_IBSSMASTER, 0), 0); 434 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 435 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 436 IFM_IEEE80211_HOSTAP, 0), 0); 437 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0); 438 } 439 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0); 440 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 441 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, 442 0), 0); 443 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 444 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 445 IFM_IEEE80211_IBSSMASTER, 0), 0); 446 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 447 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 448 IFM_IEEE80211_HOSTAP, 0), 0); 449 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 450 #undef ADD 451 ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0)); 452 453 /* 454 * Call MI attach routine. 455 */ 456 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 457 callout_handle_init(&sc->wi_stat_ch); 458 WI_UNLOCK(sc, s); 459 460 return(0); 461 } 462 463 static void 464 wi_get_id(sc) 465 struct wi_softc *sc; 466 { 467 struct wi_ltv_ver ver; 468 struct wi_card_ident *id; 469 470 /* getting chip identity */ 471 memset(&ver, 0, sizeof(ver)); 472 ver.wi_type = WI_RID_CARD_ID; 473 ver.wi_len = 5; 474 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 475 device_printf(sc->dev, "using "); 476 sc->sc_firmware_type = WI_NOTYPE; 477 for (id = wi_card_ident; id->card_name != NULL; id++) { 478 if (le16toh(ver.wi_ver[0]) == id->card_id) { 479 printf("%s", id->card_name); 480 sc->sc_firmware_type = id->firm_type; 481 break; 482 } 483 } 484 if (sc->sc_firmware_type == WI_NOTYPE) { 485 if (le16toh(ver.wi_ver[0]) & 0x8000) { 486 printf("Unknown PRISM2 chip"); 487 sc->sc_firmware_type = WI_INTERSIL; 488 } else { 489 printf("Unknown Lucent chip"); 490 sc->sc_firmware_type = WI_LUCENT; 491 } 492 } 493 494 if (sc->sc_firmware_type != WI_LUCENT) { 495 /* get primary firmware version */ 496 memset(&ver, 0, sizeof(ver)); 497 ver.wi_type = WI_RID_PRI_IDENTITY; 498 ver.wi_len = 5; 499 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 500 ver.wi_ver[1] = le16toh(ver.wi_ver[1]); 501 ver.wi_ver[2] = le16toh(ver.wi_ver[2]); 502 ver.wi_ver[3] = le16toh(ver.wi_ver[3]); 503 sc->sc_pri_firmware_ver = ver.wi_ver[2] * 10000 + 504 ver.wi_ver[3] * 100 + ver.wi_ver[1]; 505 } 506 507 /* get station firmware version */ 508 memset(&ver, 0, sizeof(ver)); 509 ver.wi_type = WI_RID_STA_IDENTITY; 510 ver.wi_len = 5; 511 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 512 ver.wi_ver[1] = le16toh(ver.wi_ver[1]); 513 ver.wi_ver[2] = le16toh(ver.wi_ver[2]); 514 ver.wi_ver[3] = le16toh(ver.wi_ver[3]); 515 sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 + 516 ver.wi_ver[3] * 100 + ver.wi_ver[1]; 517 if (sc->sc_firmware_type == WI_INTERSIL && 518 (sc->sc_sta_firmware_ver == 10102 || 519 sc->sc_sta_firmware_ver == 20102)) { 520 struct wi_ltv_str sver; 521 char *p; 522 523 memset(&sver, 0, sizeof(sver)); 524 sver.wi_type = WI_RID_SYMBOL_IDENTITY; 525 sver.wi_len = 7; 526 /* value should be the format like "V2.00-11" */ 527 if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 && 528 *(p = (char *)sver.wi_str) >= 'A' && 529 p[2] == '.' && p[5] == '-' && p[8] == '\0') { 530 sc->sc_firmware_type = WI_SYMBOL; 531 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 + 532 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + 533 (p[6] - '0') * 10 + (p[7] - '0'); 534 } 535 } 536 printf("\n"); 537 device_printf(sc->dev, "%s Firmware: ", 538 sc->sc_firmware_type == WI_LUCENT ? "Lucent" : 539 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")); 540 541 /* 542 * The primary firmware is only valid on Prism based chipsets 543 * (INTERSIL or SYMBOL). 544 */ 545 if (sc->sc_firmware_type != WI_LUCENT) 546 printf("Primary %u.%02u.%02u, ", sc->sc_pri_firmware_ver / 10000, 547 (sc->sc_pri_firmware_ver % 10000) / 100, 548 sc->sc_pri_firmware_ver % 100); 549 printf("Station %u.%02u.%02u\n", 550 sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100, 551 sc->sc_sta_firmware_ver % 100); 552 return; 553 } 554 555 static void 556 wi_rxeof(sc) 557 struct wi_softc *sc; 558 { 559 struct ifnet *ifp; 560 struct ether_header *eh; 561 struct mbuf *m; 562 int id; 563 564 ifp = &sc->arpcom.ac_if; 565 566 id = CSR_READ_2(sc, WI_RX_FID); 567 568 /* 569 * if we have the procframe flag set, disregard all this and just 570 * read the data from the device. 571 */ 572 if (sc->wi_procframe || sc->wi_debug.wi_monitor) { 573 struct wi_frame *rx_frame; 574 int datlen, hdrlen; 575 576 /* first allocate mbuf for packet storage */ 577 MGETHDR(m, M_DONTWAIT, MT_DATA); 578 if (m == NULL) { 579 ifp->if_ierrors++; 580 return; 581 } 582 MCLGET(m, M_DONTWAIT); 583 if (!(m->m_flags & M_EXT)) { 584 m_freem(m); 585 ifp->if_ierrors++; 586 return; 587 } 588 589 m->m_pkthdr.rcvif = ifp; 590 591 /* now read wi_frame first so we know how much data to read */ 592 if (wi_read_data(sc, id, 0, mtod(m, caddr_t), 593 sizeof(struct wi_frame))) { 594 m_freem(m); 595 ifp->if_ierrors++; 596 return; 597 } 598 599 rx_frame = mtod(m, struct wi_frame *); 600 601 switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) { 602 case 7: 603 switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) { 604 case WI_FTYPE_DATA: 605 hdrlen = WI_DATA_HDRLEN; 606 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 607 break; 608 case WI_FTYPE_MGMT: 609 hdrlen = WI_MGMT_HDRLEN; 610 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 611 break; 612 case WI_FTYPE_CTL: 613 /* 614 * prism2 cards don't pass control packets 615 * down properly or consistently, so we'll only 616 * pass down the header. 617 */ 618 hdrlen = WI_CTL_HDRLEN; 619 datlen = 0; 620 break; 621 default: 622 device_printf(sc->dev, "received packet of " 623 "unknown type on port 7\n"); 624 m_freem(m); 625 ifp->if_ierrors++; 626 return; 627 } 628 break; 629 case 0: 630 hdrlen = WI_DATA_HDRLEN; 631 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 632 break; 633 default: 634 device_printf(sc->dev, "received packet on invalid " 635 "port (wi_status=0x%x)\n", rx_frame->wi_status); 636 m_freem(m); 637 ifp->if_ierrors++; 638 return; 639 } 640 641 if ((hdrlen + datlen + 2) > MCLBYTES) { 642 device_printf(sc->dev, "oversized packet received " 643 "(wi_dat_len=%d, wi_status=0x%x)\n", 644 datlen, rx_frame->wi_status); 645 m_freem(m); 646 ifp->if_ierrors++; 647 return; 648 } 649 650 if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen, 651 datlen + 2)) { 652 m_freem(m); 653 ifp->if_ierrors++; 654 return; 655 } 656 657 m->m_pkthdr.len = m->m_len = hdrlen + datlen; 658 659 ifp->if_ipackets++; 660 661 /* Handle BPF listeners. */ 662 if (ifp->if_bpf) 663 bpf_mtap(ifp, m); 664 665 m_freem(m); 666 } else { 667 struct wi_frame rx_frame; 668 669 /* First read in the frame header */ 670 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, 671 sizeof(rx_frame))) { 672 ifp->if_ierrors++; 673 return; 674 } 675 676 if (rx_frame.wi_status & WI_STAT_ERRSTAT) { 677 ifp->if_ierrors++; 678 return; 679 } 680 681 MGETHDR(m, M_DONTWAIT, MT_DATA); 682 if (m == NULL) { 683 ifp->if_ierrors++; 684 return; 685 } 686 MCLGET(m, M_DONTWAIT); 687 if (!(m->m_flags & M_EXT)) { 688 m_freem(m); 689 ifp->if_ierrors++; 690 return; 691 } 692 693 eh = mtod(m, struct ether_header *); 694 m->m_pkthdr.rcvif = ifp; 695 696 if (rx_frame.wi_status == WI_STAT_MGMT && 697 sc->wi_ptype == WI_PORTTYPE_AP) { 698 if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) > 699 MCLBYTES) { 700 device_printf(sc->dev, "oversized mgmt packet " 701 "received in hostap mode " 702 "(wi_dat_len=%d, wi_status=0x%x)\n", 703 rx_frame.wi_dat_len, rx_frame.wi_status); 704 m_freem(m); 705 ifp->if_ierrors++; 706 return; 707 } 708 709 /* Put the whole header in there. */ 710 bcopy(&rx_frame, mtod(m, void *), 711 sizeof(struct wi_frame)); 712 if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW, 713 mtod(m, caddr_t) + WI_802_11_OFFSET_RAW, 714 rx_frame.wi_dat_len + 2)) { 715 m_freem(m); 716 ifp->if_ierrors++; 717 return; 718 } 719 m->m_pkthdr.len = m->m_len = 720 WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len; 721 /* XXX: consider giving packet to bhp? */ 722 wihap_mgmt_input(sc, &rx_frame, m); 723 return; 724 } 725 726 if (rx_frame.wi_status == WI_STAT_1042 || 727 rx_frame.wi_status == WI_STAT_TUNNEL || 728 rx_frame.wi_status == WI_STAT_WMP_MSG) { 729 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { 730 device_printf(sc->dev, 731 "oversized packet received " 732 "(wi_dat_len=%d, wi_status=0x%x)\n", 733 rx_frame.wi_dat_len, rx_frame.wi_status); 734 m_freem(m); 735 ifp->if_ierrors++; 736 return; 737 } 738 m->m_pkthdr.len = m->m_len = 739 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 740 741 #if 0 742 bcopy((char *)&rx_frame.wi_addr1, 743 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 744 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) { 745 bcopy((char *)&rx_frame.wi_addr2, 746 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 747 } else { 748 bcopy((char *)&rx_frame.wi_addr3, 749 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 750 } 751 #else 752 bcopy((char *)&rx_frame.wi_dst_addr, 753 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 754 bcopy((char *)&rx_frame.wi_src_addr, 755 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 756 #endif 757 758 bcopy((char *)&rx_frame.wi_type, 759 (char *)&eh->ether_type, ETHER_TYPE_LEN); 760 761 if (wi_read_data(sc, id, WI_802_11_OFFSET, 762 mtod(m, caddr_t) + sizeof(struct ether_header), 763 m->m_len + 2)) { 764 m_freem(m); 765 ifp->if_ierrors++; 766 return; 767 } 768 } else { 769 if((rx_frame.wi_dat_len + 770 sizeof(struct ether_header)) > MCLBYTES) { 771 device_printf(sc->dev, 772 "oversized packet received " 773 "(wi_dat_len=%d, wi_status=0x%x)\n", 774 rx_frame.wi_dat_len, rx_frame.wi_status); 775 m_freem(m); 776 ifp->if_ierrors++; 777 return; 778 } 779 m->m_pkthdr.len = m->m_len = 780 rx_frame.wi_dat_len + sizeof(struct ether_header); 781 782 if (wi_read_data(sc, id, WI_802_3_OFFSET, 783 mtod(m, caddr_t), m->m_len + 2)) { 784 m_freem(m); 785 ifp->if_ierrors++; 786 return; 787 } 788 } 789 790 ifp->if_ipackets++; 791 792 if (sc->wi_ptype == WI_PORTTYPE_AP) { 793 /* 794 * Give host AP code first crack at data 795 * packets. If it decides to handle it (or 796 * drop it), it will return a non-zero. 797 * Otherwise, it is destined for this host. 798 */ 799 if (wihap_data_input(sc, &rx_frame, m)) 800 return; 801 } 802 /* Receive packet. */ 803 m_adj(m, sizeof(struct ether_header)); 804 #ifdef WICACHE 805 wi_cache_store(sc, eh, m, rx_frame.wi_q_info); 806 #endif 807 ether_input(ifp, eh, m); 808 } 809 } 810 811 static void 812 wi_txeof(sc, status) 813 struct wi_softc *sc; 814 int status; 815 { 816 struct ifnet *ifp; 817 818 ifp = &sc->arpcom.ac_if; 819 820 ifp->if_timer = 0; 821 ifp->if_flags &= ~IFF_OACTIVE; 822 823 if (status & WI_EV_TX_EXC) 824 ifp->if_oerrors++; 825 else 826 ifp->if_opackets++; 827 828 return; 829 } 830 831 void 832 wi_inquire(xsc) 833 void *xsc; 834 { 835 struct wi_softc *sc; 836 struct ifnet *ifp; 837 int s; 838 839 sc = xsc; 840 ifp = &sc->arpcom.ac_if; 841 842 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 843 844 /* Don't do this while we're transmitting */ 845 if (ifp->if_flags & IFF_OACTIVE) 846 return; 847 848 WI_LOCK(sc, s); 849 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0); 850 WI_UNLOCK(sc, s); 851 852 return; 853 } 854 855 void 856 wi_update_stats(sc) 857 struct wi_softc *sc; 858 { 859 struct wi_ltv_gen gen; 860 u_int16_t id; 861 struct ifnet *ifp; 862 u_int32_t *ptr; 863 int len, i; 864 u_int16_t t; 865 866 ifp = &sc->arpcom.ac_if; 867 868 id = CSR_READ_2(sc, WI_INFO_FID); 869 870 wi_read_data(sc, id, 0, (char *)&gen, 4); 871 872 /* 873 * if we just got our scan results, copy it over into the scan buffer 874 * so we can return it to anyone that asks for it. (add a little 875 * compatibility with the prism2 scanning mechanism) 876 */ 877 if (gen.wi_type == WI_INFO_SCAN_RESULTS) 878 { 879 sc->wi_scanbuf_len = gen.wi_len; 880 wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf, 881 sc->wi_scanbuf_len * 2); 882 883 return; 884 } 885 else if (gen.wi_type != WI_INFO_COUNTERS) 886 return; 887 888 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ? 889 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4; 890 ptr = (u_int32_t *)&sc->wi_stats; 891 892 for (i = 0; i < len - 1; i++) { 893 t = CSR_READ_2(sc, WI_DATA1); 894 #ifdef WI_HERMES_STATS_WAR 895 if (t > 0xF000) 896 t = ~t & 0xFFFF; 897 #endif 898 ptr[i] += t; 899 } 900 901 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 902 sc->wi_stats.wi_tx_multi_retries + 903 sc->wi_stats.wi_tx_retry_limit; 904 905 return; 906 } 907 908 static void 909 wi_intr(xsc) 910 void *xsc; 911 { 912 struct wi_softc *sc = xsc; 913 struct ifnet *ifp; 914 u_int16_t status; 915 int s; 916 917 WI_LOCK(sc, s); 918 919 ifp = &sc->arpcom.ac_if; 920 921 if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) { 922 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 923 CSR_WRITE_2(sc, WI_INT_EN, 0); 924 WI_UNLOCK(sc, s); 925 return; 926 } 927 928 /* Disable interrupts. */ 929 CSR_WRITE_2(sc, WI_INT_EN, 0); 930 931 status = CSR_READ_2(sc, WI_EVENT_STAT); 932 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS); 933 934 if (status & WI_EV_RX) { 935 wi_rxeof(sc); 936 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); 937 } 938 939 if (status & WI_EV_TX) { 940 wi_txeof(sc, status); 941 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX); 942 } 943 944 if (status & WI_EV_ALLOC) { 945 int id; 946 947 id = CSR_READ_2(sc, WI_ALLOC_FID); 948 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 949 if (id == sc->wi_tx_data_id) 950 wi_txeof(sc, status); 951 } 952 953 if (status & WI_EV_INFO) { 954 wi_update_stats(sc); 955 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); 956 } 957 958 if (status & WI_EV_TX_EXC) { 959 wi_txeof(sc, status); 960 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); 961 } 962 963 if (status & WI_EV_INFO_DROP) { 964 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP); 965 } 966 967 /* Re-enable interrupts. */ 968 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 969 970 if (ifp->if_snd.ifq_head != NULL) { 971 wi_start(ifp); 972 } 973 974 WI_UNLOCK(sc, s); 975 976 return; 977 } 978 979 static int 980 wi_cmd(sc, cmd, val0, val1, val2) 981 struct wi_softc *sc; 982 int cmd; 983 int val0; 984 int val1; 985 int val2; 986 { 987 int i, s = 0; 988 static volatile int count = 0; 989 990 if (count > 1) 991 panic("Hey partner, hold on there!"); 992 count++; 993 994 /* wait for the busy bit to clear */ 995 for (i = 500; i > 0; i--) { /* 5s */ 996 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { 997 break; 998 } 999 DELAY(10*1000); /* 10 m sec */ 1000 } 1001 if (i == 0) { 1002 device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" ); 1003 count--; 1004 return(ETIMEDOUT); 1005 } 1006 1007 CSR_WRITE_2(sc, WI_PARAM0, val0); 1008 CSR_WRITE_2(sc, WI_PARAM1, val1); 1009 CSR_WRITE_2(sc, WI_PARAM2, val2); 1010 CSR_WRITE_2(sc, WI_COMMAND, cmd); 1011 1012 for (i = 0; i < WI_TIMEOUT; i++) { 1013 /* 1014 * Wait for 'command complete' bit to be 1015 * set in the event status register. 1016 */ 1017 s = CSR_READ_2(sc, WI_EVENT_STAT); 1018 if (s & WI_EV_CMD) { 1019 /* Ack the event and read result code. */ 1020 s = CSR_READ_2(sc, WI_STATUS); 1021 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 1022 #ifdef foo 1023 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK)) 1024 return(EIO); 1025 #endif 1026 if (s & WI_STAT_CMD_RESULT) { 1027 count--; 1028 return(EIO); 1029 } 1030 break; 1031 } 1032 DELAY(WI_DELAY); 1033 } 1034 1035 count--; 1036 if (i == WI_TIMEOUT) { 1037 device_printf(sc->dev, 1038 "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s); 1039 return(ETIMEDOUT); 1040 } 1041 return(0); 1042 } 1043 1044 static void 1045 wi_reset(sc) 1046 struct wi_softc *sc; 1047 { 1048 #define WI_INIT_TRIES 3 1049 int i; 1050 int tries; 1051 1052 /* Symbol firmware cannot be initialized more than once */ 1053 if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_enabled) 1054 return; 1055 if (sc->sc_firmware_type == WI_SYMBOL) 1056 tries = 1; 1057 else 1058 tries = WI_INIT_TRIES; 1059 1060 for (i = 0; i < tries; i++) { 1061 if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0) 1062 break; 1063 DELAY(WI_DELAY * 1000); 1064 } 1065 sc->sc_enabled = 1; 1066 1067 if (i == tries) { 1068 device_printf(sc->dev, "init failed\n"); 1069 return; 1070 } 1071 1072 CSR_WRITE_2(sc, WI_INT_EN, 0); 1073 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 1074 1075 /* Calibrate timer. */ 1076 WI_SETVAL(WI_RID_TICK_TIME, 8); 1077 1078 return; 1079 } 1080 1081 /* 1082 * Read an LTV record from the NIC. 1083 */ 1084 static int 1085 wi_read_record(sc, ltv) 1086 struct wi_softc *sc; 1087 struct wi_ltv_gen *ltv; 1088 { 1089 u_int16_t *ptr; 1090 int i, len, code; 1091 struct wi_ltv_gen *oltv, p2ltv; 1092 1093 oltv = ltv; 1094 if (sc->sc_firmware_type != WI_LUCENT) { 1095 switch (ltv->wi_type) { 1096 case WI_RID_ENCRYPTION: 1097 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1098 p2ltv.wi_len = 2; 1099 ltv = &p2ltv; 1100 break; 1101 case WI_RID_TX_CRYPT_KEY: 1102 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1103 p2ltv.wi_len = 2; 1104 ltv = &p2ltv; 1105 break; 1106 case WI_RID_ROAMING_MODE: 1107 if (sc->sc_firmware_type == WI_INTERSIL) 1108 break; 1109 /* not supported */ 1110 ltv->wi_len = 1; 1111 return 0; 1112 case WI_RID_MICROWAVE_OVEN: 1113 /* not supported */ 1114 ltv->wi_len = 1; 1115 return 0; 1116 } 1117 } 1118 1119 /* Tell the NIC to enter record read mode. */ 1120 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0)) 1121 return(EIO); 1122 1123 /* Seek to the record. */ 1124 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1125 return(EIO); 1126 1127 /* 1128 * Read the length and record type and make sure they 1129 * match what we expect (this verifies that we have enough 1130 * room to hold all of the returned data). 1131 */ 1132 len = CSR_READ_2(sc, WI_DATA1); 1133 if (len > ltv->wi_len) 1134 return(ENOSPC); 1135 code = CSR_READ_2(sc, WI_DATA1); 1136 if (code != ltv->wi_type) 1137 return(EIO); 1138 1139 ltv->wi_len = len; 1140 ltv->wi_type = code; 1141 1142 /* Now read the data. */ 1143 ptr = <v->wi_val; 1144 for (i = 0; i < ltv->wi_len - 1; i++) 1145 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1146 1147 if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS 1148 && ltv->wi_val == sc->wi_ibss_port) { 1149 /* 1150 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS. 1151 * Since Lucent uses port type 1 for BSS *and* IBSS we 1152 * have to rely on wi_ptype to distinguish this for us. 1153 */ 1154 ltv->wi_val = htole16(WI_PORTTYPE_IBSS); 1155 } else if (sc->sc_firmware_type != WI_LUCENT) { 1156 switch (oltv->wi_type) { 1157 case WI_RID_TX_RATE: 1158 case WI_RID_CUR_TX_RATE: 1159 switch (ltv->wi_val) { 1160 case 1: oltv->wi_val = 1; break; 1161 case 2: oltv->wi_val = 2; break; 1162 case 3: oltv->wi_val = 6; break; 1163 case 4: oltv->wi_val = 5; break; 1164 case 7: oltv->wi_val = 7; break; 1165 case 8: oltv->wi_val = 11; break; 1166 case 15: oltv->wi_val = 3; break; 1167 default: oltv->wi_val = 0x100 + ltv->wi_val; break; 1168 } 1169 break; 1170 case WI_RID_ENCRYPTION: 1171 oltv->wi_len = 2; 1172 if (ltv->wi_val & 0x01) 1173 oltv->wi_val = 1; 1174 else 1175 oltv->wi_val = 0; 1176 break; 1177 case WI_RID_TX_CRYPT_KEY: 1178 oltv->wi_len = 2; 1179 oltv->wi_val = ltv->wi_val; 1180 break; 1181 case WI_RID_CNFAUTHMODE: 1182 oltv->wi_len = 2; 1183 if (le16toh(ltv->wi_val) & 0x01) 1184 oltv->wi_val = htole16(1); 1185 else if (le16toh(ltv->wi_val) & 0x02) 1186 oltv->wi_val = htole16(2); 1187 break; 1188 } 1189 } 1190 1191 return(0); 1192 } 1193 1194 /* 1195 * Same as read, except we inject data instead of reading it. 1196 */ 1197 static int 1198 wi_write_record(sc, ltv) 1199 struct wi_softc *sc; 1200 struct wi_ltv_gen *ltv; 1201 { 1202 u_int16_t *ptr; 1203 int i; 1204 struct wi_ltv_gen p2ltv; 1205 1206 if (ltv->wi_type == WI_RID_PORTTYPE && 1207 le16toh(ltv->wi_val) == WI_PORTTYPE_IBSS) { 1208 /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */ 1209 p2ltv.wi_type = WI_RID_PORTTYPE; 1210 p2ltv.wi_len = 2; 1211 p2ltv.wi_val = sc->wi_ibss_port; 1212 ltv = &p2ltv; 1213 } else if (sc->sc_firmware_type != WI_LUCENT) { 1214 switch (ltv->wi_type) { 1215 case WI_RID_TX_RATE: 1216 p2ltv.wi_type = WI_RID_TX_RATE; 1217 p2ltv.wi_len = 2; 1218 switch (ltv->wi_val) { 1219 case 1: p2ltv.wi_val = 1; break; 1220 case 2: p2ltv.wi_val = 2; break; 1221 case 3: p2ltv.wi_val = 15; break; 1222 case 5: p2ltv.wi_val = 4; break; 1223 case 6: p2ltv.wi_val = 3; break; 1224 case 7: p2ltv.wi_val = 7; break; 1225 case 11: p2ltv.wi_val = 8; break; 1226 default: return EINVAL; 1227 } 1228 ltv = &p2ltv; 1229 break; 1230 case WI_RID_ENCRYPTION: 1231 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1232 p2ltv.wi_len = 2; 1233 if (le16toh(ltv->wi_val)) { 1234 p2ltv.wi_val =htole16(PRIVACY_INVOKED | 1235 EXCLUDE_UNENCRYPTED); 1236 if (sc->wi_ptype == WI_PORTTYPE_AP) 1237 /* 1238 * Disable tx encryption... 1239 * it's broken. 1240 */ 1241 p2ltv.wi_val |= htole16(HOST_ENCRYPT); 1242 } else 1243 p2ltv.wi_val = 1244 htole16(HOST_ENCRYPT | HOST_DECRYPT); 1245 ltv = &p2ltv; 1246 break; 1247 case WI_RID_TX_CRYPT_KEY: 1248 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1249 p2ltv.wi_len = 2; 1250 p2ltv.wi_val = ltv->wi_val; 1251 ltv = &p2ltv; 1252 break; 1253 case WI_RID_DEFLT_CRYPT_KEYS: 1254 { 1255 int error; 1256 int keylen; 1257 struct wi_ltv_str ws; 1258 struct wi_ltv_keys *wk = 1259 (struct wi_ltv_keys *)ltv; 1260 1261 keylen = wk->wi_keys[sc->wi_tx_key].wi_keylen; 1262 1263 for (i = 0; i < 4; i++) { 1264 bzero(&ws, sizeof(ws)); 1265 ws.wi_len = (keylen > 5) ? 8 : 4; 1266 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 1267 memcpy(ws.wi_str, 1268 &wk->wi_keys[i].wi_keydat, keylen); 1269 error = wi_write_record(sc, 1270 (struct wi_ltv_gen *)&ws); 1271 if (error) 1272 return error; 1273 } 1274 return 0; 1275 } 1276 case WI_RID_CNFAUTHMODE: 1277 p2ltv.wi_type = WI_RID_CNFAUTHMODE; 1278 p2ltv.wi_len = 2; 1279 if (le16toh(ltv->wi_val) == 1) 1280 p2ltv.wi_val = htole16(0x01); 1281 else if (le16toh(ltv->wi_val) == 2) 1282 p2ltv.wi_val = htole16(0x02); 1283 ltv = &p2ltv; 1284 break; 1285 case WI_RID_ROAMING_MODE: 1286 if (sc->sc_firmware_type == WI_INTERSIL) 1287 break; 1288 /* not supported */ 1289 return 0; 1290 case WI_RID_MICROWAVE_OVEN: 1291 /* not supported */ 1292 return 0; 1293 } 1294 } else { 1295 /* LUCENT */ 1296 switch (ltv->wi_type) { 1297 case WI_RID_TX_RATE: 1298 switch (ltv->wi_val) { 1299 case 1: ltv->wi_val = 1; break; /* 1Mb/s fixed */ 1300 case 2: ltv->wi_val = 2; break; /* 2Mb/s fixed */ 1301 case 3: ltv->wi_val = 3; break; /* 11Mb/s auto */ 1302 case 5: ltv->wi_val = 4; break; /* 5.5Mb/s fixed */ 1303 case 6: ltv->wi_val = 6; break; /* 2Mb/s auto */ 1304 case 7: ltv->wi_val = 7; break; /* 5.5Mb/s auto */ 1305 case 11: ltv->wi_val = 5; break; /* 11Mb/s fixed */ 1306 default: return EINVAL; 1307 } 1308 } 1309 } 1310 1311 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1312 return(EIO); 1313 1314 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 1315 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 1316 1317 ptr = <v->wi_val; 1318 for (i = 0; i < ltv->wi_len - 1; i++) 1319 CSR_WRITE_2(sc, WI_DATA1, ptr[i]); 1320 1321 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0)) 1322 return(EIO); 1323 1324 return(0); 1325 } 1326 1327 static int 1328 wi_seek(sc, id, off, chan) 1329 struct wi_softc *sc; 1330 int id, off, chan; 1331 { 1332 int i; 1333 int selreg, offreg; 1334 int status; 1335 1336 switch (chan) { 1337 case WI_BAP0: 1338 selreg = WI_SEL0; 1339 offreg = WI_OFF0; 1340 break; 1341 case WI_BAP1: 1342 selreg = WI_SEL1; 1343 offreg = WI_OFF1; 1344 break; 1345 default: 1346 device_printf(sc->dev, "invalid data path: %x\n", chan); 1347 return(EIO); 1348 } 1349 1350 CSR_WRITE_2(sc, selreg, id); 1351 CSR_WRITE_2(sc, offreg, off); 1352 1353 for (i = 0; i < WI_TIMEOUT; i++) { 1354 status = CSR_READ_2(sc, offreg); 1355 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR))) 1356 break; 1357 DELAY(WI_DELAY); 1358 } 1359 1360 if (i == WI_TIMEOUT) { 1361 device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n", 1362 id, off, status); 1363 return(ETIMEDOUT); 1364 } 1365 1366 return(0); 1367 } 1368 1369 static int 1370 wi_read_data(sc, id, off, buf, len) 1371 struct wi_softc *sc; 1372 int id, off; 1373 caddr_t buf; 1374 int len; 1375 { 1376 int i; 1377 u_int16_t *ptr; 1378 1379 if (wi_seek(sc, id, off, WI_BAP1)) 1380 return(EIO); 1381 1382 ptr = (u_int16_t *)buf; 1383 for (i = 0; i < len / 2; i++) 1384 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1385 1386 return(0); 1387 } 1388 1389 /* 1390 * According to the comments in the HCF Light code, there is a bug in 1391 * the Hermes (or possibly in certain Hermes firmware revisions) where 1392 * the chip's internal autoincrement counter gets thrown off during 1393 * data writes: the autoincrement is missed, causing one data word to 1394 * be overwritten and subsequent words to be written to the wrong memory 1395 * locations. The end result is that we could end up transmitting bogus 1396 * frames without realizing it. The workaround for this is to write a 1397 * couple of extra guard words after the end of the transfer, then 1398 * attempt to read then back. If we fail to locate the guard words where 1399 * we expect them, we preform the transfer over again. 1400 */ 1401 static int 1402 wi_write_data(sc, id, off, buf, len) 1403 struct wi_softc *sc; 1404 int id, off; 1405 caddr_t buf; 1406 int len; 1407 { 1408 int i; 1409 u_int16_t *ptr; 1410 #ifdef WI_HERMES_AUTOINC_WAR 1411 int retries; 1412 1413 retries = 512; 1414 again: 1415 #endif 1416 1417 if (wi_seek(sc, id, off, WI_BAP0)) 1418 return(EIO); 1419 1420 ptr = (u_int16_t *)buf; 1421 for (i = 0; i < (len / 2); i++) 1422 CSR_WRITE_2(sc, WI_DATA0, ptr[i]); 1423 1424 #ifdef WI_HERMES_AUTOINC_WAR 1425 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 1426 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 1427 1428 if (wi_seek(sc, id, off + len, WI_BAP0)) 1429 return(EIO); 1430 1431 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 1432 CSR_READ_2(sc, WI_DATA0) != 0x5678) { 1433 if (--retries >= 0) 1434 goto again; 1435 device_printf(sc->dev, "wi_write_data device timeout\n"); 1436 return (EIO); 1437 } 1438 #endif 1439 1440 return(0); 1441 } 1442 1443 /* 1444 * Allocate a region of memory inside the NIC and zero 1445 * it out. 1446 */ 1447 static int 1448 wi_alloc_nicmem(sc, len, id) 1449 struct wi_softc *sc; 1450 int len; 1451 int *id; 1452 { 1453 int i; 1454 1455 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) { 1456 device_printf(sc->dev, 1457 "failed to allocate %d bytes on NIC\n", len); 1458 return(ENOMEM); 1459 } 1460 1461 for (i = 0; i < WI_TIMEOUT; i++) { 1462 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 1463 break; 1464 DELAY(WI_DELAY); 1465 } 1466 1467 if (i == WI_TIMEOUT) { 1468 device_printf(sc->dev, "time out allocating memory on card\n"); 1469 return(ETIMEDOUT); 1470 } 1471 1472 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 1473 *id = CSR_READ_2(sc, WI_ALLOC_FID); 1474 1475 if (wi_seek(sc, *id, 0, WI_BAP0)) { 1476 device_printf(sc->dev, "seek failed while allocating memory on card\n"); 1477 return(EIO); 1478 } 1479 1480 for (i = 0; i < len / 2; i++) 1481 CSR_WRITE_2(sc, WI_DATA0, 0); 1482 1483 return(0); 1484 } 1485 1486 static void 1487 wi_setmulti(sc) 1488 struct wi_softc *sc; 1489 { 1490 struct ifnet *ifp; 1491 int i = 0; 1492 struct ifmultiaddr *ifma; 1493 struct wi_ltv_mcast mcast; 1494 1495 ifp = &sc->arpcom.ac_if; 1496 1497 bzero((char *)&mcast, sizeof(mcast)); 1498 1499 mcast.wi_type = WI_RID_MCAST_LIST; 1500 mcast.wi_len = (3 * 16) + 1; 1501 1502 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 1503 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1504 return; 1505 } 1506 1507 #if __FreeBSD_version < 500000 1508 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1509 #else 1510 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1511 #endif 1512 if (ifma->ifma_addr->sa_family != AF_LINK) 1513 continue; 1514 if (i < 16) { 1515 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 1516 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN); 1517 i++; 1518 } else { 1519 bzero((char *)&mcast, sizeof(mcast)); 1520 break; 1521 } 1522 } 1523 1524 mcast.wi_len = (i * 3) + 1; 1525 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1526 1527 return; 1528 } 1529 1530 static void 1531 wi_setdef(sc, wreq) 1532 struct wi_softc *sc; 1533 struct wi_req *wreq; 1534 { 1535 struct sockaddr_dl *sdl; 1536 struct ifaddr *ifa; 1537 struct ifnet *ifp; 1538 1539 ifp = &sc->arpcom.ac_if; 1540 1541 switch(wreq->wi_type) { 1542 case WI_RID_MAC_NODE: 1543 ifa = ifaddr_byindex(ifp->if_index); 1544 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1545 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr, 1546 ETHER_ADDR_LEN); 1547 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 1548 break; 1549 case WI_RID_PORTTYPE: 1550 sc->wi_ptype = le16toh(wreq->wi_val[0]); 1551 break; 1552 case WI_RID_TX_RATE: 1553 sc->wi_tx_rate = le16toh(wreq->wi_val[0]); 1554 break; 1555 case WI_RID_MAX_DATALEN: 1556 sc->wi_max_data_len = le16toh(wreq->wi_val[0]); 1557 break; 1558 case WI_RID_RTS_THRESH: 1559 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]); 1560 break; 1561 case WI_RID_SYSTEM_SCALE: 1562 sc->wi_ap_density = le16toh(wreq->wi_val[0]); 1563 break; 1564 case WI_RID_CREATE_IBSS: 1565 sc->wi_create_ibss = le16toh(wreq->wi_val[0]); 1566 break; 1567 case WI_RID_OWN_CHNL: 1568 sc->wi_channel = le16toh(wreq->wi_val[0]); 1569 break; 1570 case WI_RID_NODENAME: 1571 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 1572 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30); 1573 break; 1574 case WI_RID_DESIRED_SSID: 1575 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 1576 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30); 1577 break; 1578 case WI_RID_OWN_SSID: 1579 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 1580 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30); 1581 break; 1582 case WI_RID_PM_ENABLED: 1583 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]); 1584 break; 1585 case WI_RID_MICROWAVE_OVEN: 1586 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]); 1587 break; 1588 case WI_RID_MAX_SLEEP: 1589 sc->wi_max_sleep = le16toh(wreq->wi_val[0]); 1590 break; 1591 case WI_RID_CNFAUTHMODE: 1592 sc->wi_authtype = le16toh(wreq->wi_val[0]); 1593 break; 1594 case WI_RID_ROAMING_MODE: 1595 sc->wi_roaming = le16toh(wreq->wi_val[0]); 1596 break; 1597 case WI_RID_ENCRYPTION: 1598 sc->wi_use_wep = le16toh(wreq->wi_val[0]); 1599 break; 1600 case WI_RID_TX_CRYPT_KEY: 1601 sc->wi_tx_key = le16toh(wreq->wi_val[0]); 1602 break; 1603 case WI_RID_DEFLT_CRYPT_KEYS: 1604 bcopy((char *)wreq, (char *)&sc->wi_keys, 1605 sizeof(struct wi_ltv_keys)); 1606 break; 1607 default: 1608 break; 1609 } 1610 1611 /* Reinitialize WaveLAN. */ 1612 wi_init(sc); 1613 1614 return; 1615 } 1616 1617 static int 1618 wi_ioctl(ifp, command, data) 1619 struct ifnet *ifp; 1620 u_long command; 1621 caddr_t data; 1622 { 1623 int error = 0; 1624 int len; 1625 u_int8_t tmpkey[14]; 1626 char tmpssid[IEEE80211_NWID_LEN]; 1627 struct wi_softc *sc; 1628 struct wi_req wreq; 1629 struct ifreq *ifr; 1630 struct ieee80211req *ireq; 1631 #if __FreeBSD_version >= 500000 1632 struct thread *td = curthread; 1633 #else 1634 struct proc *td = curproc; /* Little white lie */ 1635 #endif 1636 int s; 1637 1638 sc = ifp->if_softc; 1639 WI_LOCK(sc, s); 1640 ifr = (struct ifreq *)data; 1641 ireq = (struct ieee80211req *)data; 1642 1643 if (sc->wi_gone) { 1644 error = ENODEV; 1645 goto out; 1646 } 1647 1648 switch(command) { 1649 case SIOCSIFADDR: 1650 case SIOCGIFADDR: 1651 case SIOCSIFMTU: 1652 error = ether_ioctl(ifp, command, data); 1653 break; 1654 case SIOCSIFFLAGS: 1655 /* 1656 * Can't do promisc and hostap at the same time. If all that's 1657 * changing is the promisc flag, try to short-circuit a call to 1658 * wi_init() by just setting PROMISC in the hardware. 1659 */ 1660 if (ifp->if_flags & IFF_UP) { 1661 if (sc->wi_ptype != WI_PORTTYPE_AP && 1662 ifp->if_flags & IFF_RUNNING) { 1663 if (ifp->if_flags & IFF_PROMISC && 1664 !(sc->wi_if_flags & IFF_PROMISC)) { 1665 WI_SETVAL(WI_RID_PROMISC, 1); 1666 } else if (!(ifp->if_flags & IFF_PROMISC) && 1667 sc->wi_if_flags & IFF_PROMISC) { 1668 WI_SETVAL(WI_RID_PROMISC, 0); 1669 } else { 1670 wi_init(sc); 1671 } 1672 } else { 1673 wi_init(sc); 1674 } 1675 } else { 1676 if (ifp->if_flags & IFF_RUNNING) { 1677 wi_stop(sc); 1678 } 1679 } 1680 sc->wi_if_flags = ifp->if_flags; 1681 error = 0; 1682 break; 1683 case SIOCSIFMEDIA: 1684 case SIOCGIFMEDIA: 1685 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1686 break; 1687 case SIOCADDMULTI: 1688 case SIOCDELMULTI: 1689 wi_setmulti(sc); 1690 error = 0; 1691 break; 1692 case SIOCGWAVELAN: 1693 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1694 if (error) 1695 break; 1696 if (wreq.wi_len > WI_MAX_DATALEN) { 1697 error = EINVAL; 1698 break; 1699 } 1700 /* Don't show WEP keys to non-root users. */ 1701 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td)) 1702 break; 1703 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1704 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1705 sizeof(sc->wi_stats)); 1706 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1707 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) { 1708 bcopy((char *)&sc->wi_keys, (char *)&wreq, 1709 sizeof(struct wi_ltv_keys)); 1710 } 1711 #ifdef WICACHE 1712 else if (wreq.wi_type == WI_RID_ZERO_CACHE) { 1713 sc->wi_sigitems = sc->wi_nextitem = 0; 1714 } else if (wreq.wi_type == WI_RID_READ_CACHE) { 1715 char *pt = (char *)&wreq.wi_val; 1716 bcopy((char *)&sc->wi_sigitems, 1717 (char *)pt, sizeof(int)); 1718 pt += (sizeof (int)); 1719 wreq.wi_len = sizeof(int) / 2; 1720 bcopy((char *)&sc->wi_sigcache, (char *)pt, 1721 sizeof(struct wi_sigcache) * sc->wi_sigitems); 1722 wreq.wi_len += ((sizeof(struct wi_sigcache) * 1723 sc->wi_sigitems) / 2) + 1; 1724 } 1725 #endif 1726 else if (wreq.wi_type == WI_RID_PROCFRAME) { 1727 wreq.wi_len = 2; 1728 wreq.wi_val[0] = sc->wi_procframe; 1729 } else if (wreq.wi_type == WI_RID_PRISM2) { 1730 wreq.wi_len = 2; 1731 wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT; 1732 } else if (wreq.wi_type == WI_RID_SCAN_RES && 1733 sc->sc_firmware_type == WI_LUCENT) { 1734 memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf, 1735 sc->wi_scanbuf_len * 2); 1736 wreq.wi_len = sc->wi_scanbuf_len; 1737 } else { 1738 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1739 error = EINVAL; 1740 break; 1741 } 1742 } 1743 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1744 break; 1745 case SIOCSWAVELAN: 1746 if ((error = suser(td))) 1747 goto out; 1748 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1749 if (error) 1750 break; 1751 if (wreq.wi_len > WI_MAX_DATALEN) { 1752 error = EINVAL; 1753 break; 1754 } 1755 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1756 error = EINVAL; 1757 break; 1758 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) { 1759 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1760 wreq.wi_len); 1761 } else if (wreq.wi_type == WI_RID_PROCFRAME) { 1762 sc->wi_procframe = wreq.wi_val[0]; 1763 /* 1764 * if we're getting a scan request from a wavelan card 1765 * (non-prism2), send out a cmd_inquire to the card to scan 1766 * results for the scan will be received through the info 1767 * interrupt handler. otherwise the scan request can be 1768 * directly handled by a prism2 card's rid interface. 1769 */ 1770 } else if (wreq.wi_type == WI_RID_SCAN_REQ && 1771 sc->sc_firmware_type == WI_LUCENT) { 1772 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); 1773 } else { 1774 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1775 if (!error) 1776 wi_setdef(sc, &wreq); 1777 } 1778 break; 1779 case SIOCGPRISM2DEBUG: 1780 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1781 if (error) 1782 break; 1783 if (!(ifp->if_flags & IFF_RUNNING) || 1784 sc->sc_firmware_type == WI_LUCENT) { 1785 error = EIO; 1786 break; 1787 } 1788 error = wi_get_debug(sc, &wreq); 1789 if (error == 0) 1790 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1791 break; 1792 case SIOCSPRISM2DEBUG: 1793 if ((error = suser(td))) 1794 goto out; 1795 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1796 if (error) 1797 break; 1798 error = wi_set_debug(sc, &wreq); 1799 break; 1800 case SIOCG80211: 1801 switch(ireq->i_type) { 1802 case IEEE80211_IOC_SSID: 1803 if(ireq->i_val == -1) { 1804 bzero(tmpssid, IEEE80211_NWID_LEN); 1805 error = wi_get_cur_ssid(sc, tmpssid, &len); 1806 if (error != 0) 1807 break; 1808 error = copyout(tmpssid, ireq->i_data, 1809 IEEE80211_NWID_LEN); 1810 ireq->i_len = len; 1811 } else if (ireq->i_val == 0) { 1812 error = copyout(sc->wi_net_name, 1813 ireq->i_data, 1814 IEEE80211_NWID_LEN); 1815 ireq->i_len = IEEE80211_NWID_LEN; 1816 } else 1817 error = EINVAL; 1818 break; 1819 case IEEE80211_IOC_NUMSSIDS: 1820 ireq->i_val = 1; 1821 break; 1822 case IEEE80211_IOC_WEP: 1823 if(!sc->wi_has_wep) { 1824 ireq->i_val = IEEE80211_WEP_NOSUP; 1825 } else { 1826 if(sc->wi_use_wep) { 1827 ireq->i_val = 1828 IEEE80211_WEP_MIXED; 1829 } else { 1830 ireq->i_val = 1831 IEEE80211_WEP_OFF; 1832 } 1833 } 1834 break; 1835 case IEEE80211_IOC_WEPKEY: 1836 if(!sc->wi_has_wep || 1837 ireq->i_val < 0 || ireq->i_val > 3) { 1838 error = EINVAL; 1839 break; 1840 } 1841 len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen; 1842 if (suser(td)) 1843 bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1844 tmpkey, len); 1845 else 1846 bzero(tmpkey, len); 1847 1848 ireq->i_len = len; 1849 error = copyout(tmpkey, ireq->i_data, len); 1850 1851 break; 1852 case IEEE80211_IOC_NUMWEPKEYS: 1853 if(!sc->wi_has_wep) 1854 error = EINVAL; 1855 else 1856 ireq->i_val = 4; 1857 break; 1858 case IEEE80211_IOC_WEPTXKEY: 1859 if(!sc->wi_has_wep) 1860 error = EINVAL; 1861 else 1862 ireq->i_val = sc->wi_tx_key; 1863 break; 1864 case IEEE80211_IOC_AUTHMODE: 1865 ireq->i_val = sc->wi_authmode; 1866 break; 1867 case IEEE80211_IOC_STATIONNAME: 1868 error = copyout(sc->wi_node_name, 1869 ireq->i_data, IEEE80211_NWID_LEN); 1870 ireq->i_len = IEEE80211_NWID_LEN; 1871 break; 1872 case IEEE80211_IOC_CHANNEL: 1873 wreq.wi_type = WI_RID_CURRENT_CHAN; 1874 wreq.wi_len = WI_MAX_DATALEN; 1875 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) 1876 error = EINVAL; 1877 else { 1878 ireq->i_val = wreq.wi_val[0]; 1879 } 1880 break; 1881 case IEEE80211_IOC_POWERSAVE: 1882 if(sc->wi_pm_enabled) 1883 ireq->i_val = IEEE80211_POWERSAVE_ON; 1884 else 1885 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1886 break; 1887 case IEEE80211_IOC_POWERSAVESLEEP: 1888 ireq->i_val = sc->wi_max_sleep; 1889 break; 1890 default: 1891 error = EINVAL; 1892 } 1893 break; 1894 case SIOCS80211: 1895 if ((error = suser(td))) 1896 goto out; 1897 switch(ireq->i_type) { 1898 case IEEE80211_IOC_SSID: 1899 if (ireq->i_val != 0 || 1900 ireq->i_len > IEEE80211_NWID_LEN) { 1901 error = EINVAL; 1902 break; 1903 } 1904 /* We set both of them */ 1905 bzero(sc->wi_net_name, IEEE80211_NWID_LEN); 1906 error = copyin(ireq->i_data, 1907 sc->wi_net_name, ireq->i_len); 1908 bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN); 1909 break; 1910 case IEEE80211_IOC_WEP: 1911 /* 1912 * These cards only support one mode so 1913 * we just turn wep on what ever is 1914 * passed in if it's not OFF. 1915 */ 1916 if (ireq->i_val == IEEE80211_WEP_OFF) { 1917 sc->wi_use_wep = 0; 1918 } else { 1919 sc->wi_use_wep = 1; 1920 } 1921 break; 1922 case IEEE80211_IOC_WEPKEY: 1923 if (ireq->i_val < 0 || ireq->i_val > 3 || 1924 ireq->i_len > 13) { 1925 error = EINVAL; 1926 break; 1927 } 1928 bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13); 1929 error = copyin(ireq->i_data, 1930 sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1931 ireq->i_len); 1932 if(error) 1933 break; 1934 sc->wi_keys.wi_keys[ireq->i_val].wi_keylen = 1935 ireq->i_len; 1936 break; 1937 case IEEE80211_IOC_WEPTXKEY: 1938 if (ireq->i_val < 0 || ireq->i_val > 3) { 1939 error = EINVAL; 1940 break; 1941 } 1942 sc->wi_tx_key = ireq->i_val; 1943 break; 1944 case IEEE80211_IOC_AUTHMODE: 1945 sc->wi_authmode = ireq->i_val; 1946 break; 1947 case IEEE80211_IOC_STATIONNAME: 1948 if (ireq->i_len > 32) { 1949 error = EINVAL; 1950 break; 1951 } 1952 bzero(sc->wi_node_name, 32); 1953 error = copyin(ireq->i_data, 1954 sc->wi_node_name, ireq->i_len); 1955 break; 1956 case IEEE80211_IOC_CHANNEL: 1957 /* 1958 * The actual range is 1-14, but if you 1959 * set it to 0 you get the default. So 1960 * we let that work too. 1961 */ 1962 if (ireq->i_val < 0 || ireq->i_val > 14) { 1963 error = EINVAL; 1964 break; 1965 } 1966 sc->wi_channel = ireq->i_val; 1967 break; 1968 case IEEE80211_IOC_POWERSAVE: 1969 switch (ireq->i_val) { 1970 case IEEE80211_POWERSAVE_OFF: 1971 sc->wi_pm_enabled = 0; 1972 break; 1973 case IEEE80211_POWERSAVE_ON: 1974 sc->wi_pm_enabled = 1; 1975 break; 1976 default: 1977 error = EINVAL; 1978 break; 1979 } 1980 break; 1981 case IEEE80211_IOC_POWERSAVESLEEP: 1982 if (ireq->i_val < 0) { 1983 error = EINVAL; 1984 break; 1985 } 1986 sc->wi_max_sleep = ireq->i_val; 1987 break; 1988 default: 1989 error = EINVAL; 1990 break; 1991 } 1992 1993 /* Reinitialize WaveLAN. */ 1994 wi_init(sc); 1995 1996 break; 1997 case SIOCHOSTAP_ADD: 1998 case SIOCHOSTAP_DEL: 1999 case SIOCHOSTAP_GET: 2000 case SIOCHOSTAP_GETALL: 2001 case SIOCHOSTAP_GFLAGS: 2002 case SIOCHOSTAP_SFLAGS: 2003 /* Send all Host AP specific ioctl's to Host AP code. */ 2004 error = wihap_ioctl(sc, command, data); 2005 break; 2006 default: 2007 error = EINVAL; 2008 break; 2009 } 2010 out: 2011 WI_UNLOCK(sc, s); 2012 2013 return(error); 2014 } 2015 2016 static void 2017 wi_init(xsc) 2018 void *xsc; 2019 { 2020 struct wi_softc *sc = xsc; 2021 struct ifnet *ifp = &sc->arpcom.ac_if; 2022 struct wi_ltv_macaddr mac; 2023 int id = 0; 2024 int s; 2025 2026 WI_LOCK(sc, s); 2027 2028 if (sc->wi_gone) { 2029 WI_UNLOCK(sc, s); 2030 return; 2031 } 2032 2033 if (ifp->if_flags & IFF_RUNNING) 2034 wi_stop(sc); 2035 2036 wi_reset(sc); 2037 2038 /* Program max data length. */ 2039 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 2040 2041 /* Set the port type. */ 2042 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 2043 2044 /* Enable/disable IBSS creation. */ 2045 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 2046 2047 /* Program the RTS/CTS threshold. */ 2048 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 2049 2050 /* Program the TX rate */ 2051 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 2052 2053 /* Access point density */ 2054 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 2055 2056 /* Power Management Enabled */ 2057 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 2058 2059 /* Power Managment Max Sleep */ 2060 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 2061 2062 /* Roaming type */ 2063 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming); 2064 2065 /* Specify the IBSS name */ 2066 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name); 2067 2068 /* Specify the network name */ 2069 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name); 2070 2071 /* Specify the frequency to use */ 2072 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 2073 2074 /* Program the nodename. */ 2075 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name); 2076 2077 /* Specify the authentication mode. */ 2078 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authmode); 2079 2080 /* Set our MAC address. */ 2081 mac.wi_len = 4; 2082 mac.wi_type = WI_RID_MAC_NODE; 2083 bcopy((char *)&sc->arpcom.ac_enaddr, 2084 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN); 2085 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 2086 2087 /* 2088 * Initialize promisc mode. 2089 * Being in the Host-AP mode causes 2090 * great deal of pain if promisc mode is set. 2091 * Therefore we avoid confusing the firmware 2092 * and always reset promisc mode in Host-AP regime, 2093 * it shows us all the packets anyway. 2094 */ 2095 if (sc->wi_ptype != WI_PORTTYPE_AP && ifp->if_flags & IFF_PROMISC) 2096 WI_SETVAL(WI_RID_PROMISC, 1); 2097 else 2098 WI_SETVAL(WI_RID_PROMISC, 0); 2099 2100 /* Configure WEP. */ 2101 if (sc->wi_has_wep) { 2102 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 2103 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 2104 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 2105 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 2106 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 2107 if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) { 2108 /* 2109 * ONLY HWB3163 EVAL-CARD Firmware version 2110 * less than 0.8 variant2 2111 * 2112 * If promiscuous mode disable, Prism2 chip 2113 * does not work with WEP. 2114 * It is under investigation for details. 2115 * (ichiro@netbsd.org) 2116 * 2117 * And make sure that we don't need to do it 2118 * in hostap mode, since it interferes with 2119 * the above hostap workaround. 2120 */ 2121 if (sc->wi_ptype != WI_PORTTYPE_AP && 2122 sc->sc_firmware_type == WI_INTERSIL && 2123 sc->sc_sta_firmware_ver < 802 ) { 2124 /* firm ver < 0.8 variant 2 */ 2125 WI_SETVAL(WI_RID_PROMISC, 1); 2126 } 2127 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authtype); 2128 } 2129 } 2130 2131 /* Set multicast filter. */ 2132 wi_setmulti(sc); 2133 2134 /* Enable desired port */ 2135 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0); 2136 2137 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 2138 device_printf(sc->dev, "tx buffer allocation failed\n"); 2139 sc->wi_tx_data_id = id; 2140 2141 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 2142 device_printf(sc->dev, "mgmt. buffer allocation failed\n"); 2143 sc->wi_tx_mgmt_id = id; 2144 2145 /* enable interrupts */ 2146 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 2147 2148 wihap_init(sc); 2149 2150 ifp->if_flags |= IFF_RUNNING; 2151 ifp->if_flags &= ~IFF_OACTIVE; 2152 2153 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 2154 WI_UNLOCK(sc, s); 2155 2156 return; 2157 } 2158 2159 #define RC4STATE 256 2160 #define RC4KEYLEN 16 2161 #define RC4SWAP(x,y) \ 2162 do { u_int8_t t = state[x]; state[x] = state[y]; state[y] = t; } while(0) 2163 2164 static void 2165 wi_do_hostencrypt(struct wi_softc *sc, caddr_t buf, int len) 2166 { 2167 u_int32_t i, crc, klen; 2168 u_int8_t state[RC4STATE], key[RC4KEYLEN]; 2169 u_int8_t x, y, *dat; 2170 2171 if (!sc->wi_icv_flag) { 2172 sc->wi_icv = arc4random(); 2173 sc->wi_icv_flag++; 2174 } else 2175 sc->wi_icv++; 2176 /* 2177 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir: 2178 * (B, 255, N) with 3 <= B < 8 2179 */ 2180 if (sc->wi_icv >= 0x03ff00 && 2181 (sc->wi_icv & 0xf8ff00) == 0x00ff00) 2182 sc->wi_icv += 0x000100; 2183 2184 /* prepend 24bit IV to tx key, byte order does not matter */ 2185 key[0] = sc->wi_icv >> 16; 2186 key[1] = sc->wi_icv >> 8; 2187 key[2] = sc->wi_icv; 2188 2189 klen = sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keylen + 2190 IEEE80211_WEP_IVLEN; 2191 klen = (klen >= RC4KEYLEN) ? RC4KEYLEN : RC4KEYLEN/2; 2192 bcopy((char *)&sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keydat, 2193 (char *)key + IEEE80211_WEP_IVLEN, klen - IEEE80211_WEP_IVLEN); 2194 2195 /* rc4 keysetup */ 2196 x = y = 0; 2197 for (i = 0; i < RC4STATE; i++) 2198 state[i] = i; 2199 for (i = 0; i < RC4STATE; i++) { 2200 y = (key[x] + state[i] + y) % RC4STATE; 2201 RC4SWAP(i, y); 2202 x = (x + 1) % klen; 2203 } 2204 2205 /* output: IV, tx keyid, rc4(data), rc4(crc32(data)) */ 2206 dat = buf; 2207 dat[0] = key[0]; 2208 dat[1] = key[1]; 2209 dat[2] = key[2]; 2210 dat[3] = sc->wi_tx_key << 6; /* pad and keyid */ 2211 dat += 4; 2212 2213 /* compute rc4 over data, crc32 over data */ 2214 crc = ~0; 2215 x = y = 0; 2216 for (i = 0; i < len; i++) { 2217 x = (x + 1) % RC4STATE; 2218 y = (state[x] + y) % RC4STATE; 2219 RC4SWAP(x, y); 2220 crc = crc32_tab[(crc ^ dat[i]) & 0xff] ^ (crc >> 8); 2221 dat[i] ^= state[(state[x] + state[y]) % RC4STATE]; 2222 } 2223 crc = ~crc; 2224 dat += len; 2225 2226 /* append little-endian crc32 and encrypt */ 2227 dat[0] = crc; 2228 dat[1] = crc >> 8; 2229 dat[2] = crc >> 16; 2230 dat[3] = crc >> 24; 2231 for (i = 0; i < IEEE80211_WEP_CRCLEN; i++) { 2232 x = (x + 1) % RC4STATE; 2233 y = (state[x] + y) % RC4STATE; 2234 RC4SWAP(x, y); 2235 dat[i] ^= state[(state[x] + state[y]) % RC4STATE]; 2236 } 2237 } 2238 2239 static void 2240 wi_start(ifp) 2241 struct ifnet *ifp; 2242 { 2243 struct wi_softc *sc; 2244 struct mbuf *m0; 2245 struct wi_frame tx_frame; 2246 struct ether_header *eh; 2247 int id; 2248 int s; 2249 2250 sc = ifp->if_softc; 2251 WI_LOCK(sc, s); 2252 2253 if (sc->wi_gone) { 2254 WI_UNLOCK(sc, s); 2255 return; 2256 } 2257 2258 if (ifp->if_flags & IFF_OACTIVE) { 2259 WI_UNLOCK(sc, s); 2260 return; 2261 } 2262 2263 nextpkt: 2264 IF_DEQUEUE(&ifp->if_snd, m0); 2265 if (m0 == NULL) { 2266 WI_UNLOCK(sc, s); 2267 return; 2268 } 2269 2270 bzero((char *)&tx_frame, sizeof(tx_frame)); 2271 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA); 2272 id = sc->wi_tx_data_id; 2273 eh = mtod(m0, struct ether_header *); 2274 2275 if (sc->wi_ptype == WI_PORTTYPE_AP) { 2276 if (!wihap_check_tx(&sc->wi_hostap_info, 2277 eh->ether_dhost, &tx_frame.wi_tx_rate)) { 2278 if (ifp->if_flags & IFF_DEBUG) 2279 printf("wi_start: dropping unassoc " 2280 "dst %6D\n", eh->ether_dhost, ":"); 2281 m_freem(m0); 2282 goto nextpkt; 2283 } 2284 } 2285 /* 2286 * Use RFC1042 encoding for IP and ARP datagrams, 2287 * 802.3 for anything else. 2288 */ 2289 if (ntohs(eh->ether_type) > ETHER_MAX_LEN) { 2290 bcopy((char *)&eh->ether_dhost, 2291 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN); 2292 if (sc->wi_ptype == WI_PORTTYPE_AP) { 2293 tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; /* XXX */ 2294 tx_frame.wi_frame_ctl |= WI_FCTL_FROMDS; 2295 if (sc->wi_use_wep) 2296 tx_frame.wi_frame_ctl |= WI_FCTL_WEP; 2297 bcopy((char *)&sc->arpcom.ac_enaddr, 2298 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 2299 bcopy((char *)&eh->ether_shost, 2300 (char *)&tx_frame.wi_addr3, ETHER_ADDR_LEN); 2301 } 2302 else 2303 bcopy((char *)&eh->ether_shost, 2304 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 2305 bcopy((char *)&eh->ether_dhost, 2306 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN); 2307 bcopy((char *)&eh->ether_shost, 2308 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN); 2309 2310 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN; 2311 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 2312 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 2313 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 2314 tx_frame.wi_type = eh->ether_type; 2315 2316 if (sc->wi_ptype == WI_PORTTYPE_AP && sc->wi_use_wep) { 2317 /* Do host encryption. */ 2318 bcopy(&tx_frame.wi_dat[0], &sc->wi_txbuf[4], 8); 2319 m_copydata(m0, sizeof(struct ether_header), 2320 m0->m_pkthdr.len - sizeof(struct ether_header), 2321 (caddr_t)&sc->wi_txbuf[12]); 2322 wi_do_hostencrypt(sc, &sc->wi_txbuf[0], 2323 tx_frame.wi_dat_len); 2324 tx_frame.wi_dat_len += IEEE80211_WEP_IVLEN + 2325 IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; 2326 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2327 sizeof(struct wi_frame)); 2328 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, 2329 (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len - 2330 sizeof(struct ether_header)) + 18); 2331 } else { 2332 m_copydata(m0, sizeof(struct ether_header), 2333 m0->m_pkthdr.len - sizeof(struct ether_header), 2334 (caddr_t)&sc->wi_txbuf); 2335 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2336 sizeof(struct wi_frame)); 2337 wi_write_data(sc, id, WI_802_11_OFFSET, 2338 (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len - 2339 sizeof(struct ether_header)) + 2); 2340 } 2341 } else { 2342 tx_frame.wi_dat_len = m0->m_pkthdr.len; 2343 2344 if (sc->wi_ptype == WI_PORTTYPE_AP && sc->wi_use_wep) { 2345 /* Do host encryption. */ 2346 printf( "XXX: host encrypt not implemented for 802.3\n" ); 2347 } else { 2348 eh->ether_type = htons(m0->m_pkthdr.len - 2349 WI_SNAPHDR_LEN); 2350 m_copydata(m0, 0, m0->m_pkthdr.len, 2351 (caddr_t)&sc->wi_txbuf); 2352 2353 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2354 sizeof(struct wi_frame)); 2355 wi_write_data(sc, id, WI_802_3_OFFSET, 2356 (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2); 2357 } 2358 } 2359 2360 /* 2361 * If there's a BPF listner, bounce a copy of 2362 * this frame to him. Also, don't send this to the bpf sniffer 2363 * if we're in procframe or monitor sniffing mode. 2364 */ 2365 if (!(sc->wi_procframe || sc->wi_debug.wi_monitor) && ifp->if_bpf) 2366 bpf_mtap(ifp, m0); 2367 2368 m_freem(m0); 2369 2370 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) 2371 device_printf(sc->dev, "xmit failed\n"); 2372 2373 ifp->if_flags |= IFF_OACTIVE; 2374 2375 /* 2376 * Set a timeout in case the chip goes out to lunch. 2377 */ 2378 ifp->if_timer = 5; 2379 2380 WI_UNLOCK(sc, s); 2381 return; 2382 } 2383 2384 int 2385 wi_mgmt_xmit(sc, data, len) 2386 struct wi_softc *sc; 2387 caddr_t data; 2388 int len; 2389 { 2390 struct wi_frame tx_frame; 2391 int id; 2392 struct wi_80211_hdr *hdr; 2393 caddr_t dptr; 2394 2395 if (sc->wi_gone) 2396 return(ENODEV); 2397 2398 hdr = (struct wi_80211_hdr *)data; 2399 dptr = data + sizeof(struct wi_80211_hdr); 2400 2401 bzero((char *)&tx_frame, sizeof(tx_frame)); 2402 id = sc->wi_tx_mgmt_id; 2403 2404 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl, 2405 sizeof(struct wi_80211_hdr)); 2406 2407 tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; 2408 tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr); 2409 tx_frame.wi_len = htons(tx_frame.wi_dat_len); 2410 2411 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 2412 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 2413 len - sizeof(struct wi_80211_hdr) + 2); 2414 2415 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) { 2416 device_printf(sc->dev, "xmit failed\n"); 2417 return(EIO); 2418 } 2419 2420 return(0); 2421 } 2422 2423 static void 2424 wi_stop(sc) 2425 struct wi_softc *sc; 2426 { 2427 struct ifnet *ifp; 2428 int s; 2429 2430 WI_LOCK(sc, s); 2431 2432 if (sc->wi_gone) { 2433 WI_UNLOCK(sc, s); 2434 return; 2435 } 2436 2437 wihap_shutdown(sc); 2438 2439 ifp = &sc->arpcom.ac_if; 2440 2441 /* 2442 * If the card is gone and the memory port isn't mapped, we will 2443 * (hopefully) get 0xffff back from the status read, which is not 2444 * a valid status value. 2445 */ 2446 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) { 2447 CSR_WRITE_2(sc, WI_INT_EN, 0); 2448 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0); 2449 } 2450 2451 untimeout(wi_inquire, sc, sc->wi_stat_ch); 2452 2453 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 2454 2455 WI_UNLOCK(sc, s); 2456 return; 2457 } 2458 2459 static void 2460 wi_watchdog(ifp) 2461 struct ifnet *ifp; 2462 { 2463 struct wi_softc *sc; 2464 2465 sc = ifp->if_softc; 2466 2467 device_printf(sc->dev, "watchdog timeout\n"); 2468 2469 wi_init(sc); 2470 2471 ifp->if_oerrors++; 2472 2473 return; 2474 } 2475 2476 int 2477 wi_alloc(dev, rid) 2478 device_t dev; 2479 int rid; 2480 { 2481 struct wi_softc *sc = device_get_softc(dev); 2482 2483 if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { 2484 sc->iobase_rid = rid; 2485 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, 2486 &sc->iobase_rid, 0, ~0, (1 << 6), 2487 rman_make_alignment_flags(1 << 6) | RF_ACTIVE); 2488 if (!sc->iobase) { 2489 device_printf(dev, "No I/O space?!\n"); 2490 return (ENXIO); 2491 } 2492 2493 sc->wi_io_addr = rman_get_start(sc->iobase); 2494 sc->wi_btag = rman_get_bustag(sc->iobase); 2495 sc->wi_bhandle = rman_get_bushandle(sc->iobase); 2496 } else { 2497 sc->mem_rid = rid; 2498 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, 2499 &sc->mem_rid, 0, ~0, 1, RF_ACTIVE); 2500 2501 if (!sc->mem) { 2502 device_printf(dev, "No Mem space on prism2.5?\n"); 2503 return (ENXIO); 2504 } 2505 2506 sc->wi_btag = rman_get_bustag(sc->mem); 2507 sc->wi_bhandle = rman_get_bushandle(sc->mem); 2508 } 2509 2510 2511 sc->irq_rid = 0; 2512 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 2513 0, ~0, 1, RF_ACTIVE | 2514 ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE)); 2515 2516 if (!sc->irq) { 2517 wi_free(dev); 2518 device_printf(dev, "No irq?!\n"); 2519 return (ENXIO); 2520 } 2521 2522 sc->dev = dev; 2523 sc->wi_unit = device_get_unit(dev); 2524 2525 return (0); 2526 } 2527 2528 void 2529 wi_free(dev) 2530 device_t dev; 2531 { 2532 struct wi_softc *sc = device_get_softc(dev); 2533 2534 if (sc->iobase != NULL) { 2535 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase); 2536 sc->iobase = NULL; 2537 } 2538 if (sc->irq != NULL) { 2539 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 2540 sc->irq = NULL; 2541 } 2542 if (sc->mem != NULL) { 2543 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 2544 sc->mem = NULL; 2545 } 2546 2547 return; 2548 } 2549 2550 void 2551 wi_shutdown(dev) 2552 device_t dev; 2553 { 2554 struct wi_softc *sc; 2555 2556 sc = device_get_softc(dev); 2557 wi_stop(sc); 2558 2559 return; 2560 } 2561 2562 #ifdef WICACHE 2563 /* wavelan signal strength cache code. 2564 * store signal/noise/quality on per MAC src basis in 2565 * a small fixed cache. The cache wraps if > MAX slots 2566 * used. The cache may be zeroed out to start over. 2567 * Two simple filters exist to reduce computation: 2568 * 1. ip only (literally 0x800) which may be used 2569 * to ignore some packets. It defaults to ip only. 2570 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2571 * 2. multicast/broadcast only. This may be used to 2572 * ignore unicast packets and only cache signal strength 2573 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2574 * beacons and not unicast traffic. 2575 * 2576 * The cache stores (MAC src(index), IP src (major clue), signal, 2577 * quality, noise) 2578 * 2579 * No apologies for storing IP src here. It's easy and saves much 2580 * trouble elsewhere. The cache is assumed to be INET dependent, 2581 * although it need not be. 2582 */ 2583 2584 #ifdef documentation 2585 2586 int wi_sigitems; /* number of cached entries */ 2587 struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */ 2588 int wi_nextitem; /* index/# of entries */ 2589 2590 2591 #endif 2592 2593 /* control variables for cache filtering. Basic idea is 2594 * to reduce cost (e.g., to only Mobile-IP agent beacons 2595 * which are broadcast or multicast). Still you might 2596 * want to measure signal strength with unicast ping packets 2597 * on a pt. to pt. ant. setup. 2598 */ 2599 /* set true if you want to limit cache items to broadcast/mcast 2600 * only packets (not unicast). Useful for mobile-ip beacons which 2601 * are broadcast/multicast at network layer. Default is all packets 2602 * so ping/unicast will work say with pt. to pt. antennae setup. 2603 */ 2604 static int wi_cache_mcastonly = 0; 2605 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 2606 &wi_cache_mcastonly, 0, ""); 2607 2608 /* set true if you want to limit cache items to IP packets only 2609 */ 2610 static int wi_cache_iponly = 1; 2611 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 2612 &wi_cache_iponly, 0, ""); 2613 2614 /* 2615 * Original comments: 2616 * ----------------- 2617 * wi_cache_store, per rx packet store signal 2618 * strength in MAC (src) indexed cache. 2619 * 2620 * follows linux driver in how signal strength is computed. 2621 * In ad hoc mode, we use the rx_quality field. 2622 * signal and noise are trimmed to fit in the range from 47..138. 2623 * rx_quality field MSB is signal strength. 2624 * rx_quality field LSB is noise. 2625 * "quality" is (signal - noise) as is log value. 2626 * note: quality CAN be negative. 2627 * 2628 * In BSS mode, we use the RID for communication quality. 2629 * TBD: BSS mode is currently untested. 2630 * 2631 * Bill's comments: 2632 * --------------- 2633 * Actually, we use the rx_quality field all the time for both "ad-hoc" 2634 * and BSS modes. Why? Because reading an RID is really, really expensive: 2635 * there's a bunch of PIO operations that have to be done to read a record 2636 * from the NIC, and reading the comms quality RID each time a packet is 2637 * received can really hurt performance. We don't have to do this anyway: 2638 * the comms quality field only reflects the values in the rx_quality field 2639 * anyway. The comms quality RID is only meaningful in infrastructure mode, 2640 * but the values it contains are updated based on the rx_quality from 2641 * frames received from the access point. 2642 * 2643 * Also, according to Lucent, the signal strength and noise level values 2644 * can be converted to dBms by subtracting 149, so I've modified the code 2645 * to do that instead of the scaling it did originally. 2646 */ 2647 static void 2648 wi_cache_store(struct wi_softc *sc, struct ether_header *eh, 2649 struct mbuf *m, unsigned short rx_quality) 2650 { 2651 struct ip *ip = 0; 2652 int i; 2653 static int cache_slot = 0; /* use this cache entry */ 2654 static int wrapindex = 0; /* next "free" cache entry */ 2655 int sig, noise; 2656 int sawip=0; 2657 2658 /* 2659 * filters: 2660 * 1. ip only 2661 * 2. configurable filter to throw out unicast packets, 2662 * keep multicast only. 2663 */ 2664 2665 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 2666 sawip = 1; 2667 } 2668 2669 /* 2670 * filter for ip packets only 2671 */ 2672 if (wi_cache_iponly && !sawip) { 2673 return; 2674 } 2675 2676 /* 2677 * filter for broadcast/multicast only 2678 */ 2679 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2680 return; 2681 } 2682 2683 #ifdef SIGDEBUG 2684 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit, 2685 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2686 #endif 2687 2688 /* 2689 * find the ip header. we want to store the ip_src 2690 * address. 2691 */ 2692 if (sawip) 2693 ip = mtod(m, struct ip *); 2694 2695 /* 2696 * do a linear search for a matching MAC address 2697 * in the cache table 2698 * . MAC address is 6 bytes, 2699 * . var w_nextitem holds total number of entries already cached 2700 */ 2701 for(i = 0; i < sc->wi_nextitem; i++) { 2702 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) { 2703 /* 2704 * Match!, 2705 * so we already have this entry, 2706 * update the data 2707 */ 2708 break; 2709 } 2710 } 2711 2712 /* 2713 * did we find a matching mac address? 2714 * if yes, then overwrite a previously existing cache entry 2715 */ 2716 if (i < sc->wi_nextitem ) { 2717 cache_slot = i; 2718 } 2719 /* 2720 * else, have a new address entry,so 2721 * add this new entry, 2722 * if table full, then we need to replace LRU entry 2723 */ 2724 else { 2725 2726 /* 2727 * check for space in cache table 2728 * note: wi_nextitem also holds number of entries 2729 * added in the cache table 2730 */ 2731 if ( sc->wi_nextitem < MAXWICACHE ) { 2732 cache_slot = sc->wi_nextitem; 2733 sc->wi_nextitem++; 2734 sc->wi_sigitems = sc->wi_nextitem; 2735 } 2736 /* no space found, so simply wrap with wrap index 2737 * and "zap" the next entry 2738 */ 2739 else { 2740 if (wrapindex == MAXWICACHE) { 2741 wrapindex = 0; 2742 } 2743 cache_slot = wrapindex++; 2744 } 2745 } 2746 2747 /* 2748 * invariant: cache_slot now points at some slot 2749 * in cache. 2750 */ 2751 if (cache_slot < 0 || cache_slot >= MAXWICACHE) { 2752 log(LOG_ERR, "wi_cache_store, bad index: %d of " 2753 "[0..%d], gross cache error\n", 2754 cache_slot, MAXWICACHE); 2755 return; 2756 } 2757 2758 /* 2759 * store items in cache 2760 * .ip source address 2761 * .mac src 2762 * .signal, etc. 2763 */ 2764 if (sawip) 2765 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2766 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6); 2767 2768 sig = (rx_quality >> 8) & 0xFF; 2769 noise = rx_quality & 0xFF; 2770 sc->wi_sigcache[cache_slot].signal = sig - 149; 2771 sc->wi_sigcache[cache_slot].noise = noise - 149; 2772 sc->wi_sigcache[cache_slot].quality = sig - noise; 2773 2774 return; 2775 } 2776 #endif 2777 2778 static int 2779 wi_get_cur_ssid(sc, ssid, len) 2780 struct wi_softc *sc; 2781 char *ssid; 2782 int *len; 2783 { 2784 int error = 0; 2785 struct wi_req wreq; 2786 2787 wreq.wi_len = WI_MAX_DATALEN; 2788 switch (sc->wi_ptype) { 2789 case WI_PORTTYPE_AP: 2790 *len = IEEE80211_NWID_LEN; 2791 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN); 2792 break; 2793 case WI_PORTTYPE_ADHOC: 2794 wreq.wi_type = WI_RID_CURRENT_SSID; 2795 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2796 if (error != 0) 2797 break; 2798 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2799 error = EINVAL; 2800 break; 2801 } 2802 *len = wreq.wi_val[0]; 2803 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2804 break; 2805 case WI_PORTTYPE_BSS: 2806 wreq.wi_type = WI_RID_COMMQUAL; 2807 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2808 if (error != 0) 2809 break; 2810 if (wreq.wi_val[0] != 0) /* associated */ { 2811 wreq.wi_type = WI_RID_CURRENT_SSID; 2812 wreq.wi_len = WI_MAX_DATALEN; 2813 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2814 if (error != 0) 2815 break; 2816 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2817 error = EINVAL; 2818 break; 2819 } 2820 *len = wreq.wi_val[0]; 2821 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2822 } else { 2823 *len = IEEE80211_NWID_LEN; 2824 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN); 2825 } 2826 break; 2827 default: 2828 error = EINVAL; 2829 break; 2830 } 2831 2832 return error; 2833 } 2834 2835 static int 2836 wi_media_change(ifp) 2837 struct ifnet *ifp; 2838 { 2839 struct wi_softc *sc = ifp->if_softc; 2840 int otype = sc->wi_ptype; 2841 int orate = sc->wi_tx_rate; 2842 int ocreate_ibss = sc->wi_create_ibss; 2843 2844 if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) && 2845 sc->sc_firmware_type != WI_INTERSIL) 2846 return (EINVAL); 2847 2848 sc->wi_create_ibss = 0; 2849 2850 switch (sc->ifmedia.ifm_cur->ifm_media & IFM_OMASK) { 2851 case 0: 2852 sc->wi_ptype = WI_PORTTYPE_BSS; 2853 break; 2854 case IFM_IEEE80211_ADHOC: 2855 sc->wi_ptype = WI_PORTTYPE_ADHOC; 2856 break; 2857 case IFM_IEEE80211_HOSTAP: 2858 sc->wi_ptype = WI_PORTTYPE_AP; 2859 break; 2860 case IFM_IEEE80211_IBSSMASTER: 2861 case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS: 2862 if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) 2863 return (EINVAL); 2864 sc->wi_create_ibss = 1; 2865 /* FALLTHROUGH */ 2866 case IFM_IEEE80211_IBSS: 2867 sc->wi_ptype = WI_PORTTYPE_IBSS; 2868 break; 2869 default: 2870 /* Invalid combination. */ 2871 return (EINVAL); 2872 } 2873 2874 switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) { 2875 case IFM_IEEE80211_DS1: 2876 sc->wi_tx_rate = 1; 2877 break; 2878 case IFM_IEEE80211_DS2: 2879 sc->wi_tx_rate = 2; 2880 break; 2881 case IFM_IEEE80211_DS5: 2882 sc->wi_tx_rate = 5; 2883 break; 2884 case IFM_IEEE80211_DS11: 2885 sc->wi_tx_rate = 11; 2886 break; 2887 case IFM_AUTO: 2888 sc->wi_tx_rate = 3; 2889 break; 2890 } 2891 2892 if (ocreate_ibss != sc->wi_create_ibss || otype != sc->wi_ptype || 2893 orate != sc->wi_tx_rate) 2894 wi_init(sc); 2895 2896 return(0); 2897 } 2898 2899 static void 2900 wi_media_status(ifp, imr) 2901 struct ifnet *ifp; 2902 struct ifmediareq *imr; 2903 { 2904 struct wi_req wreq; 2905 struct wi_softc *sc = ifp->if_softc; 2906 2907 if (sc->wi_tx_rate == 3) { 2908 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2909 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) 2910 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2911 else if (sc->wi_ptype == WI_PORTTYPE_AP) 2912 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 2913 else if (sc->wi_ptype == WI_PORTTYPE_IBSS) { 2914 if (sc->wi_create_ibss) 2915 imr->ifm_active |= IFM_IEEE80211_IBSSMASTER; 2916 else 2917 imr->ifm_active |= IFM_IEEE80211_IBSS; 2918 } 2919 wreq.wi_type = WI_RID_CUR_TX_RATE; 2920 wreq.wi_len = WI_MAX_DATALEN; 2921 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) { 2922 switch(wreq.wi_val[0]) { 2923 case 1: 2924 imr->ifm_active |= IFM_IEEE80211_DS1; 2925 break; 2926 case 2: 2927 imr->ifm_active |= IFM_IEEE80211_DS2; 2928 break; 2929 case 6: 2930 imr->ifm_active |= IFM_IEEE80211_DS5; 2931 break; 2932 case 11: 2933 imr->ifm_active |= IFM_IEEE80211_DS11; 2934 break; 2935 } 2936 } 2937 } else { 2938 imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; 2939 } 2940 2941 imr->ifm_status = IFM_AVALID; 2942 if (sc->wi_ptype == WI_PORTTYPE_ADHOC || 2943 sc->wi_ptype == WI_PORTTYPE_IBSS) 2944 /* 2945 * XXX: It would be nice if we could give some actually 2946 * useful status like whether we joined another IBSS or 2947 * created one ourselves. 2948 */ 2949 imr->ifm_status |= IFM_ACTIVE; 2950 else if (sc->wi_ptype == WI_PORTTYPE_AP) 2951 imr->ifm_status |= IFM_ACTIVE; 2952 else { 2953 wreq.wi_type = WI_RID_COMMQUAL; 2954 wreq.wi_len = WI_MAX_DATALEN; 2955 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 && 2956 wreq.wi_val[0] != 0) 2957 imr->ifm_status |= IFM_ACTIVE; 2958 } 2959 } 2960 2961 static int 2962 wi_get_debug(sc, wreq) 2963 struct wi_softc *sc; 2964 struct wi_req *wreq; 2965 { 2966 int error = 0; 2967 2968 wreq->wi_len = 1; 2969 2970 switch (wreq->wi_type) { 2971 case WI_DEBUG_SLEEP: 2972 wreq->wi_len++; 2973 wreq->wi_val[0] = sc->wi_debug.wi_sleep; 2974 break; 2975 case WI_DEBUG_DELAYSUPP: 2976 wreq->wi_len++; 2977 wreq->wi_val[0] = sc->wi_debug.wi_delaysupp; 2978 break; 2979 case WI_DEBUG_TXSUPP: 2980 wreq->wi_len++; 2981 wreq->wi_val[0] = sc->wi_debug.wi_txsupp; 2982 break; 2983 case WI_DEBUG_MONITOR: 2984 wreq->wi_len++; 2985 wreq->wi_val[0] = sc->wi_debug.wi_monitor; 2986 break; 2987 case WI_DEBUG_LEDTEST: 2988 wreq->wi_len += 3; 2989 wreq->wi_val[0] = sc->wi_debug.wi_ledtest; 2990 wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0; 2991 wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1; 2992 break; 2993 case WI_DEBUG_CONTTX: 2994 wreq->wi_len += 2; 2995 wreq->wi_val[0] = sc->wi_debug.wi_conttx; 2996 wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0; 2997 break; 2998 case WI_DEBUG_CONTRX: 2999 wreq->wi_len++; 3000 wreq->wi_val[0] = sc->wi_debug.wi_contrx; 3001 break; 3002 case WI_DEBUG_SIGSTATE: 3003 wreq->wi_len += 2; 3004 wreq->wi_val[0] = sc->wi_debug.wi_sigstate; 3005 wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0; 3006 break; 3007 case WI_DEBUG_CONFBITS: 3008 wreq->wi_len += 2; 3009 wreq->wi_val[0] = sc->wi_debug.wi_confbits; 3010 wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0; 3011 break; 3012 default: 3013 error = EIO; 3014 break; 3015 } 3016 3017 return (error); 3018 } 3019 3020 static int 3021 wi_set_debug(sc, wreq) 3022 struct wi_softc *sc; 3023 struct wi_req *wreq; 3024 { 3025 int error = 0; 3026 u_int16_t cmd, param0 = 0, param1 = 0; 3027 3028 switch (wreq->wi_type) { 3029 case WI_DEBUG_RESET: 3030 case WI_DEBUG_INIT: 3031 case WI_DEBUG_CALENABLE: 3032 break; 3033 case WI_DEBUG_SLEEP: 3034 sc->wi_debug.wi_sleep = 1; 3035 break; 3036 case WI_DEBUG_WAKE: 3037 sc->wi_debug.wi_sleep = 0; 3038 break; 3039 case WI_DEBUG_CHAN: 3040 param0 = wreq->wi_val[0]; 3041 break; 3042 case WI_DEBUG_DELAYSUPP: 3043 sc->wi_debug.wi_delaysupp = 1; 3044 break; 3045 case WI_DEBUG_TXSUPP: 3046 sc->wi_debug.wi_txsupp = 1; 3047 break; 3048 case WI_DEBUG_MONITOR: 3049 sc->wi_debug.wi_monitor = 1; 3050 break; 3051 case WI_DEBUG_LEDTEST: 3052 param0 = wreq->wi_val[0]; 3053 param1 = wreq->wi_val[1]; 3054 sc->wi_debug.wi_ledtest = 1; 3055 sc->wi_debug.wi_ledtest_param0 = param0; 3056 sc->wi_debug.wi_ledtest_param1 = param1; 3057 break; 3058 case WI_DEBUG_CONTTX: 3059 param0 = wreq->wi_val[0]; 3060 sc->wi_debug.wi_conttx = 1; 3061 sc->wi_debug.wi_conttx_param0 = param0; 3062 break; 3063 case WI_DEBUG_STOPTEST: 3064 sc->wi_debug.wi_delaysupp = 0; 3065 sc->wi_debug.wi_txsupp = 0; 3066 sc->wi_debug.wi_monitor = 0; 3067 sc->wi_debug.wi_ledtest = 0; 3068 sc->wi_debug.wi_ledtest_param0 = 0; 3069 sc->wi_debug.wi_ledtest_param1 = 0; 3070 sc->wi_debug.wi_conttx = 0; 3071 sc->wi_debug.wi_conttx_param0 = 0; 3072 sc->wi_debug.wi_contrx = 0; 3073 sc->wi_debug.wi_sigstate = 0; 3074 sc->wi_debug.wi_sigstate_param0 = 0; 3075 break; 3076 case WI_DEBUG_CONTRX: 3077 sc->wi_debug.wi_contrx = 1; 3078 break; 3079 case WI_DEBUG_SIGSTATE: 3080 param0 = wreq->wi_val[0]; 3081 sc->wi_debug.wi_sigstate = 1; 3082 sc->wi_debug.wi_sigstate_param0 = param0; 3083 break; 3084 case WI_DEBUG_CONFBITS: 3085 param0 = wreq->wi_val[0]; 3086 param1 = wreq->wi_val[1]; 3087 sc->wi_debug.wi_confbits = param0; 3088 sc->wi_debug.wi_confbits_param0 = param1; 3089 break; 3090 default: 3091 error = EIO; 3092 break; 3093 } 3094 3095 if (error) 3096 return (error); 3097 3098 cmd = WI_CMD_DEBUG | (wreq->wi_type << 8); 3099 error = wi_cmd(sc, cmd, param0, param1, 0); 3100 3101 return (error); 3102 } 3103