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