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