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