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