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