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