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