1/* $NetBSD: wi.c,v 1.234 2010/11/23 04:33:09 christos Exp $ */ 2 3/*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * Copyright (c) 1997, 1998, 1999 34 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by Bill Paul. 47 * 4. Neither the name of the author nor the names of any co-contributors 48 * may be used to endorse or promote products derived from this software 49 * without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 61 * THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64/* 65 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD. 66 * 67 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu> 68 * Electrical Engineering Department 69 * Columbia University, New York City 70 */ 71 72/* 73 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 74 * from Lucent. Unlike the older cards, the new ones are programmed 75 * entirely via a firmware-driven controller called the Hermes. 76 * Unfortunately, Lucent will not release the Hermes programming manual 77 * without an NDA (if at all). What they do release is an API library 78 * called the HCF (Hardware Control Functions) which is supposed to 79 * do the device-specific operations of a device driver for you. The 80 * publically available version of the HCF library (the 'HCF Light') is 81 * a) extremely gross, b) lacks certain features, particularly support 82 * for 802.11 frames, and c) is contaminated by the GNU Public License. 83 * 84 * This driver does not use the HCF or HCF Light at all. Instead, it 85 * programs the Hermes controller directly, using information gleaned 86 * from the HCF Light code and corresponding documentation. 87 * 88 * This driver supports both the PCMCIA and ISA versions of the 89 * WaveLAN/IEEE cards. Note however that the ISA card isn't really 90 * anything of the sort: it's actually a PCMCIA bridge adapter 91 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 92 * inserted. Consequently, you need to use the pccard support for 93 * both the ISA and PCMCIA adapters. 94 */ 95 96/* 97 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the 98 * Oslo IETF plenary meeting. 99 */ 100 101#include <sys/cdefs.h> 102__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.234 2010/11/23 04:33:09 christos Exp $"); 103 104#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 105#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ 106#undef WI_HISTOGRAM 107#undef WI_RING_DEBUG 108#define STATIC static 109 110 111#include <sys/param.h> 112#include <sys/sysctl.h> 113#include <sys/systm.h> 114#include <sys/callout.h> 115#include <sys/device.h> 116#include <sys/socket.h> 117#include <sys/mbuf.h> 118#include <sys/ioctl.h> 119#include <sys/kernel.h> /* for hz */ 120#include <sys/proc.h> 121#include <sys/kauth.h> 122 123#include <net/if.h> 124#include <net/if_dl.h> 125#include <net/if_llc.h> 126#include <net/if_media.h> 127#include <net/if_ether.h> 128#include <net/route.h> 129 130#include <net80211/ieee80211_netbsd.h> 131#include <net80211/ieee80211_var.h> 132#include <net80211/ieee80211_ioctl.h> 133#include <net80211/ieee80211_radiotap.h> 134#include <net80211/ieee80211_rssadapt.h> 135 136#include <net/bpf.h> 137#include <net/bpfdesc.h> 138 139#include <sys/bus.h> 140 141#include <dev/ic/wi_ieee.h> 142#include <dev/ic/wireg.h> 143#include <dev/ic/wivar.h> 144 145STATIC int wi_init(struct ifnet *); 146STATIC void wi_stop(struct ifnet *, int); 147STATIC void wi_start(struct ifnet *); 148STATIC int wi_reset(struct wi_softc *); 149STATIC void wi_watchdog(struct ifnet *); 150STATIC int wi_ioctl(struct ifnet *, u_long, void *); 151STATIC int wi_media_change(struct ifnet *); 152STATIC void wi_media_status(struct ifnet *, struct ifmediareq *); 153 154static void wi_ioctl_init(struct wi_softc *); 155static int wi_ioctl_enter(struct wi_softc *); 156static void wi_ioctl_exit(struct wi_softc *); 157static void wi_ioctl_drain(struct wi_softc *); 158 159STATIC struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *); 160STATIC void wi_node_free(struct ieee80211_node *); 161 162STATIC void wi_raise_rate(struct ieee80211com *, struct ieee80211_rssdesc *); 163STATIC void wi_lower_rate(struct ieee80211com *, struct ieee80211_rssdesc *); 164STATIC int wi_choose_rate(struct ieee80211com *, struct ieee80211_node *, 165 struct ieee80211_frame *, u_int); 166STATIC void wi_rssadapt_updatestats_cb(void *, struct ieee80211_node *); 167STATIC void wi_rssadapt_updatestats(void *); 168STATIC void wi_rssdescs_init(struct wi_rssdesc (*)[], wi_rssdescq_t *); 169STATIC void wi_rssdescs_reset(struct ieee80211com *, struct wi_rssdesc (*)[], 170 wi_rssdescq_t *, u_int8_t (*)[]); 171STATIC void wi_sync_bssid(struct wi_softc *, u_int8_t new_bssid[]); 172 173STATIC void wi_rx_intr(struct wi_softc *); 174STATIC void wi_txalloc_intr(struct wi_softc *); 175STATIC void wi_cmd_intr(struct wi_softc *); 176STATIC void wi_tx_intr(struct wi_softc *); 177STATIC void wi_tx_ex_intr(struct wi_softc *); 178STATIC void wi_info_intr(struct wi_softc *); 179 180STATIC int wi_key_delete(struct ieee80211com *, const struct ieee80211_key *); 181STATIC int wi_key_set(struct ieee80211com *, const struct ieee80211_key *, 182 const u_int8_t[IEEE80211_ADDR_LEN]); 183STATIC void wi_key_update_begin(struct ieee80211com *); 184STATIC void wi_key_update_end(struct ieee80211com *); 185 186STATIC void wi_push_packet(struct wi_softc *); 187STATIC int wi_get_cfg(struct ifnet *, u_long, void *); 188STATIC int wi_set_cfg(struct ifnet *, u_long, void *); 189STATIC int wi_cfg_txrate(struct wi_softc *); 190STATIC int wi_write_txrate(struct wi_softc *, int); 191STATIC int wi_write_wep(struct wi_softc *); 192STATIC int wi_write_multi(struct wi_softc *); 193STATIC int wi_alloc_fid(struct wi_softc *, int, int *); 194STATIC void wi_read_nicid(struct wi_softc *); 195STATIC int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); 196 197STATIC int wi_cmd(struct wi_softc *, int, int, int, int); 198STATIC int wi_cmd_start(struct wi_softc *, int, int, int, int); 199STATIC int wi_cmd_wait(struct wi_softc *, int, int); 200STATIC int wi_seek_bap(struct wi_softc *, int, int); 201STATIC int wi_read_bap(struct wi_softc *, int, int, void *, int); 202STATIC int wi_write_bap(struct wi_softc *, int, int, void *, int); 203STATIC int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int); 204STATIC int wi_read_rid(struct wi_softc *, int, void *, int *); 205STATIC int wi_write_rid(struct wi_softc *, int, void *, int); 206 207STATIC int wi_newstate(struct ieee80211com *, enum ieee80211_state, int); 208STATIC void wi_set_tim(struct ieee80211_node *, int); 209 210STATIC int wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t); 211STATIC void wi_scan_result(struct wi_softc *, int, int); 212 213STATIC void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi); 214STATIC void wi_mend_flags(struct wi_softc *, enum ieee80211_state); 215 216static inline int 217wi_write_val(struct wi_softc *sc, int rid, u_int16_t val) 218{ 219 220 val = htole16(val); 221 return wi_write_rid(sc, rid, &val, sizeof(val)); 222} 223 224static struct timeval lasttxerror; /* time of last tx error msg */ 225static int curtxeps = 0; /* current tx error msgs/sec */ 226static int wi_txerate = 0; /* tx error rate: max msgs/sec */ 227 228#ifdef WI_DEBUG 229#define WI_DEBUG_MAX 2 230int wi_debug = 0; 231 232#define DPRINTF(X) if (wi_debug) printf X 233#define DPRINTF2(X) if (wi_debug > 1) printf X 234#define IFF_DUMPPKTS(_ifp) \ 235 (((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) 236static int wi_sysctl_verify_debug(SYSCTLFN_PROTO); 237#else 238#define DPRINTF(X) 239#define DPRINTF2(X) 240#define IFF_DUMPPKTS(_ifp) 0 241#endif 242 243#define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO | \ 244 WI_EV_TX | WI_EV_TX_EXC | WI_EV_CMD) 245 246struct wi_card_ident 247wi_card_ident[] = { 248 /* CARD_ID CARD_NAME FIRM_TYPE */ 249 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT }, 250 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT }, 251 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT }, 252 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL }, 253 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL }, 254 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL }, 255 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL }, 256 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL }, 257 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL }, 258 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL }, 259 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL }, 260 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL }, 261 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 262 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 263 { WI_NIC_3842_PCMCIA_ATM_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 264 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 265 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 266 { WI_NIC_3842_MINI_ATM_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 267 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 268 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 269 { WI_NIC_3842_PCI_ATM_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 270 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 271 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 272 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 273 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 274 { 0, NULL, 0 }, 275}; 276 277#ifndef _MODULE 278/* 279 * Setup sysctl(3) MIB, hw.wi.* 280 * 281 * TBD condition CTLFLAG_PERMANENT on being a module or not 282 */ 283SYSCTL_SETUP(sysctl_wi, "sysctl wi(4) subtree setup") 284{ 285 int rc; 286 const struct sysctlnode *rnode; 287#ifdef WI_DEBUG 288 const struct sysctlnode *cnode; 289#endif /* WI_DEBUG */ 290 291 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 292 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 293 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 294 goto err; 295 296 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 297 CTLFLAG_PERMANENT, CTLTYPE_NODE, "wi", 298 "Lucent/Prism/Symbol 802.11 controls", 299 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 300 goto err; 301 302#ifdef WI_DEBUG 303 /* control debugging printfs */ 304 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 305 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 306 "debug", SYSCTL_DESCR("Enable debugging output"), 307 wi_sysctl_verify_debug, 0, &wi_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 308 goto err; 309#endif /* WI_DEBUG */ 310 return; 311err: 312 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 313} 314#endif 315 316#ifdef WI_DEBUG 317static int 318wi_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 319{ 320 int error, t; 321 struct sysctlnode node; 322 323 node = *rnode; 324 t = *(int*)rnode->sysctl_data; 325 node.sysctl_data = &t; 326 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 327 if (error || newp == NULL) 328 return (error); 329 330 if (t < lower || t > upper) 331 return (EINVAL); 332 333 *(int*)rnode->sysctl_data = t; 334 335 return (0); 336} 337 338static int 339wi_sysctl_verify_debug(SYSCTLFN_ARGS) 340{ 341 return wi_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 342 0, WI_DEBUG_MAX); 343} 344#endif /* WI_DEBUG */ 345 346STATIC int 347wi_read_xrid(struct wi_softc *sc, int rid, void *buf, int ebuflen) 348{ 349 int buflen, rc; 350 351 buflen = ebuflen; 352 if ((rc = wi_read_rid(sc, rid, buf, &buflen)) != 0) 353 return rc; 354 355 if (buflen < ebuflen) { 356#ifdef WI_DEBUG 357 printf("%s: rid=%#04x read %d, expected %d\n", __func__, 358 rid, buflen, ebuflen); 359#endif 360 return -1; 361 } 362 return 0; 363} 364 365int 366wi_attach(struct wi_softc *sc, const u_int8_t *macaddr) 367{ 368 struct ieee80211com *ic = &sc->sc_ic; 369 struct ifnet *ifp = &sc->sc_if; 370 int chan, nrate, buflen; 371 u_int16_t val, chanavail; 372 struct { 373 u_int16_t nrates; 374 char rates[IEEE80211_RATE_SIZE]; 375 } ratebuf; 376 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 378 }; 379 int s; 380 381 wi_ioctl_init(sc); 382 383 s = splnet(); 384 385 /* Make sure interrupts are disabled. */ 386 CSR_WRITE_2(sc, WI_INT_EN, 0); 387 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 388 389 sc->sc_invalid = 0; 390 391 /* Reset the NIC. */ 392 if (wi_reset(sc) != 0) { 393 sc->sc_invalid = 1; 394 splx(s); 395 return 1; 396 } 397 398 if (wi_read_xrid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, 399 IEEE80211_ADDR_LEN) != 0 || 400 IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) { 401 if (macaddr != NULL) 402 memcpy(ic->ic_myaddr, macaddr, IEEE80211_ADDR_LEN); 403 else { 404 printf(" could not get mac address, attach failed\n"); 405 splx(s); 406 return 1; 407 } 408 } 409 410 printf(" 802.11 address %s\n", ether_sprintf(ic->ic_myaddr)); 411 412 /* Read NIC identification */ 413 wi_read_nicid(sc); 414 415 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 416 ifp->if_softc = sc; 417 ifp->if_start = wi_start; 418 ifp->if_ioctl = wi_ioctl; 419 ifp->if_watchdog = wi_watchdog; 420 ifp->if_init = wi_init; 421 ifp->if_stop = wi_stop; 422 ifp->if_flags = 423 IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS; 424 IFQ_SET_READY(&ifp->if_snd); 425 426 ic->ic_ifp = ifp; 427 ic->ic_phytype = IEEE80211_T_DS; 428 ic->ic_opmode = IEEE80211_M_STA; 429 ic->ic_caps = IEEE80211_C_AHDEMO; 430 ic->ic_state = IEEE80211_S_INIT; 431 ic->ic_max_aid = WI_MAX_AID; 432 433 /* Find available channel */ 434 if (wi_read_xrid(sc, WI_RID_CHANNEL_LIST, &chanavail, 435 sizeof(chanavail)) != 0) { 436 aprint_normal_dev(sc->sc_dev, "using default channel list\n"); 437 chanavail = htole16(0x1fff); /* assume 1-13 */ 438 } 439 for (chan = 16; chan > 0; chan--) { 440 if (!isset((u_int8_t*)&chanavail, chan - 1)) 441 continue; 442 ic->ic_ibss_chan = &ic->ic_channels[chan]; 443 ic->ic_channels[chan].ic_freq = 444 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 445 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B; 446 } 447 448 /* Find default IBSS channel */ 449 if (wi_read_xrid(sc, WI_RID_OWN_CHNL, &val, sizeof(val)) == 0) { 450 chan = le16toh(val); 451 if (isset((u_int8_t*)&chanavail, chan - 1)) 452 ic->ic_ibss_chan = &ic->ic_channels[chan]; 453 } 454 if (ic->ic_ibss_chan == NULL) { 455 aprint_error_dev(sc->sc_dev, "no available channel\n"); 456 return 1; 457 } 458 459 if (sc->sc_firmware_type == WI_LUCENT) { 460 sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET; 461 } else { 462 if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) && 463 wi_read_xrid(sc, WI_RID_DBM_ADJUST, &val, sizeof(val)) == 0) 464 sc->sc_dbm_offset = le16toh(val); 465 else 466 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET; 467 } 468 469 sc->sc_flags |= WI_FLAGS_RSSADAPTSTA; 470 471 /* 472 * Set flags based on firmware version. 473 */ 474 switch (sc->sc_firmware_type) { 475 case WI_LUCENT: 476 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; 477#ifdef WI_HERMES_AUTOINC_WAR 478 /* XXX: not confirmed, but never seen for recent firmware */ 479 if (sc->sc_sta_firmware_ver < 40000) { 480 sc->sc_flags |= WI_FLAGS_BUG_AUTOINC; 481 } 482#endif 483 if (sc->sc_sta_firmware_ver >= 60000) 484 sc->sc_flags |= WI_FLAGS_HAS_MOR; 485 if (sc->sc_sta_firmware_ver >= 60006) { 486 ic->ic_caps |= IEEE80211_C_IBSS; 487 ic->ic_caps |= IEEE80211_C_MONITOR; 488 } 489 ic->ic_caps |= IEEE80211_C_PMGT; 490 sc->sc_ibss_port = 1; 491 break; 492 493 case WI_INTERSIL: 494 sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR; 495 sc->sc_flags |= WI_FLAGS_HAS_ROAMING; 496 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; 497 if (sc->sc_sta_firmware_ver > 10101) 498 sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST; 499 if (sc->sc_sta_firmware_ver >= 800) { 500 if (sc->sc_sta_firmware_ver != 10402) 501 ic->ic_caps |= IEEE80211_C_HOSTAP; 502 ic->ic_caps |= IEEE80211_C_IBSS; 503 ic->ic_caps |= IEEE80211_C_MONITOR; 504 } 505 ic->ic_caps |= IEEE80211_C_PMGT; 506 sc->sc_ibss_port = 0; 507 sc->sc_alt_retry = 2; 508 break; 509 510 case WI_SYMBOL: 511 sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY; 512 if (sc->sc_sta_firmware_ver >= 20000) 513 ic->ic_caps |= IEEE80211_C_IBSS; 514 sc->sc_ibss_port = 4; 515 break; 516 } 517 518 /* 519 * Find out if we support WEP on this card. 520 */ 521 if (wi_read_xrid(sc, WI_RID_WEP_AVAIL, &val, sizeof(val)) == 0 && 522 val != htole16(0)) 523 ic->ic_caps |= IEEE80211_C_WEP; 524 525 /* Find supported rates. */ 526 buflen = sizeof(ratebuf); 527 if (wi_read_rid(sc, WI_RID_DATA_RATES, &ratebuf, &buflen) == 0 && 528 buflen > 2) { 529 nrate = le16toh(ratebuf.nrates); 530 if (nrate > IEEE80211_RATE_SIZE) 531 nrate = IEEE80211_RATE_SIZE; 532 memcpy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates, 533 &ratebuf.rates[0], nrate); 534 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 535 } else { 536 aprint_error_dev(sc->sc_dev, "no supported rate list\n"); 537 return 1; 538 } 539 540 sc->sc_max_datalen = 2304; 541 sc->sc_rts_thresh = 2347; 542 sc->sc_frag_thresh = 2346; 543 sc->sc_system_scale = 1; 544 sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN; 545 sc->sc_roaming_mode = 1; 546 547 callout_init(&sc->sc_rssadapt_ch, 0); 548 549 /* 550 * Call MI attach routines. 551 */ 552 if_attach(ifp); 553 ieee80211_ifattach(ic); 554 555 sc->sc_newstate = ic->ic_newstate; 556 sc->sc_set_tim = ic->ic_set_tim; 557 ic->ic_newstate = wi_newstate; 558 ic->ic_node_alloc = wi_node_alloc; 559 ic->ic_node_free = wi_node_free; 560 ic->ic_set_tim = wi_set_tim; 561 562 ic->ic_crypto.cs_key_delete = wi_key_delete; 563 ic->ic_crypto.cs_key_set = wi_key_set; 564 ic->ic_crypto.cs_key_update_begin = wi_key_update_begin; 565 ic->ic_crypto.cs_key_update_end = wi_key_update_end; 566 567 ieee80211_media_init(ic, wi_media_change, wi_media_status); 568 569 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 570 sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf); 571 572 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 573 sc->sc_rxtap.wr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); 574 sc->sc_rxtap.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT); 575 576 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 577 sc->sc_txtap.wt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); 578 sc->sc_txtap.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT); 579 580 /* Attach is successful. */ 581 sc->sc_attached = 1; 582 583 splx(s); 584 ieee80211_announce(ic); 585 return 0; 586} 587 588int 589wi_detach(struct wi_softc *sc) 590{ 591 struct ifnet *ifp = &sc->sc_if; 592 int s; 593 594 if (!sc->sc_attached) 595 return 0; 596 597 sc->sc_invalid = 1; 598 s = splnet(); 599 600 wi_stop(ifp, 1); 601 602 ieee80211_ifdetach(&sc->sc_ic); 603 if_detach(ifp); 604 splx(s); 605 wi_ioctl_drain(sc); 606 return 0; 607} 608 609int 610wi_activate(device_t self, enum devact act) 611{ 612 struct wi_softc *sc = device_private(self); 613 614 switch (act) { 615 case DVACT_DEACTIVATE: 616 if_deactivate(&sc->sc_if); 617 return 0; 618 default: 619 return EOPNOTSUPP; 620 } 621} 622 623int 624wi_intr(void *arg) 625{ 626 int i; 627 struct wi_softc *sc = arg; 628 struct ifnet *ifp = &sc->sc_if; 629 u_int16_t status; 630 631 if (sc->sc_enabled == 0 || 632 !device_is_active(sc->sc_dev) || 633 (ifp->if_flags & IFF_RUNNING) == 0) 634 return 0; 635 636 if ((ifp->if_flags & IFF_UP) == 0) { 637 CSR_WRITE_2(sc, WI_INT_EN, 0); 638 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 639 return 1; 640 } 641 642 /* This is superfluous on Prism, but Lucent breaks if we 643 * do not disable interrupts. 644 */ 645 CSR_WRITE_2(sc, WI_INT_EN, 0); 646 647 /* maximum 10 loops per interrupt */ 648 for (i = 0; i < 10; i++) { 649 status = CSR_READ_2(sc, WI_EVENT_STAT); 650#ifdef WI_DEBUG 651 if (wi_debug > 1) { 652 printf("%s: iter %d status %#04x\n", __func__, i, 653 status); 654 } 655#endif /* WI_DEBUG */ 656 if ((status & WI_INTRS) == 0) 657 break; 658 659 sc->sc_status = status; 660 661 if (status & WI_EV_RX) 662 wi_rx_intr(sc); 663 664 if (status & WI_EV_ALLOC) 665 wi_txalloc_intr(sc); 666 667 if (status & WI_EV_TX) 668 wi_tx_intr(sc); 669 670 if (status & WI_EV_TX_EXC) 671 wi_tx_ex_intr(sc); 672 673 if (status & WI_EV_INFO) 674 wi_info_intr(sc); 675 676 CSR_WRITE_2(sc, WI_EVENT_ACK, sc->sc_status); 677 678 if (sc->sc_status & WI_EV_CMD) 679 wi_cmd_intr(sc); 680 681 if ((ifp->if_flags & IFF_OACTIVE) == 0 && 682 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 && 683 !IFQ_IS_EMPTY(&ifp->if_snd)) 684 wi_start(ifp); 685 686 sc->sc_status = 0; 687 } 688 689 /* re-enable interrupts */ 690 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 691 692 sc->sc_status = 0; 693 694 return 1; 695} 696 697#define arraylen(a) (sizeof(a) / sizeof((a)[0])) 698 699STATIC void 700wi_rssdescs_init(struct wi_rssdesc (*rssd)[WI_NTXRSS], wi_rssdescq_t *rssdfree) 701{ 702 int i; 703 SLIST_INIT(rssdfree); 704 for (i = 0; i < arraylen(*rssd); i++) { 705 SLIST_INSERT_HEAD(rssdfree, &(*rssd)[i], rd_next); 706 } 707} 708 709STATIC void 710wi_rssdescs_reset(struct ieee80211com *ic, struct wi_rssdesc (*rssd)[WI_NTXRSS], 711 wi_rssdescq_t *rssdfree, u_int8_t (*txpending)[IEEE80211_RATE_MAXSIZE]) 712{ 713 struct ieee80211_node *ni; 714 int i; 715 for (i = 0; i < arraylen(*rssd); i++) { 716 ni = (*rssd)[i].rd_desc.id_node; 717 (*rssd)[i].rd_desc.id_node = NULL; 718 if (ni != NULL && (ic->ic_ifp->if_flags & IFF_DEBUG) != 0) 719 printf("%s: cleaning outstanding rssadapt " 720 "descriptor for %s\n", 721 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr)); 722 if (ni != NULL) 723 ieee80211_free_node(ni); 724 } 725 memset(*txpending, 0, sizeof(*txpending)); 726 wi_rssdescs_init(rssd, rssdfree); 727} 728 729STATIC int 730wi_init(struct ifnet *ifp) 731{ 732 struct wi_softc *sc = ifp->if_softc; 733 struct ieee80211com *ic = &sc->sc_ic; 734 struct wi_joinreq join; 735 int i; 736 int error = 0, wasenabled; 737 738 DPRINTF(("wi_init: enabled %d\n", sc->sc_enabled)); 739 wasenabled = sc->sc_enabled; 740 if (!sc->sc_enabled) { 741 if ((error = (*sc->sc_enable)(sc->sc_dev, 1)) != 0) 742 goto out; 743 sc->sc_enabled = 1; 744 } else 745 wi_stop(ifp, 0); 746 747 /* Symbol firmware cannot be initialized more than once */ 748 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) 749 if ((error = wi_reset(sc)) != 0) 750 goto out; 751 752 /* common 802.11 configuration */ 753 ic->ic_flags &= ~IEEE80211_F_IBSSON; 754 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 755 switch (ic->ic_opmode) { 756 case IEEE80211_M_STA: 757 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS); 758 break; 759 case IEEE80211_M_IBSS: 760 wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port); 761 ic->ic_flags |= IEEE80211_F_IBSSON; 762 break; 763 case IEEE80211_M_AHDEMO: 764 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); 765 break; 766 case IEEE80211_M_HOSTAP: 767 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP); 768 break; 769 case IEEE80211_M_MONITOR: 770 if (sc->sc_firmware_type == WI_LUCENT) 771 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); 772 wi_cmd(sc, WI_CMD_TEST | (WI_TEST_MONITOR << 8), 0, 0, 0); 773 break; 774 } 775 776 /* Intersil interprets this RID as joining ESS even in IBSS mode */ 777 if (sc->sc_firmware_type == WI_LUCENT && 778 (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0) 779 wi_write_val(sc, WI_RID_CREATE_IBSS, 1); 780 else 781 wi_write_val(sc, WI_RID_CREATE_IBSS, 0); 782 wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval); 783 wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid, 784 ic->ic_des_esslen); 785 wi_write_val(sc, WI_RID_OWN_CHNL, 786 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)); 787 wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen); 788 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 789 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN); 790 if (ic->ic_caps & IEEE80211_C_PMGT) 791 wi_write_val(sc, WI_RID_PM_ENABLED, 792 (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0); 793 794 /* not yet common 802.11 configuration */ 795 wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen); 796 wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh); 797 if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) 798 wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh); 799 800 /* driver specific 802.11 configuration */ 801 if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) 802 wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale); 803 if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) 804 wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode); 805 if (sc->sc_flags & WI_FLAGS_HAS_MOR) 806 wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven); 807 wi_cfg_txrate(sc); 808 wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen); 809 810#ifndef IEEE80211_NO_HOSTAP 811 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 812 sc->sc_firmware_type == WI_INTERSIL) { 813 wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval); 814 wi_write_val(sc, WI_RID_DTIM_PERIOD, 1); 815 } 816#endif /* !IEEE80211_NO_HOSTAP */ 817 818 if (sc->sc_firmware_type == WI_INTERSIL) { 819 struct ieee80211_rateset *rs = 820 &ic->ic_sup_rates[IEEE80211_MODE_11B]; 821 u_int16_t basic = 0, supported = 0, rate; 822 823 for (i = 0; i < rs->rs_nrates; i++) { 824 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) { 825 case 2: 826 rate = 1; 827 break; 828 case 4: 829 rate = 2; 830 break; 831 case 11: 832 rate = 4; 833 break; 834 case 22: 835 rate = 8; 836 break; 837 default: 838 rate = 0; 839 break; 840 } 841 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) 842 basic |= rate; 843 supported |= rate; 844 } 845 wi_write_val(sc, WI_RID_BASIC_RATE, basic); 846 wi_write_val(sc, WI_RID_SUPPORT_RATE, supported); 847 wi_write_val(sc, WI_RID_ALT_RETRY_COUNT, sc->sc_alt_retry); 848 } 849 850 /* 851 * Initialize promisc mode. 852 * Being in Host-AP mode causes a great 853 * deal of pain if promiscuous mode is set. 854 * Therefore we avoid confusing the firmware 855 * and always reset promisc mode in Host-AP 856 * mode. Host-AP sees all the packets anyway. 857 */ 858 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 859 (ifp->if_flags & IFF_PROMISC) != 0) { 860 wi_write_val(sc, WI_RID_PROMISC, 1); 861 } else { 862 wi_write_val(sc, WI_RID_PROMISC, 0); 863 } 864 865 /* Configure WEP. */ 866 if (ic->ic_caps & IEEE80211_C_WEP) { 867 sc->sc_cnfauthmode = ic->ic_bss->ni_authmode; 868 wi_write_wep(sc); 869 } 870 871 /* Set multicast filter. */ 872 wi_write_multi(sc); 873 874 sc->sc_txalloc = 0; 875 sc->sc_txalloced = 0; 876 sc->sc_txqueue = 0; 877 sc->sc_txqueued = 0; 878 sc->sc_txstart = 0; 879 sc->sc_txstarted = 0; 880 881 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) { 882 sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame); 883 if (sc->sc_firmware_type == WI_SYMBOL) 884 sc->sc_buflen = 1585; /* XXX */ 885 for (i = 0; i < WI_NTXBUF; i++) { 886 error = wi_alloc_fid(sc, sc->sc_buflen, 887 &sc->sc_txd[i].d_fid); 888 if (error) { 889 aprint_error_dev(sc->sc_dev, 890 "tx buffer allocation failed\n"); 891 goto out; 892 } 893 DPRINTF2(("wi_init: txbuf %d allocated %x\n", i, 894 sc->sc_txd[i].d_fid)); 895 ++sc->sc_txalloced; 896 } 897 } 898 899 wi_rssdescs_init(&sc->sc_rssd, &sc->sc_rssdfree); 900 901 /* Enable desired port */ 902 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); 903 ifp->if_flags |= IFF_RUNNING; 904 ifp->if_flags &= ~IFF_OACTIVE; 905 ic->ic_state = IEEE80211_S_INIT; 906 907 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 908 ic->ic_opmode == IEEE80211_M_IBSS || 909 ic->ic_opmode == IEEE80211_M_MONITOR || 910 ic->ic_opmode == IEEE80211_M_HOSTAP) 911 ieee80211_create_ibss(ic, ic->ic_ibss_chan); 912 913 /* Enable interrupts */ 914 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 915 916#ifndef IEEE80211_NO_HOSTAP 917 if (!wasenabled && 918 ic->ic_opmode == IEEE80211_M_HOSTAP && 919 sc->sc_firmware_type == WI_INTERSIL) { 920 /* XXX: some card need to be re-enabled for hostap */ 921 wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); 922 wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); 923 } 924#endif /* !IEEE80211_NO_HOSTAP */ 925 926 if (ic->ic_opmode == IEEE80211_M_STA && 927 ((ic->ic_flags & IEEE80211_F_DESBSSID) || 928 ic->ic_des_chan != IEEE80211_CHAN_ANYC)) { 929 memset(&join, 0, sizeof(join)); 930 if (ic->ic_flags & IEEE80211_F_DESBSSID) 931 IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid); 932 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) 933 join.wi_chan = 934 htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan)); 935 /* Lucent firmware does not support the JOIN RID. */ 936 if (sc->sc_firmware_type != WI_LUCENT) 937 wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join)); 938 } 939 940 out: 941 if (error) { 942 printf("%s: interface not running\n", device_xname(sc->sc_dev)); 943 wi_stop(ifp, 0); 944 } 945 DPRINTF(("wi_init: return %d\n", error)); 946 return error; 947} 948 949STATIC void 950wi_txcmd_wait(struct wi_softc *sc) 951{ 952 KASSERT(sc->sc_txcmds == 1); 953 if (sc->sc_status & WI_EV_CMD) { 954 sc->sc_status &= ~WI_EV_CMD; 955 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 956 } else 957 (void)wi_cmd_wait(sc, WI_CMD_TX | WI_RECLAIM, 0); 958} 959 960STATIC void 961wi_stop(struct ifnet *ifp, int disable) 962{ 963 struct wi_softc *sc = ifp->if_softc; 964 struct ieee80211com *ic = &sc->sc_ic; 965 int s; 966 967 if (!sc->sc_enabled) 968 return; 969 970 s = splnet(); 971 972 DPRINTF(("wi_stop: disable %d\n", disable)); 973 974 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 975 976 /* wait for tx command completion (deassoc, deauth) */ 977 while (sc->sc_txcmds > 0) { 978 wi_txcmd_wait(sc); 979 wi_cmd_intr(sc); 980 } 981 982 /* TBD wait for deassoc, deauth tx completion? */ 983 984 if (!sc->sc_invalid) { 985 CSR_WRITE_2(sc, WI_INT_EN, 0); 986 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0); 987 } 988 989 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 990 &sc->sc_txpending); 991 992 sc->sc_tx_timer = 0; 993 sc->sc_scan_timer = 0; 994 sc->sc_false_syns = 0; 995 sc->sc_naps = 0; 996 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING); 997 ifp->if_timer = 0; 998 999 if (disable) { 1000 (*sc->sc_enable)(sc->sc_dev, 0); 1001 sc->sc_enabled = 0; 1002 } 1003 splx(s); 1004} 1005 1006/* 1007 * Choose a data rate for a packet len bytes long that suits the packet 1008 * type and the wireless conditions. 1009 * 1010 * TBD Adapt fragmentation threshold. 1011 */ 1012STATIC int 1013wi_choose_rate(struct ieee80211com *ic, struct ieee80211_node *ni, 1014 struct ieee80211_frame *wh, u_int len) 1015{ 1016 struct wi_softc *sc = ic->ic_ifp->if_softc; 1017 struct wi_node *wn = (void*)ni; 1018 struct ieee80211_rssadapt *ra = &wn->wn_rssadapt; 1019 int do_not_adapt, i, rateidx, s; 1020 1021 do_not_adapt = (ic->ic_opmode != IEEE80211_M_HOSTAP) && 1022 (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) == 0; 1023 1024 s = splnet(); 1025 1026 rateidx = ieee80211_rssadapt_choose(ra, &ni->ni_rates, wh, len, 1027 ic->ic_fixed_rate, 1028 ((ic->ic_ifp->if_flags & IFF_DEBUG) == 0) ? NULL : ic->ic_ifp->if_xname, 1029 do_not_adapt); 1030 1031 ni->ni_txrate = rateidx; 1032 1033 if (ic->ic_opmode != IEEE80211_M_HOSTAP) { 1034 /* choose the slowest pending rate so that we don't 1035 * accidentally send a packet on the MAC's queue 1036 * too fast. TBD find out if the MAC labels Tx 1037 * packets w/ rate when enqueued or dequeued. 1038 */ 1039 for (i = 0; i < rateidx && sc->sc_txpending[i] == 0; i++); 1040 rateidx = i; 1041 } 1042 1043 splx(s); 1044 return (rateidx); 1045} 1046 1047STATIC void 1048wi_raise_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id) 1049{ 1050 struct wi_node *wn; 1051 if (id->id_node == NULL) 1052 return; 1053 1054 wn = (void*)id->id_node; 1055 ieee80211_rssadapt_raise_rate(ic, &wn->wn_rssadapt, id); 1056} 1057 1058STATIC void 1059wi_lower_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id) 1060{ 1061 struct ieee80211_node *ni; 1062 struct wi_node *wn; 1063 int s; 1064 1065 s = splnet(); 1066 1067 if ((ni = id->id_node) == NULL) { 1068 DPRINTF(("wi_lower_rate: missing node\n")); 1069 goto out; 1070 } 1071 1072 wn = (void *)ni; 1073 1074 ieee80211_rssadapt_lower_rate(ic, ni, &wn->wn_rssadapt, id); 1075out: 1076 splx(s); 1077 return; 1078} 1079 1080STATIC void 1081wi_start(struct ifnet *ifp) 1082{ 1083 struct wi_softc *sc = ifp->if_softc; 1084 struct ieee80211com *ic = &sc->sc_ic; 1085 struct ether_header *eh; 1086 struct ieee80211_node *ni; 1087 struct ieee80211_frame *wh; 1088 struct ieee80211_rateset *rs; 1089 struct wi_rssdesc *rd; 1090 struct ieee80211_rssdesc *id; 1091 struct mbuf *m0; 1092 struct wi_frame frmhdr; 1093 int cur, fid, off, rateidx; 1094 1095 if (!sc->sc_enabled || sc->sc_invalid) 1096 return; 1097 if (sc->sc_flags & WI_FLAGS_OUTRANGE) 1098 return; 1099 1100 memset(&frmhdr, 0, sizeof(frmhdr)); 1101 cur = sc->sc_txqueue; 1102 for (;;) { 1103 ni = ic->ic_bss; 1104 if (sc->sc_txalloced == 0 || SLIST_EMPTY(&sc->sc_rssdfree)) { 1105 ifp->if_flags |= IFF_OACTIVE; 1106 break; 1107 } 1108 if (!IF_IS_EMPTY(&ic->ic_mgtq)) { 1109 IF_DEQUEUE(&ic->ic_mgtq, m0); 1110 m_copydata(m0, 4, ETHER_ADDR_LEN * 2, 1111 (void *)&frmhdr.wi_ehdr); 1112 frmhdr.wi_ehdr.ether_type = 0; 1113 wh = mtod(m0, struct ieee80211_frame *); 1114 ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 1115 m0->m_pkthdr.rcvif = NULL; 1116 } else if (ic->ic_state == IEEE80211_S_RUN) { 1117 IFQ_POLL(&ifp->if_snd, m0); 1118 if (m0 == NULL) 1119 break; 1120 IFQ_DEQUEUE(&ifp->if_snd, m0); 1121 ifp->if_opackets++; 1122 m_copydata(m0, 0, ETHER_HDR_LEN, 1123 (void *)&frmhdr.wi_ehdr); 1124 bpf_mtap(ifp, m0); 1125 1126 eh = mtod(m0, struct ether_header *); 1127 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 1128 if (ni == NULL) { 1129 ifp->if_oerrors++; 1130 continue; 1131 } 1132 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && 1133 (m0->m_flags & M_PWR_SAV) == 0) { 1134 ieee80211_pwrsave(ic, ni, m0); 1135 goto next; 1136 } 1137 if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) { 1138 ieee80211_free_node(ni); 1139 ifp->if_oerrors++; 1140 continue; 1141 } 1142 wh = mtod(m0, struct ieee80211_frame *); 1143 } else 1144 break; 1145 bpf_mtap3(ic->ic_rawbpf, m0); 1146 frmhdr.wi_tx_ctl = 1147 htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX|WI_TXCNTL_TX_OK); 1148#ifndef IEEE80211_NO_HOSTAP 1149 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 1150 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY); 1151 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1152 (wh->i_fc[1] & IEEE80211_FC1_WEP)) { 1153 if (ieee80211_crypto_encap(ic, ni, m0) == NULL) { 1154 m_freem(m0); 1155 ifp->if_oerrors++; 1156 goto next; 1157 } 1158 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); 1159 } 1160#endif /* !IEEE80211_NO_HOSTAP */ 1161 1162 rateidx = wi_choose_rate(ic, ni, wh, m0->m_pkthdr.len); 1163 rs = &ni->ni_rates; 1164 1165 if (sc->sc_drvbpf) { 1166 struct wi_tx_radiotap_header *tap = &sc->sc_txtap; 1167 1168 tap->wt_rate = rs->rs_rates[rateidx]; 1169 tap->wt_chan_freq = 1170 htole16(ic->ic_bss->ni_chan->ic_freq); 1171 tap->wt_chan_flags = 1172 htole16(ic->ic_bss->ni_chan->ic_flags); 1173 /* TBD tap->wt_flags */ 1174 1175 bpf_mtap2(sc->sc_drvbpf, tap, tap->wt_ihdr.it_len, m0); 1176 } 1177 1178 rd = SLIST_FIRST(&sc->sc_rssdfree); 1179 id = &rd->rd_desc; 1180 id->id_len = m0->m_pkthdr.len; 1181 id->id_rateidx = ni->ni_txrate; 1182 id->id_rssi = ni->ni_rssi; 1183 1184 frmhdr.wi_tx_idx = rd - sc->sc_rssd; 1185 1186 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 1187 frmhdr.wi_tx_rate = 5 * (rs->rs_rates[rateidx] & 1188 IEEE80211_RATE_VAL); 1189 else if (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) 1190 (void)wi_write_txrate(sc, rs->rs_rates[rateidx]); 1191 1192 m_copydata(m0, 0, sizeof(struct ieee80211_frame), 1193 (void *)&frmhdr.wi_whdr); 1194 m_adj(m0, sizeof(struct ieee80211_frame)); 1195 frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); 1196 if (IFF_DUMPPKTS(ifp)) 1197 wi_dump_pkt(&frmhdr, ni, -1); 1198 fid = sc->sc_txd[cur].d_fid; 1199 off = sizeof(frmhdr); 1200 if (wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0 || 1201 wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0) { 1202 aprint_error_dev(sc->sc_dev, "%s write fid %x failed\n", 1203 __func__, fid); 1204 ifp->if_oerrors++; 1205 m_freem(m0); 1206 goto next; 1207 } 1208 m_freem(m0); 1209 sc->sc_txpending[ni->ni_txrate]++; 1210 --sc->sc_txalloced; 1211 if (sc->sc_txqueued++ == 0) { 1212#ifdef DIAGNOSTIC 1213 if (cur != sc->sc_txstart) 1214 printf("%s: ring is desynchronized\n", 1215 device_xname(sc->sc_dev)); 1216#endif 1217 wi_push_packet(sc); 1218 } else { 1219#ifdef WI_RING_DEBUG 1220 printf("%s: queue %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1221 device_xname(sc->sc_dev), fid, 1222 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1223 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1224#endif 1225 } 1226 sc->sc_txqueue = cur = (cur + 1) % WI_NTXBUF; 1227 SLIST_REMOVE_HEAD(&sc->sc_rssdfree, rd_next); 1228 id->id_node = ni; 1229 continue; 1230next: 1231 if (ni != NULL) 1232 ieee80211_free_node(ni); 1233 } 1234} 1235 1236 1237STATIC int 1238wi_reset(struct wi_softc *sc) 1239{ 1240 int i, error; 1241 1242 DPRINTF(("wi_reset\n")); 1243 1244 if (sc->sc_reset) 1245 (*sc->sc_reset)(sc); 1246 1247 error = 0; 1248 for (i = 0; i < 5; i++) { 1249 if (sc->sc_invalid) 1250 return ENXIO; 1251 DELAY(20*1000); /* XXX: way too long! */ 1252 if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0) 1253 break; 1254 } 1255 if (error) { 1256 aprint_error_dev(sc->sc_dev, "init failed\n"); 1257 return error; 1258 } 1259 CSR_WRITE_2(sc, WI_INT_EN, 0); 1260 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 1261 1262 /* Calibrate timer. */ 1263 wi_write_val(sc, WI_RID_TICK_TIME, 0); 1264 return 0; 1265} 1266 1267STATIC void 1268wi_watchdog(struct ifnet *ifp) 1269{ 1270 struct wi_softc *sc = ifp->if_softc; 1271 1272 ifp->if_timer = 0; 1273 if (!sc->sc_enabled) 1274 return; 1275 1276 if (sc->sc_tx_timer) { 1277 if (--sc->sc_tx_timer == 0) { 1278 printf("%s: device timeout\n", ifp->if_xname); 1279 ifp->if_oerrors++; 1280 wi_init(ifp); 1281 return; 1282 } 1283 ifp->if_timer = 1; 1284 } 1285 1286 if (sc->sc_scan_timer) { 1287 if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT && 1288 sc->sc_firmware_type == WI_INTERSIL) { 1289 DPRINTF(("wi_watchdog: inquire scan\n")); 1290 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); 1291 } 1292 if (sc->sc_scan_timer) 1293 ifp->if_timer = 1; 1294 } 1295 1296 /* TODO: rate control */ 1297 ieee80211_watchdog(&sc->sc_ic); 1298} 1299 1300static int 1301wi_ioctl_enter(struct wi_softc *sc) 1302{ 1303 int rc = 0; 1304 1305 mutex_enter(&sc->sc_ioctl_mtx); 1306 sc->sc_ioctl_nwait++; 1307 while (sc->sc_ioctl_lwp != NULL && sc->sc_ioctl_lwp != curlwp) { 1308 rc = sc->sc_ioctl_gone 1309 ? ENXIO 1310 : cv_wait_sig(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx); 1311 if (rc != 0) 1312 break; 1313 } 1314 if (rc == 0) { 1315 sc->sc_ioctl_lwp = curlwp; 1316 sc->sc_ioctl_depth++; 1317 } 1318 if (--sc->sc_ioctl_nwait == 0) 1319 cv_signal(&sc->sc_ioctl_cv); 1320 mutex_exit(&sc->sc_ioctl_mtx); 1321 return rc; 1322} 1323 1324static void 1325wi_ioctl_exit(struct wi_softc *sc) 1326{ 1327 KASSERT(sc->sc_ioctl_lwp == curlwp); 1328 mutex_enter(&sc->sc_ioctl_mtx); 1329 if (--sc->sc_ioctl_depth == 0) { 1330 sc->sc_ioctl_lwp = NULL; 1331 cv_signal(&sc->sc_ioctl_cv); 1332 } 1333 mutex_exit(&sc->sc_ioctl_mtx); 1334} 1335 1336static void 1337wi_ioctl_init(struct wi_softc *sc) 1338{ 1339 mutex_init(&sc->sc_ioctl_mtx, MUTEX_DEFAULT, IPL_NONE); 1340 cv_init(&sc->sc_ioctl_cv, device_xname(sc->sc_dev)); 1341} 1342 1343static void 1344wi_ioctl_drain(struct wi_softc *sc) 1345{ 1346 wi_ioctl_enter(sc); 1347 1348 mutex_enter(&sc->sc_ioctl_mtx); 1349 sc->sc_ioctl_gone = true; 1350 cv_broadcast(&sc->sc_ioctl_cv); 1351 while (sc->sc_ioctl_nwait != 0) 1352 cv_wait(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx); 1353 mutex_exit(&sc->sc_ioctl_mtx); 1354 1355 wi_ioctl_exit(sc); 1356 1357 mutex_destroy(&sc->sc_ioctl_mtx); 1358 cv_destroy(&sc->sc_ioctl_cv); 1359} 1360 1361STATIC int 1362wi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1363{ 1364 struct wi_softc *sc = ifp->if_softc; 1365 struct ieee80211com *ic = &sc->sc_ic; 1366 struct ifreq *ifr = (struct ifreq *)data; 1367 int s, error = 0; 1368 1369 if (!device_is_active(sc->sc_dev)) 1370 return ENXIO; 1371 1372 s = splnet(); 1373 1374 if ((error = wi_ioctl_enter(sc)) != 0) 1375 return error; 1376 1377 switch (cmd) { 1378 case SIOCSIFFLAGS: 1379 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 1380 break; 1381 /* 1382 * Can't do promisc and hostap at the same time. If all that's 1383 * changing is the promisc flag, try to short-circuit a call to 1384 * wi_init() by just setting PROMISC in the hardware. 1385 */ 1386 if (ifp->if_flags & IFF_UP) { 1387 if (sc->sc_enabled) { 1388 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 1389 (ifp->if_flags & IFF_PROMISC) != 0) 1390 wi_write_val(sc, WI_RID_PROMISC, 1); 1391 else 1392 wi_write_val(sc, WI_RID_PROMISC, 0); 1393 } else 1394 error = wi_init(ifp); 1395 } else if (sc->sc_enabled) 1396 wi_stop(ifp, 1); 1397 break; 1398 case SIOCSIFMEDIA: 1399 case SIOCGIFMEDIA: 1400 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1401 break; 1402 case SIOCADDMULTI: 1403 case SIOCDELMULTI: 1404 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 1405 if (ifp->if_flags & IFF_RUNNING) { 1406 /* do not rescan */ 1407 error = wi_write_multi(sc); 1408 } else 1409 error = 0; 1410 } 1411 break; 1412 case SIOCGIFGENERIC: 1413 error = wi_get_cfg(ifp, cmd, data); 1414 break; 1415 case SIOCSIFGENERIC: 1416 error = kauth_authorize_network(curlwp->l_cred, 1417 KAUTH_NETWORK_INTERFACE, 1418 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd), 1419 NULL); 1420 if (error) 1421 break; 1422 error = wi_set_cfg(ifp, cmd, data); 1423 if (error == ENETRESET) { 1424 if (ifp->if_flags & IFF_RUNNING) 1425 error = wi_init(ifp); 1426 else 1427 error = 0; 1428 } 1429 break; 1430 case SIOCS80211BSSID: 1431 if (sc->sc_firmware_type == WI_LUCENT) { 1432 error = ENODEV; 1433 break; 1434 } 1435 /* fall through */ 1436 default: 1437 ic->ic_flags |= sc->sc_ic_flags; 1438 error = ieee80211_ioctl(&sc->sc_ic, cmd, data); 1439 sc->sc_ic_flags = ic->ic_flags & IEEE80211_F_DROPUNENC; 1440 if (error == ENETRESET) { 1441 if (sc->sc_enabled) 1442 error = wi_init(ifp); 1443 else 1444 error = 0; 1445 } 1446 break; 1447 } 1448 wi_mend_flags(sc, ic->ic_state); 1449 wi_ioctl_exit(sc); 1450 splx(s); 1451 return error; 1452} 1453 1454STATIC int 1455wi_media_change(struct ifnet *ifp) 1456{ 1457 struct wi_softc *sc = ifp->if_softc; 1458 struct ieee80211com *ic = &sc->sc_ic; 1459 int error; 1460 1461 error = ieee80211_media_change(ifp); 1462 if (error == ENETRESET) { 1463 if (sc->sc_enabled) 1464 error = wi_init(ifp); 1465 else 1466 error = 0; 1467 } 1468 ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media); 1469 1470 return error; 1471} 1472 1473STATIC void 1474wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1475{ 1476 struct wi_softc *sc = ifp->if_softc; 1477 struct ieee80211com *ic = &sc->sc_ic; 1478 u_int16_t val; 1479 int rate; 1480 1481 if (sc->sc_enabled == 0) { 1482 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 1483 imr->ifm_status = 0; 1484 return; 1485 } 1486 1487 imr->ifm_status = IFM_AVALID; 1488 imr->ifm_active = IFM_IEEE80211; 1489 if (ic->ic_state == IEEE80211_S_RUN && 1490 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0) 1491 imr->ifm_status |= IFM_ACTIVE; 1492 if (wi_read_xrid(sc, WI_RID_CUR_TX_RATE, &val, sizeof(val)) == 0) { 1493 /* convert to 802.11 rate */ 1494 val = le16toh(val); 1495 rate = val * 2; 1496 if (sc->sc_firmware_type == WI_LUCENT) { 1497 if (rate == 10) 1498 rate = 11; /* 5.5Mbps */ 1499 } else { 1500 if (rate == 4*2) 1501 rate = 11; /* 5.5Mbps */ 1502 else if (rate == 8*2) 1503 rate = 22; /* 11Mbps */ 1504 } 1505 } else 1506 rate = 0; 1507 imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); 1508 switch (ic->ic_opmode) { 1509 case IEEE80211_M_STA: 1510 break; 1511 case IEEE80211_M_IBSS: 1512 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1513 break; 1514 case IEEE80211_M_AHDEMO: 1515 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0; 1516 break; 1517 case IEEE80211_M_HOSTAP: 1518 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1519 break; 1520 case IEEE80211_M_MONITOR: 1521 imr->ifm_active |= IFM_IEEE80211_MONITOR; 1522 break; 1523 } 1524} 1525 1526STATIC struct ieee80211_node * 1527wi_node_alloc(struct ieee80211_node_table *nt) 1528{ 1529 struct wi_node *wn = 1530 malloc(sizeof(struct wi_node), M_DEVBUF, M_NOWAIT | M_ZERO); 1531 return wn ? &wn->wn_node : NULL; 1532} 1533 1534STATIC void 1535wi_node_free(struct ieee80211_node *ni) 1536{ 1537 struct wi_softc *sc = ni->ni_ic->ic_ifp->if_softc; 1538 int i; 1539 1540 for (i = 0; i < WI_NTXRSS; i++) { 1541 if (sc->sc_rssd[i].rd_desc.id_node == ni) 1542 sc->sc_rssd[i].rd_desc.id_node = NULL; 1543 } 1544 free(ni, M_DEVBUF); 1545} 1546 1547STATIC void 1548wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) 1549{ 1550 struct ieee80211com *ic = &sc->sc_ic; 1551 struct ieee80211_node *ni = ic->ic_bss; 1552 struct ifnet *ifp = &sc->sc_if; 1553 1554 if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid)) 1555 return; 1556 1557 DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid))); 1558 DPRINTF(("%s ?\n", ether_sprintf(new_bssid))); 1559 1560 /* In promiscuous mode, the BSSID field is not a reliable 1561 * indicator of the firmware's BSSID. Damp spurious 1562 * change-of-BSSID indications. 1563 */ 1564 if ((ifp->if_flags & IFF_PROMISC) != 0 && 1565 !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns, 1566 WI_MAX_FALSE_SYNS)) 1567 return; 1568 1569 sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1); 1570 /* 1571 * XXX hack; we should create a new node with the new bssid 1572 * and replace the existing ic_bss with it but since we don't 1573 * process management frames to collect state we cheat by 1574 * reusing the existing node as we know wi_newstate will be 1575 * called and it will overwrite the node state. 1576 */ 1577 ieee80211_sta_join(ic, ieee80211_ref_node(ni)); 1578} 1579 1580static inline void 1581wi_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni, 1582 struct ieee80211_frame *wh, int rssi) 1583{ 1584 struct wi_node *wn; 1585 1586 if (ni == NULL) { 1587 printf("%s: null node", __func__); 1588 return; 1589 } 1590 1591 wn = (void*)ni; 1592 ieee80211_rssadapt_input(ic, ni, &wn->wn_rssadapt, rssi); 1593} 1594 1595STATIC void 1596wi_rx_intr(struct wi_softc *sc) 1597{ 1598 struct ieee80211com *ic = &sc->sc_ic; 1599 struct ifnet *ifp = &sc->sc_if; 1600 struct ieee80211_node *ni; 1601 struct wi_frame frmhdr; 1602 struct mbuf *m; 1603 struct ieee80211_frame *wh; 1604 int fid, len, off, rssi; 1605 u_int8_t dir; 1606 u_int16_t status; 1607 u_int32_t rstamp; 1608 1609 fid = CSR_READ_2(sc, WI_RX_FID); 1610 1611 /* First read in the frame header */ 1612 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) { 1613 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1614 __func__, fid); 1615 ifp->if_ierrors++; 1616 return; 1617 } 1618 1619 if (IFF_DUMPPKTS(ifp)) 1620 wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal); 1621 1622 /* 1623 * Drop undecryptable or packets with receive errors here 1624 */ 1625 status = le16toh(frmhdr.wi_status); 1626 if ((status & WI_STAT_ERRSTAT) != 0 && 1627 ic->ic_opmode != IEEE80211_M_MONITOR) { 1628 ifp->if_ierrors++; 1629 DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status)); 1630 return; 1631 } 1632 rssi = frmhdr.wi_rx_signal; 1633 rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) | 1634 le16toh(frmhdr.wi_rx_tstamp1); 1635 1636 len = le16toh(frmhdr.wi_dat_len); 1637 off = ALIGN(sizeof(struct ieee80211_frame)); 1638 1639 /* Sometimes the PRISM2.x returns bogusly large frames. Except 1640 * in monitor mode, just throw them away. 1641 */ 1642 if (off + len > MCLBYTES) { 1643 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 1644 ifp->if_ierrors++; 1645 DPRINTF(("wi_rx_intr: oversized packet\n")); 1646 return; 1647 } else 1648 len = 0; 1649 } 1650 1651 MGETHDR(m, M_DONTWAIT, MT_DATA); 1652 if (m == NULL) { 1653 ifp->if_ierrors++; 1654 DPRINTF(("wi_rx_intr: MGET failed\n")); 1655 return; 1656 } 1657 if (off + len > MHLEN) { 1658 MCLGET(m, M_DONTWAIT); 1659 if ((m->m_flags & M_EXT) == 0) { 1660 m_freem(m); 1661 ifp->if_ierrors++; 1662 DPRINTF(("wi_rx_intr: MCLGET failed\n")); 1663 return; 1664 } 1665 } 1666 1667 m->m_data += off - sizeof(struct ieee80211_frame); 1668 memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame)); 1669 wi_read_bap(sc, fid, sizeof(frmhdr), 1670 m->m_data + sizeof(struct ieee80211_frame), len); 1671 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len; 1672 m->m_pkthdr.rcvif = ifp; 1673 1674 wh = mtod(m, struct ieee80211_frame *); 1675 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1676 /* 1677 * WEP is decrypted by hardware. Clear WEP bit 1678 * header for ieee80211_input(). 1679 */ 1680 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1681 } 1682 if (sc->sc_drvbpf) { 1683 struct wi_rx_radiotap_header *tap = &sc->sc_rxtap; 1684 1685 tap->wr_rate = frmhdr.wi_rx_rate / 5; 1686 tap->wr_antsignal = frmhdr.wi_rx_signal; 1687 tap->wr_antnoise = frmhdr.wi_rx_silence; 1688 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1689 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1690 if (frmhdr.wi_status & WI_STAT_PCF) 1691 tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP; 1692 1693 /* XXX IEEE80211_RADIOTAP_F_WEP */ 1694 bpf_mtap2(sc->sc_drvbpf, tap, tap->wr_ihdr.it_len, m); 1695 } 1696 1697 /* synchronize driver's BSSID with firmware's BSSID */ 1698 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 1699 if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS) 1700 wi_sync_bssid(sc, wh->i_addr3); 1701 1702 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); 1703 1704 ieee80211_input(ic, m, ni, rssi, rstamp); 1705 1706 wi_rssadapt_input(ic, ni, wh, rssi); 1707 1708 /* 1709 * The frame may have caused the node to be marked for 1710 * reclamation (e.g. in response to a DEAUTH message) 1711 * so use release_node here instead of unref_node. 1712 */ 1713 ieee80211_free_node(ni); 1714} 1715 1716STATIC void 1717wi_tx_ex_intr(struct wi_softc *sc) 1718{ 1719 struct ieee80211com *ic = &sc->sc_ic; 1720 struct ifnet *ifp = &sc->sc_if; 1721 struct ieee80211_node *ni; 1722 struct ieee80211_rssdesc *id; 1723 struct wi_rssdesc *rssd; 1724 struct wi_frame frmhdr; 1725 int fid; 1726 u_int16_t status; 1727 1728 fid = CSR_READ_2(sc, WI_TX_CMP_FID); 1729 /* Read in the frame header */ 1730 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) { 1731 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1732 __func__, fid); 1733 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1734 &sc->sc_txpending); 1735 goto out; 1736 } 1737 1738 if (frmhdr.wi_tx_idx >= WI_NTXRSS) { 1739 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n", 1740 __func__, frmhdr.wi_tx_idx); 1741 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1742 &sc->sc_txpending); 1743 goto out; 1744 } 1745 1746 status = le16toh(frmhdr.wi_status); 1747 1748 /* 1749 * Spontaneous station disconnects appear as xmit 1750 * errors. Don't announce them and/or count them 1751 * as an output error. 1752 */ 1753 if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) { 1754 aprint_error_dev(sc->sc_dev, "tx failed"); 1755 if (status & WI_TXSTAT_RET_ERR) 1756 printf(", retry limit exceeded"); 1757 if (status & WI_TXSTAT_AGED_ERR) 1758 printf(", max transmit lifetime exceeded"); 1759 if (status & WI_TXSTAT_DISCONNECT) 1760 printf(", port disconnected"); 1761 if (status & WI_TXSTAT_FORM_ERR) 1762 printf(", invalid format (data len %u src %s)", 1763 le16toh(frmhdr.wi_dat_len), 1764 ether_sprintf(frmhdr.wi_ehdr.ether_shost)); 1765 if (status & ~0xf) 1766 printf(", status=0x%x", status); 1767 printf("\n"); 1768 } 1769 ifp->if_oerrors++; 1770 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx]; 1771 id = &rssd->rd_desc; 1772 if ((status & WI_TXSTAT_RET_ERR) != 0) 1773 wi_lower_rate(ic, id); 1774 1775 ni = id->id_node; 1776 id->id_node = NULL; 1777 1778 if (ni == NULL) { 1779 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n", 1780 __func__, frmhdr.wi_tx_idx); 1781 goto out; 1782 } 1783 1784 if (sc->sc_txpending[id->id_rateidx]-- == 0) { 1785 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound", 1786 __func__, id->id_rateidx); 1787 sc->sc_txpending[id->id_rateidx] = 0; 1788 } 1789 if (ni != NULL) 1790 ieee80211_free_node(ni); 1791 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next); 1792out: 1793 ifp->if_flags &= ~IFF_OACTIVE; 1794} 1795 1796STATIC void 1797wi_txalloc_intr(struct wi_softc *sc) 1798{ 1799 int fid, cur; 1800 1801 fid = CSR_READ_2(sc, WI_ALLOC_FID); 1802 1803 cur = sc->sc_txalloc; 1804#ifdef DIAGNOSTIC 1805 if (sc->sc_txstarted == 0) { 1806 printf("%s: spurious alloc %x != %x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1807 device_xname(sc->sc_dev), fid, sc->sc_txd[cur].d_fid, cur, 1808 sc->sc_txqueue, sc->sc_txstart, sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1809 return; 1810 } 1811#endif 1812 --sc->sc_txstarted; 1813 ++sc->sc_txalloced; 1814 sc->sc_txd[cur].d_fid = fid; 1815 sc->sc_txalloc = (cur + 1) % WI_NTXBUF; 1816#ifdef WI_RING_DEBUG 1817 printf("%s: alloc %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1818 device_xname(sc->sc_dev), fid, 1819 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1820 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1821#endif 1822} 1823 1824STATIC void 1825wi_cmd_intr(struct wi_softc *sc) 1826{ 1827 struct ifnet *ifp = &sc->sc_if; 1828 1829 if (sc->sc_invalid) 1830 return; 1831#ifdef WI_DEBUG 1832 if (wi_debug > 1) 1833 printf("%s: %d txcmds outstanding\n", __func__, sc->sc_txcmds); 1834#endif 1835 KASSERT(sc->sc_txcmds > 0); 1836 1837 --sc->sc_txcmds; 1838 1839 if (--sc->sc_txqueued == 0) { 1840 sc->sc_tx_timer = 0; 1841 ifp->if_flags &= ~IFF_OACTIVE; 1842#ifdef WI_RING_DEBUG 1843 printf("%s: cmd , alloc %d queue %d start %d alloced %d queued %d started %d\n", 1844 device_xname(sc->sc_dev), 1845 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1846 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1847#endif 1848 } else 1849 wi_push_packet(sc); 1850} 1851 1852STATIC void 1853wi_push_packet(struct wi_softc *sc) 1854{ 1855 struct ifnet *ifp = &sc->sc_if; 1856 int cur, fid; 1857 1858 cur = sc->sc_txstart; 1859 fid = sc->sc_txd[cur].d_fid; 1860 1861 KASSERT(sc->sc_txcmds == 0); 1862 1863 if (wi_cmd_start(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) { 1864 aprint_error_dev(sc->sc_dev, "xmit failed\n"); 1865 /* XXX ring might have a hole */ 1866 } 1867 1868 if (sc->sc_txcmds++ > 0) 1869 printf("%s: %d tx cmds pending!!!\n", __func__, sc->sc_txcmds); 1870 1871 ++sc->sc_txstarted; 1872#ifdef DIAGNOSTIC 1873 if (sc->sc_txstarted > WI_NTXBUF) 1874 aprint_error_dev(sc->sc_dev, "too many buffers started\n"); 1875#endif 1876 sc->sc_txstart = (cur + 1) % WI_NTXBUF; 1877 sc->sc_tx_timer = 5; 1878 ifp->if_timer = 1; 1879#ifdef WI_RING_DEBUG 1880 printf("%s: push %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1881 device_xname(sc->sc_dev), fid, 1882 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1883 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1884#endif 1885} 1886 1887STATIC void 1888wi_tx_intr(struct wi_softc *sc) 1889{ 1890 struct ieee80211com *ic = &sc->sc_ic; 1891 struct ifnet *ifp = &sc->sc_if; 1892 struct ieee80211_node *ni; 1893 struct ieee80211_rssdesc *id; 1894 struct wi_rssdesc *rssd; 1895 struct wi_frame frmhdr; 1896 int fid; 1897 1898 fid = CSR_READ_2(sc, WI_TX_CMP_FID); 1899 /* Read in the frame header */ 1900 if (wi_read_bap(sc, fid, offsetof(struct wi_frame, wi_tx_swsup2), 1901 &frmhdr.wi_tx_swsup2, 2) != 0) { 1902 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1903 __func__, fid); 1904 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1905 &sc->sc_txpending); 1906 goto out; 1907 } 1908 1909 if (frmhdr.wi_tx_idx >= WI_NTXRSS) { 1910 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n", 1911 __func__, frmhdr.wi_tx_idx); 1912 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1913 &sc->sc_txpending); 1914 goto out; 1915 } 1916 1917 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx]; 1918 id = &rssd->rd_desc; 1919 wi_raise_rate(ic, id); 1920 1921 ni = id->id_node; 1922 id->id_node = NULL; 1923 1924 if (ni == NULL) { 1925 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n", 1926 __func__, frmhdr.wi_tx_idx); 1927 goto out; 1928 } 1929 1930 if (sc->sc_txpending[id->id_rateidx]-- == 0) { 1931 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound", 1932 __func__, id->id_rateidx); 1933 sc->sc_txpending[id->id_rateidx] = 0; 1934 } 1935 if (ni != NULL) 1936 ieee80211_free_node(ni); 1937 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next); 1938out: 1939 ifp->if_flags &= ~IFF_OACTIVE; 1940} 1941 1942STATIC void 1943wi_info_intr(struct wi_softc *sc) 1944{ 1945 struct ieee80211com *ic = &sc->sc_ic; 1946 struct ifnet *ifp = &sc->sc_if; 1947 int i, fid, len, off; 1948 u_int16_t ltbuf[2]; 1949 u_int16_t stat; 1950 u_int32_t *ptr; 1951 1952 fid = CSR_READ_2(sc, WI_INFO_FID); 1953 wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf)); 1954 1955 switch (le16toh(ltbuf[1])) { 1956 1957 case WI_INFO_LINK_STAT: 1958 wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat)); 1959 DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat))); 1960 switch (le16toh(stat)) { 1961 case CONNECTED: 1962 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 1963 if (ic->ic_state == IEEE80211_S_RUN && 1964 ic->ic_opmode != IEEE80211_M_IBSS) 1965 break; 1966 /* FALLTHROUGH */ 1967 case AP_CHANGE: 1968 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 1969 break; 1970 case AP_IN_RANGE: 1971 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 1972 break; 1973 case AP_OUT_OF_RANGE: 1974 if (sc->sc_firmware_type == WI_SYMBOL && 1975 sc->sc_scan_timer > 0) { 1976 if (wi_cmd(sc, WI_CMD_INQUIRE, 1977 WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0) 1978 sc->sc_scan_timer = 0; 1979 break; 1980 } 1981 if (ic->ic_opmode == IEEE80211_M_STA) 1982 sc->sc_flags |= WI_FLAGS_OUTRANGE; 1983 break; 1984 case DISCONNECTED: 1985 case ASSOC_FAILED: 1986 if (ic->ic_opmode == IEEE80211_M_STA) 1987 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1988 break; 1989 } 1990 break; 1991 1992 case WI_INFO_COUNTERS: 1993 /* some card versions have a larger stats structure */ 1994 len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4); 1995 ptr = (u_int32_t *)&sc->sc_stats; 1996 off = sizeof(ltbuf); 1997 for (i = 0; i < len; i++, off += 2, ptr++) { 1998 wi_read_bap(sc, fid, off, &stat, sizeof(stat)); 1999 stat = le16toh(stat); 2000#ifdef WI_HERMES_STATS_WAR 2001 if (stat & 0xf000) 2002 stat = ~stat; 2003#endif 2004 *ptr += stat; 2005 } 2006 ifp->if_collisions = sc->sc_stats.wi_tx_single_retries + 2007 sc->sc_stats.wi_tx_multi_retries + 2008 sc->sc_stats.wi_tx_retry_limit; 2009 break; 2010 2011 case WI_INFO_SCAN_RESULTS: 2012 case WI_INFO_HOST_SCAN_RESULTS: 2013 wi_scan_result(sc, fid, le16toh(ltbuf[0])); 2014 break; 2015 2016 default: 2017 DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid, 2018 le16toh(ltbuf[1]), le16toh(ltbuf[0]))); 2019 break; 2020 } 2021} 2022 2023STATIC int 2024wi_write_multi(struct wi_softc *sc) 2025{ 2026 struct ifnet *ifp = &sc->sc_if; 2027 int n; 2028 struct wi_mcast mlist; 2029 struct ether_multi *enm; 2030 struct ether_multistep estep; 2031 2032 if ((ifp->if_flags & IFF_PROMISC) != 0) { 2033allmulti: 2034 ifp->if_flags |= IFF_ALLMULTI; 2035 memset(&mlist, 0, sizeof(mlist)); 2036 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, 2037 sizeof(mlist)); 2038 } 2039 2040 n = 0; 2041 ETHER_FIRST_MULTI(estep, &sc->sc_ec, enm); 2042 while (enm != NULL) { 2043 /* Punt on ranges or too many multicast addresses. */ 2044 if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi) || 2045 n >= sizeof(mlist) / sizeof(mlist.wi_mcast[0])) 2046 goto allmulti; 2047 2048 IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], enm->enm_addrlo); 2049 n++; 2050 ETHER_NEXT_MULTI(estep, enm); 2051 } 2052 ifp->if_flags &= ~IFF_ALLMULTI; 2053 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, 2054 IEEE80211_ADDR_LEN * n); 2055} 2056 2057 2058STATIC void 2059wi_read_nicid(struct wi_softc *sc) 2060{ 2061 struct wi_card_ident *id; 2062 char *p; 2063 int len; 2064 u_int16_t ver[4]; 2065 2066 /* getting chip identity */ 2067 memset(ver, 0, sizeof(ver)); 2068 len = sizeof(ver); 2069 wi_read_rid(sc, WI_RID_CARD_ID, ver, &len); 2070 printf("%s: using ", device_xname(sc->sc_dev)); 2071DPRINTF2(("wi_read_nicid: CARD_ID: %x %x %x %x\n", le16toh(ver[0]), le16toh(ver[1]), le16toh(ver[2]), le16toh(ver[3]))); 2072 2073 sc->sc_firmware_type = WI_NOTYPE; 2074 for (id = wi_card_ident; id->card_name != NULL; id++) { 2075 if (le16toh(ver[0]) == id->card_id) { 2076 printf("%s", id->card_name); 2077 sc->sc_firmware_type = id->firm_type; 2078 break; 2079 } 2080 } 2081 if (sc->sc_firmware_type == WI_NOTYPE) { 2082 if (le16toh(ver[0]) & 0x8000) { 2083 printf("Unknown PRISM2 chip"); 2084 sc->sc_firmware_type = WI_INTERSIL; 2085 } else { 2086 printf("Unknown Lucent chip"); 2087 sc->sc_firmware_type = WI_LUCENT; 2088 } 2089 } 2090 2091 /* get primary firmware version (Only Prism chips) */ 2092 if (sc->sc_firmware_type != WI_LUCENT) { 2093 memset(ver, 0, sizeof(ver)); 2094 len = sizeof(ver); 2095 wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len); 2096 sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 + 2097 le16toh(ver[3]) * 100 + le16toh(ver[1]); 2098 } 2099 2100 /* get station firmware version */ 2101 memset(ver, 0, sizeof(ver)); 2102 len = sizeof(ver); 2103 wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len); 2104 sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 + 2105 le16toh(ver[3]) * 100 + le16toh(ver[1]); 2106 if (sc->sc_firmware_type == WI_INTERSIL && 2107 (sc->sc_sta_firmware_ver == 10102 || 2108 sc->sc_sta_firmware_ver == 20102)) { 2109 char ident[12]; 2110 memset(ident, 0, sizeof(ident)); 2111 len = sizeof(ident); 2112 /* value should be the format like "V2.00-11" */ 2113 if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 && 2114 *(p = (char *)ident) >= 'A' && 2115 p[2] == '.' && p[5] == '-' && p[8] == '\0') { 2116 sc->sc_firmware_type = WI_SYMBOL; 2117 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 + 2118 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + 2119 (p[6] - '0') * 10 + (p[7] - '0'); 2120 } 2121 } 2122 2123 printf("\n%s: %s Firmware: ", device_xname(sc->sc_dev), 2124 sc->sc_firmware_type == WI_LUCENT ? "Lucent" : 2125 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")); 2126 if (sc->sc_firmware_type != WI_LUCENT) /* XXX */ 2127 printf("Primary (%u.%u.%u), ", 2128 sc->sc_pri_firmware_ver / 10000, 2129 (sc->sc_pri_firmware_ver % 10000) / 100, 2130 sc->sc_pri_firmware_ver % 100); 2131 printf("Station (%u.%u.%u)\n", 2132 sc->sc_sta_firmware_ver / 10000, 2133 (sc->sc_sta_firmware_ver % 10000) / 100, 2134 sc->sc_sta_firmware_ver % 100); 2135} 2136 2137STATIC int 2138wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen) 2139{ 2140 struct wi_ssid ssid; 2141 2142 if (buflen > IEEE80211_NWID_LEN) 2143 return ENOBUFS; 2144 memset(&ssid, 0, sizeof(ssid)); 2145 ssid.wi_len = htole16(buflen); 2146 memcpy(ssid.wi_ssid, buf, buflen); 2147 return wi_write_rid(sc, rid, &ssid, sizeof(ssid)); 2148} 2149 2150STATIC int 2151wi_get_cfg(struct ifnet *ifp, u_long cmd, void *data) 2152{ 2153 struct wi_softc *sc = ifp->if_softc; 2154 struct ieee80211com *ic = &sc->sc_ic; 2155 struct ifreq *ifr = (struct ifreq *)data; 2156 struct wi_req wreq; 2157 int len, n, error; 2158 2159 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 2160 if (error) 2161 return error; 2162 len = (wreq.wi_len - 1) * 2; 2163 if (len < sizeof(u_int16_t)) 2164 return ENOSPC; 2165 if (len > sizeof(wreq.wi_val)) 2166 len = sizeof(wreq.wi_val); 2167 2168 switch (wreq.wi_type) { 2169 2170 case WI_RID_IFACE_STATS: 2171 memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats)); 2172 if (len < sizeof(sc->sc_stats)) 2173 error = ENOSPC; 2174 else 2175 len = sizeof(sc->sc_stats); 2176 break; 2177 2178 case WI_RID_ENCRYPTION: 2179 case WI_RID_TX_CRYPT_KEY: 2180 case WI_RID_DEFLT_CRYPT_KEYS: 2181 case WI_RID_TX_RATE: 2182 return ieee80211_cfgget(ic, cmd, data); 2183 2184 case WI_RID_MICROWAVE_OVEN: 2185 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) { 2186 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2187 &len); 2188 break; 2189 } 2190 wreq.wi_val[0] = htole16(sc->sc_microwave_oven); 2191 len = sizeof(u_int16_t); 2192 break; 2193 2194 case WI_RID_DBM_ADJUST: 2195 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) { 2196 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2197 &len); 2198 break; 2199 } 2200 wreq.wi_val[0] = htole16(sc->sc_dbm_offset); 2201 len = sizeof(u_int16_t); 2202 break; 2203 2204 case WI_RID_ROAMING_MODE: 2205 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) { 2206 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2207 &len); 2208 break; 2209 } 2210 wreq.wi_val[0] = htole16(sc->sc_roaming_mode); 2211 len = sizeof(u_int16_t); 2212 break; 2213 2214 case WI_RID_SYSTEM_SCALE: 2215 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) { 2216 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2217 &len); 2218 break; 2219 } 2220 wreq.wi_val[0] = htole16(sc->sc_system_scale); 2221 len = sizeof(u_int16_t); 2222 break; 2223 2224 case WI_RID_FRAG_THRESH: 2225 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) { 2226 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2227 &len); 2228 break; 2229 } 2230 wreq.wi_val[0] = htole16(sc->sc_frag_thresh); 2231 len = sizeof(u_int16_t); 2232 break; 2233 2234 case WI_RID_READ_APS: 2235#ifndef IEEE80211_NO_HOSTAP 2236 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 2237 return ieee80211_cfgget(ic, cmd, data); 2238#endif /* !IEEE80211_NO_HOSTAP */ 2239 if (sc->sc_scan_timer > 0) { 2240 error = EINPROGRESS; 2241 break; 2242 } 2243 n = sc->sc_naps; 2244 if (len < sizeof(n)) { 2245 error = ENOSPC; 2246 break; 2247 } 2248 if (len < sizeof(n) + sizeof(struct wi_apinfo) * n) 2249 n = (len - sizeof(n)) / sizeof(struct wi_apinfo); 2250 len = sizeof(n) + sizeof(struct wi_apinfo) * n; 2251 memcpy(wreq.wi_val, &n, sizeof(n)); 2252 memcpy((char *)wreq.wi_val + sizeof(n), sc->sc_aps, 2253 sizeof(struct wi_apinfo) * n); 2254 break; 2255 2256 default: 2257 if (sc->sc_enabled) { 2258 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2259 &len); 2260 break; 2261 } 2262 switch (wreq.wi_type) { 2263 case WI_RID_MAX_DATALEN: 2264 wreq.wi_val[0] = htole16(sc->sc_max_datalen); 2265 len = sizeof(u_int16_t); 2266 break; 2267 case WI_RID_FRAG_THRESH: 2268 wreq.wi_val[0] = htole16(sc->sc_frag_thresh); 2269 len = sizeof(u_int16_t); 2270 break; 2271 case WI_RID_RTS_THRESH: 2272 wreq.wi_val[0] = htole16(sc->sc_rts_thresh); 2273 len = sizeof(u_int16_t); 2274 break; 2275 case WI_RID_CNFAUTHMODE: 2276 wreq.wi_val[0] = htole16(sc->sc_cnfauthmode); 2277 len = sizeof(u_int16_t); 2278 break; 2279 case WI_RID_NODENAME: 2280 if (len < sc->sc_nodelen + sizeof(u_int16_t)) { 2281 error = ENOSPC; 2282 break; 2283 } 2284 len = sc->sc_nodelen + sizeof(u_int16_t); 2285 wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2); 2286 memcpy(&wreq.wi_val[1], sc->sc_nodename, 2287 sc->sc_nodelen); 2288 break; 2289 default: 2290 return ieee80211_cfgget(ic, cmd, data); 2291 } 2292 break; 2293 } 2294 if (error) 2295 return error; 2296 wreq.wi_len = (len + 1) / 2 + 1; 2297 return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2); 2298} 2299 2300STATIC int 2301wi_set_cfg(struct ifnet *ifp, u_long cmd, void *data) 2302{ 2303 struct wi_softc *sc = ifp->if_softc; 2304 struct ieee80211com *ic = &sc->sc_ic; 2305 struct ifreq *ifr = (struct ifreq *)data; 2306 struct ieee80211_rateset *rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; 2307 struct wi_req wreq; 2308 struct mbuf *m; 2309 int i, len, error; 2310 2311 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 2312 if (error) 2313 return error; 2314 len = (wreq.wi_len - 1) * 2; 2315 switch (wreq.wi_type) { 2316 case WI_RID_MAC_NODE: 2317 /* XXX convert to SIOCALIFADDR, AF_LINK, IFLR_ACTIVE */ 2318 (void)memcpy(ic->ic_myaddr, wreq.wi_val, ETHER_ADDR_LEN); 2319 if_set_sadl(ifp, ic->ic_myaddr, ETHER_ADDR_LEN, false); 2320 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, 2321 IEEE80211_ADDR_LEN); 2322 break; 2323 2324 case WI_RID_DBM_ADJUST: 2325 return ENODEV; 2326 2327 case WI_RID_NODENAME: 2328 if (le16toh(wreq.wi_val[0]) * 2 > len || 2329 le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) { 2330 error = ENOSPC; 2331 break; 2332 } 2333 if (sc->sc_enabled) { 2334 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, 2335 len); 2336 if (error) 2337 break; 2338 } 2339 sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2; 2340 memcpy(sc->sc_nodename, &wreq.wi_val[1], sc->sc_nodelen); 2341 break; 2342 2343 case WI_RID_MICROWAVE_OVEN: 2344 case WI_RID_ROAMING_MODE: 2345 case WI_RID_SYSTEM_SCALE: 2346 case WI_RID_FRAG_THRESH: 2347 if (wreq.wi_type == WI_RID_MICROWAVE_OVEN && 2348 (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0) 2349 break; 2350 if (wreq.wi_type == WI_RID_ROAMING_MODE && 2351 (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0) 2352 break; 2353 if (wreq.wi_type == WI_RID_SYSTEM_SCALE && 2354 (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0) 2355 break; 2356 if (wreq.wi_type == WI_RID_FRAG_THRESH && 2357 (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0) 2358 break; 2359 /* FALLTHROUGH */ 2360 case WI_RID_RTS_THRESH: 2361 case WI_RID_CNFAUTHMODE: 2362 case WI_RID_MAX_DATALEN: 2363 if (sc->sc_enabled) { 2364 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, 2365 sizeof(u_int16_t)); 2366 if (error) 2367 break; 2368 } 2369 switch (wreq.wi_type) { 2370 case WI_RID_FRAG_THRESH: 2371 sc->sc_frag_thresh = le16toh(wreq.wi_val[0]); 2372 break; 2373 case WI_RID_RTS_THRESH: 2374 sc->sc_rts_thresh = le16toh(wreq.wi_val[0]); 2375 break; 2376 case WI_RID_MICROWAVE_OVEN: 2377 sc->sc_microwave_oven = le16toh(wreq.wi_val[0]); 2378 break; 2379 case WI_RID_ROAMING_MODE: 2380 sc->sc_roaming_mode = le16toh(wreq.wi_val[0]); 2381 break; 2382 case WI_RID_SYSTEM_SCALE: 2383 sc->sc_system_scale = le16toh(wreq.wi_val[0]); 2384 break; 2385 case WI_RID_CNFAUTHMODE: 2386 sc->sc_cnfauthmode = le16toh(wreq.wi_val[0]); 2387 break; 2388 case WI_RID_MAX_DATALEN: 2389 sc->sc_max_datalen = le16toh(wreq.wi_val[0]); 2390 break; 2391 } 2392 break; 2393 2394 case WI_RID_TX_RATE: 2395 switch (le16toh(wreq.wi_val[0])) { 2396 case 3: 2397 ic->ic_fixed_rate = -1; 2398 break; 2399 default: 2400 for (i = 0; i < IEEE80211_RATE_SIZE; i++) { 2401 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) 2402 / 2 == le16toh(wreq.wi_val[0])) 2403 break; 2404 } 2405 if (i == IEEE80211_RATE_SIZE) 2406 return EINVAL; 2407 ic->ic_fixed_rate = i; 2408 } 2409 if (sc->sc_enabled) 2410 error = wi_cfg_txrate(sc); 2411 break; 2412 2413 case WI_RID_SCAN_APS: 2414 if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP) 2415 error = wi_scan_ap(sc, 0x3fff, 0x000f); 2416 break; 2417 2418 case WI_RID_MGMT_XMIT: 2419 if (!sc->sc_enabled) { 2420 error = ENETDOWN; 2421 break; 2422 } 2423 if (ic->ic_mgtq.ifq_len > 5) { 2424 error = EAGAIN; 2425 break; 2426 } 2427 /* XXX wi_len looks in u_int8_t, not in u_int16_t */ 2428 m = m_devget((char *)&wreq.wi_val, wreq.wi_len, 0, ifp, NULL); 2429 if (m == NULL) { 2430 error = ENOMEM; 2431 break; 2432 } 2433 IF_ENQUEUE(&ic->ic_mgtq, m); 2434 break; 2435 2436 default: 2437 if (sc->sc_enabled) { 2438 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, 2439 len); 2440 if (error) 2441 break; 2442 } 2443 error = ieee80211_cfgset(ic, cmd, data); 2444 break; 2445 } 2446 return error; 2447} 2448 2449/* Rate is 0 for hardware auto-select, otherwise rate is 2450 * 2, 4, 11, or 22 (units of 500Kbps). 2451 */ 2452STATIC int 2453wi_write_txrate(struct wi_softc *sc, int rate) 2454{ 2455 u_int16_t hwrate; 2456 2457 /* rate: 0, 2, 4, 11, 22 */ 2458 switch (sc->sc_firmware_type) { 2459 case WI_LUCENT: 2460 switch (rate & IEEE80211_RATE_VAL) { 2461 case 2: 2462 hwrate = 1; 2463 break; 2464 case 4: 2465 hwrate = 2; 2466 break; 2467 default: 2468 hwrate = 3; /* auto */ 2469 break; 2470 case 11: 2471 hwrate = 4; 2472 break; 2473 case 22: 2474 hwrate = 5; 2475 break; 2476 } 2477 break; 2478 default: 2479 switch (rate & IEEE80211_RATE_VAL) { 2480 case 2: 2481 hwrate = 1; 2482 break; 2483 case 4: 2484 hwrate = 2; 2485 break; 2486 case 11: 2487 hwrate = 4; 2488 break; 2489 case 22: 2490 hwrate = 8; 2491 break; 2492 default: 2493 hwrate = 15; /* auto */ 2494 break; 2495 } 2496 break; 2497 } 2498 2499 if (sc->sc_tx_rate == hwrate) 2500 return 0; 2501 2502 if (sc->sc_if.if_flags & IFF_DEBUG) 2503 printf("%s: tx rate %d -> %d (%d)\n", __func__, sc->sc_tx_rate, 2504 hwrate, rate); 2505 2506 sc->sc_tx_rate = hwrate; 2507 2508 return wi_write_val(sc, WI_RID_TX_RATE, sc->sc_tx_rate); 2509} 2510 2511STATIC int 2512wi_cfg_txrate(struct wi_softc *sc) 2513{ 2514 struct ieee80211com *ic = &sc->sc_ic; 2515 struct ieee80211_rateset *rs; 2516 int rate; 2517 2518 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; 2519 2520 sc->sc_tx_rate = 0; /* force write to RID */ 2521 2522 if (ic->ic_fixed_rate < 0) 2523 rate = 0; /* auto */ 2524 else 2525 rate = rs->rs_rates[ic->ic_fixed_rate]; 2526 2527 return wi_write_txrate(sc, rate); 2528} 2529 2530STATIC int 2531wi_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) 2532{ 2533 struct wi_softc *sc = ic->ic_ifp->if_softc; 2534 u_int keyix = k->wk_keyix; 2535 2536 DPRINTF(("%s: delete key %u\n", __func__, keyix)); 2537 2538 if (keyix >= IEEE80211_WEP_NKID) 2539 return 0; 2540 if (k->wk_keylen != 0) 2541 sc->sc_flags &= ~WI_FLAGS_WEP_VALID; 2542 2543 return 1; 2544} 2545 2546static int 2547wi_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, 2548 const u_int8_t mac[IEEE80211_ADDR_LEN]) 2549{ 2550 struct wi_softc *sc = ic->ic_ifp->if_softc; 2551 2552 DPRINTF(("%s: set key %u\n", __func__, k->wk_keyix)); 2553 2554 if (k->wk_keyix >= IEEE80211_WEP_NKID) 2555 return 0; 2556 2557 sc->sc_flags &= ~WI_FLAGS_WEP_VALID; 2558 2559 return 1; 2560} 2561 2562STATIC void 2563wi_key_update_begin(struct ieee80211com *ic) 2564{ 2565 DPRINTF(("%s:\n", __func__)); 2566} 2567 2568STATIC void 2569wi_key_update_end(struct ieee80211com *ic) 2570{ 2571 struct ifnet *ifp = ic->ic_ifp; 2572 struct wi_softc *sc = ifp->if_softc; 2573 2574 DPRINTF(("%s:\n", __func__)); 2575 2576 if ((sc->sc_flags & WI_FLAGS_WEP_VALID) != 0) 2577 return; 2578 if ((ic->ic_caps & IEEE80211_C_WEP) != 0 && sc->sc_enabled && 2579 !sc->sc_invalid) 2580 (void)wi_write_wep(sc); 2581} 2582 2583STATIC int 2584wi_write_wep(struct wi_softc *sc) 2585{ 2586 struct ifnet *ifp = &sc->sc_if; 2587 struct ieee80211com *ic = &sc->sc_ic; 2588 int error = 0; 2589 int i, keylen; 2590 u_int16_t val; 2591 struct wi_key wkey[IEEE80211_WEP_NKID]; 2592 2593 if ((ifp->if_flags & IFF_RUNNING) != 0) 2594 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0); 2595 2596 switch (sc->sc_firmware_type) { 2597 case WI_LUCENT: 2598 val = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0; 2599 error = wi_write_val(sc, WI_RID_ENCRYPTION, val); 2600 if (error) 2601 break; 2602 error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_def_txkey); 2603 if (error) 2604 break; 2605 memset(wkey, 0, sizeof(wkey)); 2606 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2607 keylen = ic->ic_nw_keys[i].wk_keylen; 2608 wkey[i].wi_keylen = htole16(keylen); 2609 memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key, 2610 keylen); 2611 } 2612 error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS, 2613 wkey, sizeof(wkey)); 2614 break; 2615 2616 case WI_INTERSIL: 2617 case WI_SYMBOL: 2618 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 2619 /* 2620 * ONLY HWB3163 EVAL-CARD Firmware version 2621 * less than 0.8 variant2 2622 * 2623 * If promiscuous mode disable, Prism2 chip 2624 * does not work with WEP . 2625 * It is under investigation for details. 2626 * (ichiro@NetBSD.org) 2627 */ 2628 if (sc->sc_firmware_type == WI_INTERSIL && 2629 sc->sc_sta_firmware_ver < 802 ) { 2630 /* firm ver < 0.8 variant 2 */ 2631 wi_write_val(sc, WI_RID_PROMISC, 1); 2632 } 2633 wi_write_val(sc, WI_RID_CNFAUTHMODE, 2634 sc->sc_cnfauthmode); 2635 val = PRIVACY_INVOKED; 2636 if ((sc->sc_ic_flags & IEEE80211_F_DROPUNENC) != 0) 2637 val |= EXCLUDE_UNENCRYPTED; 2638#ifndef IEEE80211_NO_HOSTAP 2639 /* 2640 * Encryption firmware has a bug for HostAP mode. 2641 */ 2642 if (sc->sc_firmware_type == WI_INTERSIL && 2643 ic->ic_opmode == IEEE80211_M_HOSTAP) 2644 val |= HOST_ENCRYPT; 2645#endif /* !IEEE80211_NO_HOSTAP */ 2646 } else { 2647 wi_write_val(sc, WI_RID_CNFAUTHMODE, 2648 IEEE80211_AUTH_OPEN); 2649 val = HOST_ENCRYPT | HOST_DECRYPT; 2650 } 2651 error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val); 2652 if (error) 2653 break; 2654 error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, 2655 ic->ic_def_txkey); 2656 if (error) 2657 break; 2658 /* 2659 * It seems that the firmware accept 104bit key only if 2660 * all the keys have 104bit length. We get the length of 2661 * the transmit key and use it for all other keys. 2662 * Perhaps we should use software WEP for such situation. 2663 */ 2664 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE || 2665 IEEE80211_KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey])) 2666 keylen = 13; /* No keys => 104bit ok */ 2667 else 2668 keylen = ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen; 2669 2670 if (keylen > IEEE80211_WEP_KEYLEN) 2671 keylen = 13; /* 104bit keys */ 2672 else 2673 keylen = IEEE80211_WEP_KEYLEN; 2674 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2675 error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i, 2676 ic->ic_nw_keys[i].wk_key, keylen); 2677 if (error) 2678 break; 2679 } 2680 break; 2681 } 2682 if ((ifp->if_flags & IFF_RUNNING) != 0) 2683 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); 2684 if (error == 0) 2685 sc->sc_flags |= WI_FLAGS_WEP_VALID; 2686 return error; 2687} 2688 2689/* Must be called at proper protection level! */ 2690STATIC int 2691wi_cmd_start(struct wi_softc *sc, int cmd, int val0, int val1, int val2) 2692{ 2693#ifdef WI_HISTOGRAM 2694 static int hist1[11]; 2695 static int hist1count; 2696#endif 2697 int i; 2698 2699 /* wait for the busy bit to clear */ 2700 for (i = 500; i > 0; i--) { /* 5s */ 2701 if ((CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY) == 0) 2702 break; 2703 if (sc->sc_invalid) 2704 return ENXIO; 2705 DELAY(1000); /* 1 m sec */ 2706 } 2707 if (i == 0) { 2708 aprint_error_dev(sc->sc_dev, "wi_cmd: busy bit won't clear.\n"); 2709 return(ETIMEDOUT); 2710 } 2711#ifdef WI_HISTOGRAM 2712 if (i > 490) 2713 hist1[500 - i]++; 2714 else 2715 hist1[10]++; 2716 if (++hist1count == 1000) { 2717 hist1count = 0; 2718 printf("%s: hist1: %d %d %d %d %d %d %d %d %d %d %d\n", 2719 device_xname(sc->sc_dev), 2720 hist1[0], hist1[1], hist1[2], hist1[3], hist1[4], 2721 hist1[5], hist1[6], hist1[7], hist1[8], hist1[9], 2722 hist1[10]); 2723 } 2724#endif 2725 CSR_WRITE_2(sc, WI_PARAM0, val0); 2726 CSR_WRITE_2(sc, WI_PARAM1, val1); 2727 CSR_WRITE_2(sc, WI_PARAM2, val2); 2728 CSR_WRITE_2(sc, WI_COMMAND, cmd); 2729 2730 return 0; 2731} 2732 2733STATIC int 2734wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) 2735{ 2736 int rc; 2737 2738#ifdef WI_DEBUG 2739 if (wi_debug) { 2740 printf("%s: [enter] %d txcmds outstanding\n", __func__, 2741 sc->sc_txcmds); 2742 } 2743#endif 2744 if (sc->sc_txcmds > 0) 2745 wi_txcmd_wait(sc); 2746 2747 if ((rc = wi_cmd_start(sc, cmd, val0, val1, val2)) != 0) 2748 return rc; 2749 2750 if (cmd == WI_CMD_INI) { 2751 /* XXX: should sleep here. */ 2752 if (sc->sc_invalid) 2753 return ENXIO; 2754 DELAY(100*1000); 2755 } 2756 rc = wi_cmd_wait(sc, cmd, val0); 2757 2758#ifdef WI_DEBUG 2759 if (wi_debug) { 2760 printf("%s: [ ] %d txcmds outstanding\n", __func__, 2761 sc->sc_txcmds); 2762 } 2763#endif 2764 if (sc->sc_txcmds > 0) 2765 wi_cmd_intr(sc); 2766 2767#ifdef WI_DEBUG 2768 if (wi_debug) { 2769 printf("%s: [leave] %d txcmds outstanding\n", __func__, 2770 sc->sc_txcmds); 2771 } 2772#endif 2773 return rc; 2774} 2775 2776STATIC int 2777wi_cmd_wait(struct wi_softc *sc, int cmd, int val0) 2778{ 2779#ifdef WI_HISTOGRAM 2780 static int hist2[11]; 2781 static int hist2count; 2782#endif 2783 int i, status; 2784#ifdef WI_DEBUG 2785 if (wi_debug > 1) 2786 printf("%s: cmd=%#x, arg=%#x\n", __func__, cmd, val0); 2787#endif /* WI_DEBUG */ 2788 2789 /* wait for the cmd completed bit */ 2790 for (i = 0; i < WI_TIMEOUT; i++) { 2791 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD) 2792 break; 2793 if (sc->sc_invalid) 2794 return ENXIO; 2795 DELAY(WI_DELAY); 2796 } 2797 2798#ifdef WI_HISTOGRAM 2799 if (i < 100) 2800 hist2[i/10]++; 2801 else 2802 hist2[10]++; 2803 if (++hist2count == 1000) { 2804 hist2count = 0; 2805 printf("%s: hist2: %d %d %d %d %d %d %d %d %d %d %d\n", 2806 device_xname(sc->sc_dev), 2807 hist2[0], hist2[1], hist2[2], hist2[3], hist2[4], 2808 hist2[5], hist2[6], hist2[7], hist2[8], hist2[9], 2809 hist2[10]); 2810 } 2811#endif 2812 2813 status = CSR_READ_2(sc, WI_STATUS); 2814 2815 if (i == WI_TIMEOUT) { 2816 aprint_error_dev(sc->sc_dev, 2817 "command timed out, cmd=0x%x, arg=0x%x\n", 2818 cmd, val0); 2819 return ETIMEDOUT; 2820 } 2821 2822 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 2823 2824 if (status & WI_STAT_CMD_RESULT) { 2825 aprint_error_dev(sc->sc_dev, 2826 "command failed, cmd=0x%x, arg=0x%x\n", 2827 cmd, val0); 2828 return EIO; 2829 } 2830 return 0; 2831} 2832 2833STATIC int 2834wi_seek_bap(struct wi_softc *sc, int id, int off) 2835{ 2836#ifdef WI_HISTOGRAM 2837 static int hist4[11]; 2838 static int hist4count; 2839#endif 2840 int i, status; 2841 2842 CSR_WRITE_2(sc, WI_SEL0, id); 2843 CSR_WRITE_2(sc, WI_OFF0, off); 2844 2845 for (i = 0; ; i++) { 2846 status = CSR_READ_2(sc, WI_OFF0); 2847 if ((status & WI_OFF_BUSY) == 0) 2848 break; 2849 if (i == WI_TIMEOUT) { 2850 aprint_error_dev(sc->sc_dev, 2851 "timeout in wi_seek to %x/%x\n", 2852 id, off); 2853 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ 2854 return ETIMEDOUT; 2855 } 2856 if (sc->sc_invalid) 2857 return ENXIO; 2858 DELAY(2); 2859 } 2860#ifdef WI_HISTOGRAM 2861 if (i < 100) 2862 hist4[i/10]++; 2863 else 2864 hist4[10]++; 2865 if (++hist4count == 2500) { 2866 hist4count = 0; 2867 printf("%s: hist4: %d %d %d %d %d %d %d %d %d %d %d\n", 2868 device_xname(sc->sc_dev), 2869 hist4[0], hist4[1], hist4[2], hist4[3], hist4[4], 2870 hist4[5], hist4[6], hist4[7], hist4[8], hist4[9], 2871 hist4[10]); 2872 } 2873#endif 2874 if (status & WI_OFF_ERR) { 2875 printf("%s: failed in wi_seek to %x/%x\n", 2876 device_xname(sc->sc_dev), id, off); 2877 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ 2878 return EIO; 2879 } 2880 sc->sc_bap_id = id; 2881 sc->sc_bap_off = off; 2882 return 0; 2883} 2884 2885STATIC int 2886wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) 2887{ 2888 int error, cnt; 2889 2890 if (buflen == 0) 2891 return 0; 2892 if (id != sc->sc_bap_id || off != sc->sc_bap_off) { 2893 if ((error = wi_seek_bap(sc, id, off)) != 0) 2894 return error; 2895 } 2896 cnt = (buflen + 1) / 2; 2897 CSR_READ_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt); 2898 sc->sc_bap_off += cnt * 2; 2899 return 0; 2900} 2901 2902STATIC int 2903wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) 2904{ 2905 int error, cnt; 2906 2907 if (buflen == 0) 2908 return 0; 2909 2910#ifdef WI_HERMES_AUTOINC_WAR 2911 again: 2912#endif 2913 if (id != sc->sc_bap_id || off != sc->sc_bap_off) { 2914 if ((error = wi_seek_bap(sc, id, off)) != 0) 2915 return error; 2916 } 2917 cnt = (buflen + 1) / 2; 2918 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt); 2919 sc->sc_bap_off += cnt * 2; 2920 2921#ifdef WI_HERMES_AUTOINC_WAR 2922 /* 2923 * According to the comments in the HCF Light code, there is a bug 2924 * in the Hermes (or possibly in certain Hermes firmware revisions) 2925 * where the chip's internal autoincrement counter gets thrown off 2926 * during data writes: the autoincrement is missed, causing one 2927 * data word to be overwritten and subsequent words to be written to 2928 * the wrong memory locations. The end result is that we could end 2929 * up transmitting bogus frames without realizing it. The workaround 2930 * for this is to write a couple of extra guard words after the end 2931 * of the transfer, then attempt to read then back. If we fail to 2932 * locate the guard words where we expect them, we preform the 2933 * transfer over again. 2934 */ 2935 if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) { 2936 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 2937 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 2938 wi_seek_bap(sc, id, sc->sc_bap_off); 2939 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ 2940 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 2941 CSR_READ_2(sc, WI_DATA0) != 0x5678) { 2942 aprint_error_dev(sc->sc_dev, 2943 "detect auto increment bug, try again\n"); 2944 goto again; 2945 } 2946 } 2947#endif 2948 return 0; 2949} 2950 2951STATIC int 2952wi_mwrite_bap(struct wi_softc *sc, int id, int off, struct mbuf *m0, int totlen) 2953{ 2954 int error, len; 2955 struct mbuf *m; 2956 2957 for (m = m0; m != NULL && totlen > 0; m = m->m_next) { 2958 if (m->m_len == 0) 2959 continue; 2960 2961 len = min(m->m_len, totlen); 2962 2963 if (((u_long)m->m_data) % 2 != 0 || len % 2 != 0) { 2964 m_copydata(m, 0, totlen, (void *)&sc->sc_txbuf); 2965 return wi_write_bap(sc, id, off, (void *)&sc->sc_txbuf, 2966 totlen); 2967 } 2968 2969 if ((error = wi_write_bap(sc, id, off, m->m_data, len)) != 0) 2970 return error; 2971 2972 off += m->m_len; 2973 totlen -= len; 2974 } 2975 return 0; 2976} 2977 2978STATIC int 2979wi_alloc_fid(struct wi_softc *sc, int len, int *idp) 2980{ 2981 int i; 2982 2983 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) { 2984 aprint_error_dev(sc->sc_dev, "failed to allocate %d bytes on NIC\n", len); 2985 return ENOMEM; 2986 } 2987 2988 for (i = 0; i < WI_TIMEOUT; i++) { 2989 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 2990 break; 2991 DELAY(1); 2992 } 2993 if (i == WI_TIMEOUT) { 2994 aprint_error_dev(sc->sc_dev, "timeout in alloc\n"); 2995 return ETIMEDOUT; 2996 } 2997 *idp = CSR_READ_2(sc, WI_ALLOC_FID); 2998 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 2999 return 0; 3000} 3001 3002STATIC int 3003wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp) 3004{ 3005 int error, len; 3006 u_int16_t ltbuf[2]; 3007 3008 /* Tell the NIC to enter record read mode. */ 3009 error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0); 3010 if (error) 3011 return error; 3012 3013 error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf)); 3014 if (error) 3015 return error; 3016 3017 if (le16toh(ltbuf[0]) == 0) 3018 return EOPNOTSUPP; 3019 if (le16toh(ltbuf[1]) != rid) { 3020 aprint_error_dev(sc->sc_dev, 3021 "record read mismatch, rid=%x, got=%x\n", 3022 rid, le16toh(ltbuf[1])); 3023 return EIO; 3024 } 3025 len = (le16toh(ltbuf[0]) - 1) * 2; /* already got rid */ 3026 if (*buflenp < len) { 3027 aprint_error_dev(sc->sc_dev, "record buffer is too small, " 3028 "rid=%x, size=%d, len=%d\n", 3029 rid, *buflenp, len); 3030 return ENOSPC; 3031 } 3032 *buflenp = len; 3033 return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len); 3034} 3035 3036STATIC int 3037wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen) 3038{ 3039 int error; 3040 u_int16_t ltbuf[2]; 3041 3042 ltbuf[0] = htole16((buflen + 1) / 2 + 1); /* includes rid */ 3043 ltbuf[1] = htole16(rid); 3044 3045 error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf)); 3046 if (error) 3047 return error; 3048 error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen); 3049 if (error) 3050 return error; 3051 3052 return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0); 3053} 3054 3055STATIC void 3056wi_rssadapt_updatestats_cb(void *arg, struct ieee80211_node *ni) 3057{ 3058 struct wi_node *wn = (void*)ni; 3059 ieee80211_rssadapt_updatestats(&wn->wn_rssadapt); 3060} 3061 3062STATIC void 3063wi_rssadapt_updatestats(void *arg) 3064{ 3065 struct wi_softc *sc = arg; 3066 struct ieee80211com *ic = &sc->sc_ic; 3067 ieee80211_iterate_nodes(&ic->ic_sta, wi_rssadapt_updatestats_cb, arg); 3068 if (ic->ic_opmode != IEEE80211_M_MONITOR && 3069 ic->ic_state == IEEE80211_S_RUN) 3070 callout_reset(&sc->sc_rssadapt_ch, hz / 10, 3071 wi_rssadapt_updatestats, arg); 3072} 3073 3074/* 3075 * In HOSTAP mode, restore IEEE80211_F_DROPUNENC when operating 3076 * with WEP enabled so that the AP drops unencoded frames at the 3077 * 802.11 layer. 3078 * 3079 * In all other modes, clear IEEE80211_F_DROPUNENC when operating 3080 * with WEP enabled so we don't drop unencoded frames at the 802.11 3081 * layer. This is necessary because we must strip the WEP bit from 3082 * the 802.11 header before passing frames to ieee80211_input 3083 * because the card has already stripped the WEP crypto header from 3084 * the packet. 3085 */ 3086STATIC void 3087wi_mend_flags(struct wi_softc *sc, enum ieee80211_state nstate) 3088{ 3089 struct ieee80211com *ic = &sc->sc_ic; 3090 3091 if (nstate == IEEE80211_S_RUN && 3092 (ic->ic_flags & IEEE80211_F_PRIVACY) != 0 && 3093 ic->ic_opmode != IEEE80211_M_HOSTAP) 3094 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 3095 else 3096 ic->ic_flags |= sc->sc_ic_flags; 3097 3098 DPRINTF(("%s: state %d, " 3099 "ic->ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 ", " 3100 "sc->sc_ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 "\n", 3101 __func__, nstate, 3102 ic->ic_flags & IEEE80211_F_DROPUNENC, 3103 sc->sc_ic_flags & IEEE80211_F_DROPUNENC)); 3104} 3105 3106STATIC int 3107wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 3108{ 3109 struct ifnet *ifp = ic->ic_ifp; 3110 struct wi_softc *sc = ifp->if_softc; 3111 struct ieee80211_node *ni = ic->ic_bss; 3112 u_int16_t val; 3113 struct wi_ssid ssid; 3114 struct wi_macaddr bssid, old_bssid; 3115 enum ieee80211_state ostate; 3116#ifdef WI_DEBUG 3117 static const char *stname[] = 3118 { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" }; 3119#endif /* WI_DEBUG */ 3120 3121 ostate = ic->ic_state; 3122 DPRINTF(("wi_newstate: %s -> %s\n", stname[ostate], stname[nstate])); 3123 3124 switch (nstate) { 3125 case IEEE80211_S_INIT: 3126 if (ic->ic_opmode != IEEE80211_M_MONITOR) 3127 callout_stop(&sc->sc_rssadapt_ch); 3128 ic->ic_flags &= ~IEEE80211_F_SIBSS; 3129 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 3130 break; 3131 3132 case IEEE80211_S_SCAN: 3133 case IEEE80211_S_AUTH: 3134 case IEEE80211_S_ASSOC: 3135 ic->ic_state = nstate; /* NB: skip normal ieee80211 handling */ 3136 wi_mend_flags(sc, nstate); 3137 return 0; 3138 3139 case IEEE80211_S_RUN: 3140 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 3141 IEEE80211_ADDR_COPY(old_bssid.wi_mac_addr, ni->ni_bssid); 3142 wi_read_xrid(sc, WI_RID_CURRENT_BSSID, &bssid, 3143 IEEE80211_ADDR_LEN); 3144 IEEE80211_ADDR_COPY(ni->ni_bssid, &bssid); 3145 IEEE80211_ADDR_COPY(ni->ni_macaddr, &bssid); 3146 wi_read_xrid(sc, WI_RID_CURRENT_CHAN, &val, sizeof(val)); 3147 if (!isset(ic->ic_chan_avail, le16toh(val))) 3148 panic("%s: invalid channel %d\n", 3149 device_xname(sc->sc_dev), le16toh(val)); 3150 ni->ni_chan = &ic->ic_channels[le16toh(val)]; 3151 3152 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 3153#ifndef IEEE80211_NO_HOSTAP 3154 ni->ni_esslen = ic->ic_des_esslen; 3155 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); 3156 ni->ni_rates = ic->ic_sup_rates[ 3157 ieee80211_chan2mode(ic, ni->ni_chan)]; 3158 ni->ni_intval = ic->ic_lintval; 3159 ni->ni_capinfo = IEEE80211_CAPINFO_ESS; 3160 if (ic->ic_flags & IEEE80211_F_PRIVACY) 3161 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; 3162#endif /* !IEEE80211_NO_HOSTAP */ 3163 } else { 3164 wi_read_xrid(sc, WI_RID_CURRENT_SSID, &ssid, 3165 sizeof(ssid)); 3166 ni->ni_esslen = le16toh(ssid.wi_len); 3167 if (ni->ni_esslen > IEEE80211_NWID_LEN) 3168 ni->ni_esslen = IEEE80211_NWID_LEN; /*XXX*/ 3169 memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen); 3170 ni->ni_rates = ic->ic_sup_rates[ 3171 ieee80211_chan2mode(ic, ni->ni_chan)]; /*XXX*/ 3172 } 3173 if (ic->ic_opmode != IEEE80211_M_MONITOR) 3174 callout_reset(&sc->sc_rssadapt_ch, hz / 10, 3175 wi_rssadapt_updatestats, sc); 3176 /* Trigger routing socket messages. XXX Copied from 3177 * ieee80211_newstate. 3178 */ 3179 if (ic->ic_opmode == IEEE80211_M_STA) 3180 ieee80211_notify_node_join(ic, ic->ic_bss, 3181 arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP); 3182 break; 3183 } 3184 wi_mend_flags(sc, nstate); 3185 return (*sc->sc_newstate)(ic, nstate, arg); 3186} 3187 3188STATIC void 3189wi_set_tim(struct ieee80211_node *ni, int set) 3190{ 3191 struct ieee80211com *ic = ni->ni_ic; 3192 struct wi_softc *sc = ic->ic_ifp->if_softc; 3193 3194 (*sc->sc_set_tim)(ni, set); 3195 3196 if ((ic->ic_flags & IEEE80211_F_TIMUPDATE) == 0) 3197 return; 3198 3199 ic->ic_flags &= ~IEEE80211_F_TIMUPDATE; 3200 3201 (void)wi_write_val(sc, WI_RID_SET_TIM, 3202 IEEE80211_AID(ni->ni_associd) | (set ? 0x8000 : 0)); 3203} 3204 3205STATIC int 3206wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate) 3207{ 3208 int error = 0; 3209 u_int16_t val[2]; 3210 3211 if (!sc->sc_enabled) 3212 return ENXIO; 3213 switch (sc->sc_firmware_type) { 3214 case WI_LUCENT: 3215 (void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); 3216 break; 3217 case WI_INTERSIL: 3218 val[0] = htole16(chanmask); /* channel */ 3219 val[1] = htole16(txrate); /* tx rate */ 3220 error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val)); 3221 break; 3222 case WI_SYMBOL: 3223 /* 3224 * XXX only supported on 3.x ? 3225 */ 3226 val[0] = htole16(BSCAN_BCAST | BSCAN_ONETIME); 3227 error = wi_write_rid(sc, WI_RID_BCAST_SCAN_REQ, 3228 val, sizeof(val[0])); 3229 break; 3230 } 3231 if (error == 0) { 3232 sc->sc_scan_timer = WI_SCAN_WAIT; 3233 sc->sc_if.if_timer = 1; 3234 DPRINTF(("wi_scan_ap: start scanning, " 3235 "chanmask 0x%x txrate 0x%x\n", chanmask, txrate)); 3236 } 3237 return error; 3238} 3239 3240STATIC void 3241wi_scan_result(struct wi_softc *sc, int fid, int cnt) 3242{ 3243#define N(a) (sizeof (a) / sizeof (a[0])) 3244 int i, naps, off, szbuf; 3245 struct wi_scan_header ws_hdr; /* Prism2 header */ 3246 struct wi_scan_data_p2 ws_dat; /* Prism2 scantable*/ 3247 struct wi_apinfo *ap; 3248 3249 off = sizeof(u_int16_t) * 2; 3250 memset(&ws_hdr, 0, sizeof(ws_hdr)); 3251 switch (sc->sc_firmware_type) { 3252 case WI_INTERSIL: 3253 wi_read_bap(sc, fid, off, &ws_hdr, sizeof(ws_hdr)); 3254 off += sizeof(ws_hdr); 3255 szbuf = sizeof(struct wi_scan_data_p2); 3256 break; 3257 case WI_SYMBOL: 3258 szbuf = sizeof(struct wi_scan_data_p2) + 6; 3259 break; 3260 case WI_LUCENT: 3261 szbuf = sizeof(struct wi_scan_data); 3262 break; 3263 default: 3264 aprint_error_dev(sc->sc_dev, 3265 "wi_scan_result: unknown firmware type %u\n", 3266 sc->sc_firmware_type); 3267 naps = 0; 3268 goto done; 3269 } 3270 naps = (cnt * 2 + 2 - off) / szbuf; 3271 if (naps > N(sc->sc_aps)) 3272 naps = N(sc->sc_aps); 3273 sc->sc_naps = naps; 3274 /* Read Data */ 3275 ap = sc->sc_aps; 3276 memset(&ws_dat, 0, sizeof(ws_dat)); 3277 for (i = 0; i < naps; i++, ap++) { 3278 wi_read_bap(sc, fid, off, &ws_dat, 3279 (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf)); 3280 DPRINTF2(("wi_scan_result: #%d: off %d bssid %s\n", i, off, 3281 ether_sprintf(ws_dat.wi_bssid))); 3282 off += szbuf; 3283 ap->scanreason = le16toh(ws_hdr.wi_reason); 3284 memcpy(ap->bssid, ws_dat.wi_bssid, sizeof(ap->bssid)); 3285 ap->channel = le16toh(ws_dat.wi_chid); 3286 ap->signal = le16toh(ws_dat.wi_signal); 3287 ap->noise = le16toh(ws_dat.wi_noise); 3288 ap->quality = ap->signal - ap->noise; 3289 ap->capinfo = le16toh(ws_dat.wi_capinfo); 3290 ap->interval = le16toh(ws_dat.wi_interval); 3291 ap->rate = le16toh(ws_dat.wi_rate); 3292 ap->namelen = le16toh(ws_dat.wi_namelen); 3293 if (ap->namelen > sizeof(ap->name)) 3294 ap->namelen = sizeof(ap->name); 3295 memcpy(ap->name, ws_dat.wi_name, ap->namelen); 3296 } 3297done: 3298 /* Done scanning */ 3299 sc->sc_scan_timer = 0; 3300 DPRINTF(("wi_scan_result: scan complete: ap %d\n", naps)); 3301#undef N 3302} 3303 3304STATIC void 3305wi_dump_pkt(struct wi_frame *wh, struct ieee80211_node *ni, int rssi) 3306{ 3307 ieee80211_dump_pkt((u_int8_t *) &wh->wi_whdr, sizeof(wh->wi_whdr), 3308 ni ? ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL 3309 : -1, 3310 rssi); 3311 printf(" status 0x%x rx_tstamp1 %u rx_tstamp0 0x%u rx_silence %u\n", 3312 le16toh(wh->wi_status), le16toh(wh->wi_rx_tstamp1), 3313 le16toh(wh->wi_rx_tstamp0), wh->wi_rx_silence); 3314 printf(" rx_signal %u rx_rate %u rx_flow %u\n", 3315 wh->wi_rx_signal, wh->wi_rx_rate, wh->wi_rx_flow); 3316 printf(" tx_rtry %u tx_rate %u tx_ctl 0x%x dat_len %u\n", 3317 wh->wi_tx_rtry, wh->wi_tx_rate, 3318 le16toh(wh->wi_tx_ctl), le16toh(wh->wi_dat_len)); 3319 printf(" ehdr dst %s src %s type 0x%x\n", 3320 ether_sprintf(wh->wi_ehdr.ether_dhost), 3321 ether_sprintf(wh->wi_ehdr.ether_shost), 3322 wh->wi_ehdr.ether_type); 3323} 3324