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