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