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