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