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