if_wi.c revision 105076
1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/* 34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 35 * 36 * Written by Bill Paul <wpaul@ctr.columbia.edu> 37 * Electrical Engineering Department 38 * Columbia University, New York City 39 */ 40 41/* 42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 43 * from Lucent. Unlike the older cards, the new ones are programmed 44 * entirely via a firmware-driven controller called the Hermes. 45 * Unfortunately, Lucent will not release the Hermes programming manual 46 * without an NDA (if at all). What they do release is an API library 47 * called the HCF (Hardware Control Functions) which is supposed to 48 * do the device-specific operations of a device driver for you. The 49 * publically available version of the HCF library (the 'HCF Light') is 50 * a) extremely gross, b) lacks certain features, particularly support 51 * for 802.11 frames, and c) is contaminated by the GNU Public License. 52 * 53 * This driver does not use the HCF or HCF Light at all. Instead, it 54 * programs the Hermes controller directly, using information gleaned 55 * from the HCF Light code and corresponding documentation. 56 * 57 * This driver supports the ISA, PCMCIA and PCI versions of the Lucent 58 * WaveLan cards (based on the Hermes chipset), as well as the newer 59 * Prism 2 chipsets with firmware from Intersil and Symbol. 60 */ 61 62#include <sys/param.h> 63#include <sys/systm.h> 64#if __FreeBSD_version >= 500033 65#include <sys/endian.h> 66#endif 67#include <sys/sockio.h> 68#include <sys/mbuf.h> 69#include <sys/proc.h> 70#include <sys/kernel.h> 71#include <sys/socket.h> 72#include <sys/module.h> 73#include <sys/bus.h> 74#include <sys/random.h> 75#include <sys/syslog.h> 76#include <sys/sysctl.h> 77 78#include <machine/bus.h> 79#include <machine/resource.h> 80#include <machine/clock.h> 81#include <sys/rman.h> 82 83#include <net/if.h> 84#include <net/if_arp.h> 85#include <net/ethernet.h> 86#include <net/if_dl.h> 87#include <net/if_media.h> 88#include <net/if_types.h> 89#include <net/if_ieee80211.h> 90 91#include <netinet/in.h> 92#include <netinet/in_systm.h> 93#include <netinet/in_var.h> 94#include <netinet/ip.h> 95#include <netinet/if_ether.h> 96 97#include <net/bpf.h> 98 99#include <dev/wi/if_wavelan_ieee.h> 100#include <dev/wi/wi_hostap.h> 101#include <dev/wi/if_wivar.h> 102#include <dev/wi/if_wireg.h> 103 104#if !defined(lint) 105static const char rcsid[] = 106 "$FreeBSD: head/sys/dev/wi/if_wi.c 105076 2002-10-14 01:59:57Z imp $"; 107#endif 108 109static void wi_intr(void *); 110static void wi_reset(struct wi_softc *); 111static int wi_ioctl(struct ifnet *, u_long, caddr_t); 112static void wi_init(void *); 113static void wi_start(struct ifnet *); 114static void wi_stop(struct wi_softc *); 115static void wi_watchdog(struct ifnet *); 116static void wi_rxeof(struct wi_softc *); 117static void wi_txeof(struct wi_softc *, int); 118static void wi_update_stats(struct wi_softc *); 119static void wi_setmulti(struct wi_softc *); 120 121static int wi_cmd(struct wi_softc *, int, int, int, int); 122static int wi_read_record(struct wi_softc *, struct wi_ltv_gen *); 123static int wi_write_record(struct wi_softc *, struct wi_ltv_gen *); 124static int wi_read_data(struct wi_softc *, int, int, caddr_t, int); 125static int wi_write_data(struct wi_softc *, int, int, caddr_t, int); 126static int wi_seek(struct wi_softc *, int, int, int); 127static int wi_alloc_nicmem(struct wi_softc *, int, int *); 128static void wi_inquire(void *); 129static void wi_setdef(struct wi_softc *, struct wi_req *); 130 131#ifdef WICACHE 132static 133void wi_cache_store(struct wi_softc *, struct ether_header *, 134 struct mbuf *, unsigned short); 135#endif 136 137static int wi_get_cur_ssid(struct wi_softc *, char *, int *); 138static void wi_get_id(struct wi_softc *); 139static int wi_media_change(struct ifnet *); 140static void wi_media_status(struct ifnet *, struct ifmediareq *); 141 142static int wi_get_debug(struct wi_softc *, struct wi_req *); 143static int wi_set_debug(struct wi_softc *, struct wi_req *); 144 145#if __FreeBSD_version >= 500000 146/* support to download firmware for symbol CF card */ 147static int wi_symbol_write_firm(struct wi_softc *, const void *, int, 148 const void *, int); 149static int wi_symbol_set_hcr(struct wi_softc *, int); 150#endif 151 152devclass_t wi_devclass; 153 154struct wi_card_ident wi_card_ident[] = { 155 /* CARD_ID CARD_NAME FIRM_TYPE */ 156 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT }, 157 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT }, 158 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT }, 159 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL }, 160 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL }, 161 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL }, 162 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL }, 163 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL }, 164 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL }, 165 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL }, 166 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL }, 167 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL }, 168 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 169 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 170 { WI_NIC_3842_PCMCIA_ATL_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 171 { WI_NIC_3842_PCMCIA_ATS_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 172 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 173 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 174 { WI_NIC_3842_MINI_ATL_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 175 { WI_NIC_3842_MINI_ATS_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 176 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 177 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 178 { WI_NIC_3842_PCI_ATS_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 179 { WI_NIC_3842_PCI_ATL_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 180 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 181 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 182 { WI_NIC_P3_PCMCIA_ATL_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 183 { WI_NIC_P3_PCMCIA_ATS_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 184 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 185 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 186 { WI_NIC_P3_MINI_ATL_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 187 { WI_NIC_P3_MINI_ATS_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 188 { 0, NULL, 0 }, 189}; 190 191int 192wi_generic_detach(dev) 193 device_t dev; 194{ 195 struct wi_softc *sc; 196 struct ifnet *ifp; 197 int s; 198 199 sc = device_get_softc(dev); 200 WI_LOCK(sc, s); 201 ifp = &sc->arpcom.ac_if; 202 203 if (sc->wi_gone) { 204 device_printf(dev, "already unloaded\n"); 205 WI_UNLOCK(sc, s); 206 return(ENODEV); 207 } 208 209 wi_stop(sc); 210 211 /* Delete all remaining media. */ 212 ifmedia_removeall(&sc->ifmedia); 213 214 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); 215 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); 216 wi_free(dev); 217 sc->wi_gone = 1; 218 219 WI_UNLOCK(sc, s); 220#if __FreeBSD_version >= 500000 221 mtx_destroy(&sc->wi_mtx); 222#endif 223 224 return(0); 225} 226 227int 228wi_generic_attach(device_t dev) 229{ 230 struct wi_softc *sc; 231 struct wi_ltv_macaddr mac; 232 struct wi_ltv_gen gen; 233 struct ifnet *ifp; 234 int error; 235 int s; 236 237 /* XXX maybe we need the splimp stuff here XXX */ 238 sc = device_get_softc(dev); 239 ifp = &sc->arpcom.ac_if; 240 241 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 242 wi_intr, sc, &sc->wi_intrhand); 243 244 if (error) { 245 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 246 wi_free(dev); 247 return (error); 248 } 249 250#if __FreeBSD_version >= 500000 251 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 252 MTX_DEF | MTX_RECURSE); 253#endif 254 WI_LOCK(sc, s); 255 256 /* Reset the NIC. */ 257 wi_reset(sc); 258 259 /* 260 * Read the station address. 261 * And do it twice. I've seen PRISM-based cards that return 262 * an error when trying to read it the first time, which causes 263 * the probe to fail. 264 */ 265 mac.wi_type = WI_RID_MAC_NODE; 266 mac.wi_len = 4; 267 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 268 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) { 269 device_printf(dev, "mac read failed %d\n", error); 270 wi_free(dev); 271 return (error); 272 } 273 bcopy((char *)&mac.wi_mac_addr, 274 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 275 276 device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":"); 277 278 wi_get_id(sc); 279 280 ifp->if_softc = sc; 281 ifp->if_unit = sc->wi_unit; 282 ifp->if_name = "wi"; 283 ifp->if_mtu = ETHERMTU; 284 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 285 ifp->if_ioctl = wi_ioctl; 286 ifp->if_output = ether_output; 287 ifp->if_start = wi_start; 288 ifp->if_watchdog = wi_watchdog; 289 ifp->if_init = wi_init; 290 ifp->if_baudrate = 10000000; 291 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 292 293 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 294 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name, 295 sizeof(WI_DEFAULT_NODENAME) - 1); 296 297 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 298 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name, 299 sizeof(WI_DEFAULT_NETNAME) - 1); 300 301 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 302 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name, 303 sizeof(WI_DEFAULT_IBSS) - 1); 304 305 sc->wi_portnum = WI_DEFAULT_PORT; 306 sc->wi_ptype = WI_PORTTYPE_BSS; 307 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 308 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 309 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 310 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 311 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 312 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 313 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 314 sc->wi_roaming = WI_DEFAULT_ROAMING; 315 sc->wi_authtype = WI_DEFAULT_AUTHTYPE; 316 sc->wi_authmode = IEEE80211_AUTH_OPEN; 317 318 /* 319 * Read the default channel from the NIC. This may vary 320 * depending on the country where the NIC was purchased, so 321 * we can't hard-code a default and expect it to work for 322 * everyone. 323 */ 324 gen.wi_type = WI_RID_OWN_CHNL; 325 gen.wi_len = 2; 326 wi_read_record(sc, &gen); 327 sc->wi_channel = gen.wi_val; 328 329 /* 330 * Set flags based on firmware version. 331 */ 332 switch (sc->sc_firmware_type) { 333 case WI_LUCENT: 334 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 335 if (sc->sc_sta_firmware_ver >= 60000) 336 sc->wi_flags |= WI_FLAGS_HAS_MOR; 337 if (sc->sc_sta_firmware_ver >= 60006) { 338 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 339 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 340 } 341 sc->wi_ibss_port = htole16(1); 342 break; 343 case WI_INTERSIL: 344 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 345 if (sc->sc_sta_firmware_ver >= 800) { 346 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 347 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 348 } 349 /* 350 * version 0.8.3 and newer are the only ones that are known 351 * to currently work. Earlier versions can be made to work, 352 * at least according to the Linux driver. 353 */ 354 if (sc->sc_sta_firmware_ver >= 803) 355 sc->wi_flags |= WI_FLAGS_HAS_HOSTAP; 356 sc->wi_ibss_port = htole16(0); 357 break; 358 case WI_SYMBOL: 359 sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY; 360 if (sc->sc_sta_firmware_ver >= 20000) 361 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 362 /* Older Symbol firmware does not support IBSS creation. */ 363 if (sc->sc_sta_firmware_ver >= 25000) 364 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 365 sc->wi_ibss_port = htole16(4); 366 break; 367 } 368 369 /* 370 * Find out if we support WEP on this card. 371 */ 372 gen.wi_type = WI_RID_WEP_AVAIL; 373 gen.wi_len = 2; 374 wi_read_record(sc, &gen); 375 sc->wi_has_wep = gen.wi_val; 376 377 if (bootverbose) 378 device_printf(sc->dev, "wi_has_wep = %d\n", sc->wi_has_wep); 379 380 /* 381 * Find supported rates. 382 */ 383 gen.wi_type = WI_RID_DATA_RATES; 384 gen.wi_len = 2; 385 if (wi_read_record(sc, &gen)) 386 sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M | 387 WI_SUPPRATES_5M | WI_SUPPRATES_11M; 388 else 389 sc->wi_supprates = gen.wi_val; 390 391 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 392 393 wi_init(sc); 394 wi_stop(sc); 395 396 ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status); 397#define ADD(m, c) ifmedia_add(&sc->ifmedia, (m), (c), NULL) 398 if (sc->wi_supprates & WI_SUPPRATES_1M) { 399 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 400 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 401 IFM_IEEE80211_ADHOC, 0), 0); 402 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 403 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 404 IFM_IEEE80211_IBSS, 0), 0); 405 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 406 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 407 IFM_IEEE80211_IBSSMASTER, 0), 0); 408 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 409 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 410 IFM_IEEE80211_HOSTAP, 0), 0); 411 } 412 if (sc->wi_supprates & WI_SUPPRATES_2M) { 413 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 414 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 415 IFM_IEEE80211_ADHOC, 0), 0); 416 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 417 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 418 IFM_IEEE80211_IBSS, 0), 0); 419 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 420 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 421 IFM_IEEE80211_IBSSMASTER, 0), 0); 422 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 423 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 424 IFM_IEEE80211_HOSTAP, 0), 0); 425 } 426 if (sc->wi_supprates & WI_SUPPRATES_5M) { 427 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 428 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 429 IFM_IEEE80211_ADHOC, 0), 0); 430 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 431 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 432 IFM_IEEE80211_IBSS, 0), 0); 433 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 434 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 435 IFM_IEEE80211_IBSSMASTER, 0), 0); 436 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 437 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 438 IFM_IEEE80211_HOSTAP, 0), 0); 439 } 440 if (sc->wi_supprates & WI_SUPPRATES_11M) { 441 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 442 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 443 IFM_IEEE80211_ADHOC, 0), 0); 444 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 445 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 446 IFM_IEEE80211_IBSS, 0), 0); 447 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 448 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 449 IFM_IEEE80211_IBSSMASTER, 0), 0); 450 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 451 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 452 IFM_IEEE80211_HOSTAP, 0), 0); 453 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0); 454 } 455 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0); 456 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 457 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, 458 0), 0); 459 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 460 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 461 IFM_IEEE80211_IBSSMASTER, 0), 0); 462 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 463 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 464 IFM_IEEE80211_HOSTAP, 0), 0); 465 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 466#undef ADD 467 ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0)); 468 469 /* 470 * Call MI attach routine. 471 */ 472 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 473 callout_handle_init(&sc->wi_stat_ch); 474 WI_UNLOCK(sc, s); 475 476 return(0); 477} 478 479static void 480wi_get_id(sc) 481 struct wi_softc *sc; 482{ 483 struct wi_ltv_ver ver; 484 struct wi_card_ident *id; 485 486 /* getting chip identity */ 487 memset(&ver, 0, sizeof(ver)); 488 ver.wi_type = WI_RID_CARD_ID; 489 ver.wi_len = 5; 490 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 491 device_printf(sc->dev, "using "); 492 sc->sc_firmware_type = WI_NOTYPE; 493 for (id = wi_card_ident; id->card_name != NULL; id++) { 494 if (le16toh(ver.wi_ver[0]) == id->card_id) { 495 printf("%s", id->card_name); 496 sc->sc_firmware_type = id->firm_type; 497 break; 498 } 499 } 500 if (sc->sc_firmware_type == WI_NOTYPE) { 501 if (le16toh(ver.wi_ver[0]) & 0x8000) { 502 printf("Unknown PRISM2 chip"); 503 sc->sc_firmware_type = WI_INTERSIL; 504 } else { 505 printf("Unknown Lucent chip"); 506 sc->sc_firmware_type = WI_LUCENT; 507 } 508 } 509 510 if (sc->sc_firmware_type != WI_LUCENT) { 511 /* get primary firmware version */ 512 memset(&ver, 0, sizeof(ver)); 513 ver.wi_type = WI_RID_PRI_IDENTITY; 514 ver.wi_len = 5; 515 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 516 ver.wi_ver[1] = le16toh(ver.wi_ver[1]); 517 ver.wi_ver[2] = le16toh(ver.wi_ver[2]); 518 ver.wi_ver[3] = le16toh(ver.wi_ver[3]); 519 sc->sc_pri_firmware_ver = ver.wi_ver[2] * 10000 + 520 ver.wi_ver[3] * 100 + ver.wi_ver[1]; 521 } 522 523 /* get station firmware version */ 524 memset(&ver, 0, sizeof(ver)); 525 ver.wi_type = WI_RID_STA_IDENTITY; 526 ver.wi_len = 5; 527 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 528 ver.wi_ver[1] = le16toh(ver.wi_ver[1]); 529 ver.wi_ver[2] = le16toh(ver.wi_ver[2]); 530 ver.wi_ver[3] = le16toh(ver.wi_ver[3]); 531 sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 + 532 ver.wi_ver[3] * 100 + ver.wi_ver[1]; 533 if (sc->sc_firmware_type == WI_INTERSIL && 534 (sc->sc_sta_firmware_ver == 10102 || 535 sc->sc_sta_firmware_ver == 20102)) { 536 struct wi_ltv_str sver; 537 char *p; 538 539 memset(&sver, 0, sizeof(sver)); 540 sver.wi_type = WI_RID_SYMBOL_IDENTITY; 541 sver.wi_len = 7; 542 /* value should be the format like "V2.00-11" */ 543 if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 && 544 *(p = (char *)sver.wi_str) >= 'A' && 545 p[2] == '.' && p[5] == '-' && p[8] == '\0') { 546 sc->sc_firmware_type = WI_SYMBOL; 547 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 + 548 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + 549 (p[6] - '0') * 10 + (p[7] - '0'); 550 } 551 } 552 printf("\n"); 553 device_printf(sc->dev, "%s Firmware: ", 554 sc->sc_firmware_type == WI_LUCENT ? "Lucent" : 555 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")); 556 557 /* 558 * The primary firmware is only valid on Prism based chipsets 559 * (INTERSIL or SYMBOL). 560 */ 561 if (sc->sc_firmware_type != WI_LUCENT) 562 printf("Primary %u.%02u.%02u, ", sc->sc_pri_firmware_ver / 10000, 563 (sc->sc_pri_firmware_ver % 10000) / 100, 564 sc->sc_pri_firmware_ver % 100); 565 printf("Station %u.%02u.%02u\n", 566 sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100, 567 sc->sc_sta_firmware_ver % 100); 568 return; 569} 570 571static void 572wi_rxeof(sc) 573 struct wi_softc *sc; 574{ 575 struct ifnet *ifp; 576 struct ether_header *eh; 577 struct mbuf *m; 578 int id; 579 580 ifp = &sc->arpcom.ac_if; 581 582 id = CSR_READ_2(sc, WI_RX_FID); 583 584 /* 585 * if we have the procframe flag set, disregard all this and just 586 * read the data from the device. 587 */ 588 if (sc->wi_procframe || sc->wi_debug.wi_monitor) { 589 struct wi_frame *rx_frame; 590 int datlen, hdrlen; 591 592 /* first allocate mbuf for packet storage */ 593 MGETHDR(m, M_DONTWAIT, MT_DATA); 594 if (m == NULL) { 595 ifp->if_ierrors++; 596 return; 597 } 598 MCLGET(m, M_DONTWAIT); 599 if (!(m->m_flags & M_EXT)) { 600 m_freem(m); 601 ifp->if_ierrors++; 602 return; 603 } 604 605 m->m_pkthdr.rcvif = ifp; 606 607 /* now read wi_frame first so we know how much data to read */ 608 if (wi_read_data(sc, id, 0, mtod(m, caddr_t), 609 sizeof(struct wi_frame))) { 610 m_freem(m); 611 ifp->if_ierrors++; 612 return; 613 } 614 615 rx_frame = mtod(m, struct wi_frame *); 616 617 switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) { 618 case 7: 619 switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) { 620 case WI_FTYPE_DATA: 621 hdrlen = WI_DATA_HDRLEN; 622 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 623 break; 624 case WI_FTYPE_MGMT: 625 hdrlen = WI_MGMT_HDRLEN; 626 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 627 break; 628 case WI_FTYPE_CTL: 629 /* 630 * prism2 cards don't pass control packets 631 * down properly or consistently, so we'll only 632 * pass down the header. 633 */ 634 hdrlen = WI_CTL_HDRLEN; 635 datlen = 0; 636 break; 637 default: 638 device_printf(sc->dev, "received packet of " 639 "unknown type on port 7\n"); 640 m_freem(m); 641 ifp->if_ierrors++; 642 return; 643 } 644 break; 645 case 0: 646 hdrlen = WI_DATA_HDRLEN; 647 datlen = rx_frame->wi_dat_len + WI_FCS_LEN; 648 break; 649 default: 650 device_printf(sc->dev, "received packet on invalid " 651 "port (wi_status=0x%x)\n", rx_frame->wi_status); 652 m_freem(m); 653 ifp->if_ierrors++; 654 return; 655 } 656 657 if ((hdrlen + datlen + 2) > MCLBYTES) { 658 device_printf(sc->dev, "oversized packet received " 659 "(wi_dat_len=%d, wi_status=0x%x)\n", 660 datlen, rx_frame->wi_status); 661 m_freem(m); 662 ifp->if_ierrors++; 663 return; 664 } 665 666 if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen, 667 datlen + 2)) { 668 m_freem(m); 669 ifp->if_ierrors++; 670 return; 671 } 672 673 m->m_pkthdr.len = m->m_len = hdrlen + datlen; 674 675 ifp->if_ipackets++; 676 677 /* Handle BPF listeners. */ 678 if (ifp->if_bpf) 679 bpf_mtap(ifp, m); 680 681 m_freem(m); 682 } else { 683 struct wi_frame rx_frame; 684 685 /* First read in the frame header */ 686 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, 687 sizeof(rx_frame))) { 688 ifp->if_ierrors++; 689 return; 690 } 691 692 if (rx_frame.wi_status & WI_STAT_ERRSTAT) { 693 ifp->if_ierrors++; 694 return; 695 } 696 697 MGETHDR(m, M_DONTWAIT, MT_DATA); 698 if (m == NULL) { 699 ifp->if_ierrors++; 700 return; 701 } 702 MCLGET(m, M_DONTWAIT); 703 if (!(m->m_flags & M_EXT)) { 704 m_freem(m); 705 ifp->if_ierrors++; 706 return; 707 } 708 709 eh = mtod(m, struct ether_header *); 710 m->m_pkthdr.rcvif = ifp; 711 712 if (rx_frame.wi_status == WI_STAT_MGMT && 713 sc->wi_ptype == WI_PORTTYPE_HOSTAP) { 714 if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) > 715 MCLBYTES) { 716 device_printf(sc->dev, "oversized mgmt packet " 717 "received in hostap mode " 718 "(wi_dat_len=%d, wi_status=0x%x)\n", 719 rx_frame.wi_dat_len, rx_frame.wi_status); 720 m_freem(m); 721 ifp->if_ierrors++; 722 return; 723 } 724 725 /* Put the whole header in there. */ 726 bcopy(&rx_frame, mtod(m, void *), 727 sizeof(struct wi_frame)); 728 if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW, 729 mtod(m, caddr_t) + WI_802_11_OFFSET_RAW, 730 rx_frame.wi_dat_len + 2)) { 731 m_freem(m); 732 ifp->if_ierrors++; 733 return; 734 } 735 m->m_pkthdr.len = m->m_len = 736 WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len; 737 /* XXX: consider giving packet to bhp? */ 738 wihap_mgmt_input(sc, &rx_frame, m); 739 return; 740 } 741 742 if (rx_frame.wi_status == WI_STAT_1042 || 743 rx_frame.wi_status == WI_STAT_TUNNEL || 744 rx_frame.wi_status == WI_STAT_WMP_MSG) { 745 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { 746 device_printf(sc->dev, 747 "oversized packet received " 748 "(wi_dat_len=%d, wi_status=0x%x)\n", 749 rx_frame.wi_dat_len, rx_frame.wi_status); 750 m_freem(m); 751 ifp->if_ierrors++; 752 return; 753 } 754 m->m_pkthdr.len = m->m_len = 755 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 756 757#if 0 758 bcopy((char *)&rx_frame.wi_addr1, 759 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 760 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) { 761 bcopy((char *)&rx_frame.wi_addr2, 762 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 763 } else { 764 bcopy((char *)&rx_frame.wi_addr3, 765 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 766 } 767#else 768 bcopy((char *)&rx_frame.wi_dst_addr, 769 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 770 bcopy((char *)&rx_frame.wi_src_addr, 771 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 772#endif 773 774 bcopy((char *)&rx_frame.wi_type, 775 (char *)&eh->ether_type, ETHER_TYPE_LEN); 776 777 if (wi_read_data(sc, id, WI_802_11_OFFSET, 778 mtod(m, caddr_t) + sizeof(struct ether_header), 779 m->m_len + 2)) { 780 m_freem(m); 781 ifp->if_ierrors++; 782 return; 783 } 784 } else { 785 if((rx_frame.wi_dat_len + 786 sizeof(struct ether_header)) > MCLBYTES) { 787 device_printf(sc->dev, 788 "oversized packet received " 789 "(wi_dat_len=%d, wi_status=0x%x)\n", 790 rx_frame.wi_dat_len, rx_frame.wi_status); 791 m_freem(m); 792 ifp->if_ierrors++; 793 return; 794 } 795 m->m_pkthdr.len = m->m_len = 796 rx_frame.wi_dat_len + sizeof(struct ether_header); 797 798 if (wi_read_data(sc, id, WI_802_3_OFFSET, 799 mtod(m, caddr_t), m->m_len + 2)) { 800 m_freem(m); 801 ifp->if_ierrors++; 802 return; 803 } 804 } 805 806 ifp->if_ipackets++; 807 808 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) { 809 /* 810 * Give host AP code first crack at data 811 * packets. If it decides to handle it (or 812 * drop it), it will return a non-zero. 813 * Otherwise, it is destined for this host. 814 */ 815 if (wihap_data_input(sc, &rx_frame, m)) 816 return; 817 } 818 /* Receive packet. */ 819 m_adj(m, sizeof(struct ether_header)); 820#ifdef WICACHE 821 wi_cache_store(sc, eh, m, rx_frame.wi_q_info); 822#endif 823 ether_input(ifp, eh, m); 824 } 825} 826 827static void 828wi_txeof(sc, status) 829 struct wi_softc *sc; 830 int status; 831{ 832 struct ifnet *ifp; 833 834 ifp = &sc->arpcom.ac_if; 835 836 ifp->if_timer = 0; 837 ifp->if_flags &= ~IFF_OACTIVE; 838 839 if (status & WI_EV_TX_EXC) 840 ifp->if_oerrors++; 841 else 842 ifp->if_opackets++; 843 844 return; 845} 846 847static void 848wi_inquire(xsc) 849 void *xsc; 850{ 851 struct wi_softc *sc; 852 struct ifnet *ifp; 853 int s; 854 855 sc = xsc; 856 ifp = &sc->arpcom.ac_if; 857 858 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 859 860 /* Don't do this while we're transmitting */ 861 if (ifp->if_flags & IFF_OACTIVE) 862 return; 863 864 WI_LOCK(sc, s); 865 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0); 866 WI_UNLOCK(sc, s); 867 868 return; 869} 870 871static void 872wi_update_stats(sc) 873 struct wi_softc *sc; 874{ 875 struct wi_ltv_gen gen; 876 u_int16_t id; 877 struct ifnet *ifp; 878 u_int32_t *ptr; 879 int len, i; 880 u_int16_t t; 881 882 ifp = &sc->arpcom.ac_if; 883 884 id = CSR_READ_2(sc, WI_INFO_FID); 885 886 wi_read_data(sc, id, 0, (char *)&gen, 4); 887 888 /* 889 * if we just got our scan results, copy it over into the scan buffer 890 * so we can return it to anyone that asks for it. (add a little 891 * compatibility with the prism2 scanning mechanism) 892 */ 893 if (gen.wi_type == WI_INFO_SCAN_RESULTS) 894 { 895 sc->wi_scanbuf_len = gen.wi_len; 896 wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf, 897 sc->wi_scanbuf_len * 2); 898 899 return; 900 } 901 else if (gen.wi_type != WI_INFO_COUNTERS) 902 return; 903 904 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ? 905 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4; 906 ptr = (u_int32_t *)&sc->wi_stats; 907 908 for (i = 0; i < len - 1; i++) { 909 t = CSR_READ_2(sc, WI_DATA1); 910#ifdef WI_HERMES_STATS_WAR 911 if (t > 0xF000) 912 t = ~t & 0xFFFF; 913#endif 914 ptr[i] += t; 915 } 916 917 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 918 sc->wi_stats.wi_tx_multi_retries + 919 sc->wi_stats.wi_tx_retry_limit; 920 921 return; 922} 923 924static void 925wi_intr(xsc) 926 void *xsc; 927{ 928 struct wi_softc *sc = xsc; 929 struct ifnet *ifp; 930 u_int16_t status; 931 int s; 932 933 WI_LOCK(sc, s); 934 935 ifp = &sc->arpcom.ac_if; 936 937 if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) { 938 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 939 CSR_WRITE_2(sc, WI_INT_EN, 0); 940 WI_UNLOCK(sc, s); 941 return; 942 } 943 944 /* Disable interrupts. */ 945 CSR_WRITE_2(sc, WI_INT_EN, 0); 946 947 status = CSR_READ_2(sc, WI_EVENT_STAT); 948 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS); 949 950 if (status & WI_EV_RX) { 951 wi_rxeof(sc); 952 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); 953 } 954 955 if (status & WI_EV_TX) { 956 wi_txeof(sc, status); 957 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX); 958 } 959 960 if (status & WI_EV_ALLOC) { 961 int id; 962 963 id = CSR_READ_2(sc, WI_ALLOC_FID); 964 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 965 if (id == sc->wi_tx_data_id) 966 wi_txeof(sc, status); 967 } 968 969 if (status & WI_EV_INFO) { 970 wi_update_stats(sc); 971 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); 972 } 973 974 if (status & WI_EV_TX_EXC) { 975 wi_txeof(sc, status); 976 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); 977 } 978 979 if (status & WI_EV_INFO_DROP) { 980 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP); 981 } 982 983 /* Re-enable interrupts. */ 984 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 985 986 if (ifp->if_snd.ifq_head != NULL) { 987 wi_start(ifp); 988 } 989 990 WI_UNLOCK(sc, s); 991 992 return; 993} 994 995static int 996wi_cmd(sc, cmd, val0, val1, val2) 997 struct wi_softc *sc; 998 int cmd; 999 int val0; 1000 int val1; 1001 int val2; 1002{ 1003 int i, s = 0; 1004 static volatile int count = 0; 1005 1006 if (count > 1) 1007 panic("Hey partner, hold on there!"); 1008 count++; 1009 1010 /* wait for the busy bit to clear */ 1011 for (i = 500; i > 0; i--) { /* 5s */ 1012 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { 1013 break; 1014 } 1015 DELAY(10*1000); /* 10 m sec */ 1016 } 1017 if (i == 0) { 1018 device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" ); 1019 count--; 1020 return(ETIMEDOUT); 1021 } 1022 1023 CSR_WRITE_2(sc, WI_PARAM0, val0); 1024 CSR_WRITE_2(sc, WI_PARAM1, val1); 1025 CSR_WRITE_2(sc, WI_PARAM2, val2); 1026 CSR_WRITE_2(sc, WI_COMMAND, cmd); 1027 1028 for (i = 0; i < WI_TIMEOUT; i++) { 1029 /* 1030 * Wait for 'command complete' bit to be 1031 * set in the event status register. 1032 */ 1033 s = CSR_READ_2(sc, WI_EVENT_STAT); 1034 if (s & WI_EV_CMD) { 1035 /* Ack the event and read result code. */ 1036 s = CSR_READ_2(sc, WI_STATUS); 1037 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 1038#ifdef foo 1039 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK)) 1040 return(EIO); 1041#endif 1042 if (s & WI_STAT_CMD_RESULT) { 1043 count--; 1044 return(EIO); 1045 } 1046 break; 1047 } 1048 DELAY(WI_DELAY); 1049 } 1050 1051 count--; 1052 if (i == WI_TIMEOUT) { 1053 device_printf(sc->dev, 1054 "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s); 1055 return(ETIMEDOUT); 1056 } 1057 return(0); 1058} 1059 1060static void 1061wi_reset(sc) 1062 struct wi_softc *sc; 1063{ 1064#define WI_INIT_TRIES 3 1065 int i; 1066 int tries; 1067 1068 /* Symbol firmware cannot be initialized more than once */ 1069 if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_enabled) 1070 return; 1071 if (sc->sc_firmware_type == WI_SYMBOL) 1072 tries = 1; 1073 else 1074 tries = WI_INIT_TRIES; 1075 1076 for (i = 0; i < tries; i++) { 1077 if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0) 1078 break; 1079 DELAY(WI_DELAY * 1000); 1080 } 1081 sc->sc_enabled = 1; 1082 1083 if (i == tries) { 1084 device_printf(sc->dev, "init failed\n"); 1085 return; 1086 } 1087 1088 CSR_WRITE_2(sc, WI_INT_EN, 0); 1089 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 1090 1091 /* Calibrate timer. */ 1092 WI_SETVAL(WI_RID_TICK_TIME, 8); 1093 1094 return; 1095} 1096 1097/* 1098 * Read an LTV record from the NIC. 1099 */ 1100static int 1101wi_read_record(sc, ltv) 1102 struct wi_softc *sc; 1103 struct wi_ltv_gen *ltv; 1104{ 1105 u_int16_t *ptr; 1106 int i, len, code; 1107 struct wi_ltv_gen *oltv, p2ltv; 1108 1109 oltv = ltv; 1110 if (sc->sc_firmware_type != WI_LUCENT) { 1111 switch (ltv->wi_type) { 1112 case WI_RID_ENCRYPTION: 1113 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1114 p2ltv.wi_len = 2; 1115 ltv = &p2ltv; 1116 break; 1117 case WI_RID_TX_CRYPT_KEY: 1118 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1119 p2ltv.wi_len = 2; 1120 ltv = &p2ltv; 1121 break; 1122 case WI_RID_ROAMING_MODE: 1123 if (sc->sc_firmware_type == WI_INTERSIL) 1124 break; 1125 /* not supported */ 1126 ltv->wi_len = 1; 1127 return 0; 1128 case WI_RID_MICROWAVE_OVEN: 1129 /* not supported */ 1130 ltv->wi_len = 1; 1131 return 0; 1132 } 1133 } 1134 1135 /* Tell the NIC to enter record read mode. */ 1136 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0)) 1137 return(EIO); 1138 1139 /* Seek to the record. */ 1140 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1141 return(EIO); 1142 1143 /* 1144 * Read the length and record type and make sure they 1145 * match what we expect (this verifies that we have enough 1146 * room to hold all of the returned data). 1147 */ 1148 len = CSR_READ_2(sc, WI_DATA1); 1149 if (len > ltv->wi_len) 1150 return(ENOSPC); 1151 code = CSR_READ_2(sc, WI_DATA1); 1152 if (code != ltv->wi_type) 1153 return(EIO); 1154 1155 ltv->wi_len = len; 1156 ltv->wi_type = code; 1157 1158 /* Now read the data. */ 1159 ptr = <v->wi_val; 1160 for (i = 0; i < ltv->wi_len - 1; i++) 1161 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1162 1163 if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS 1164 && ltv->wi_val == sc->wi_ibss_port) { 1165 /* 1166 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS. 1167 * Since Lucent uses port type 1 for BSS *and* IBSS we 1168 * have to rely on wi_ptype to distinguish this for us. 1169 */ 1170 ltv->wi_val = htole16(WI_PORTTYPE_IBSS); 1171 } else if (sc->sc_firmware_type != WI_LUCENT) { 1172 switch (oltv->wi_type) { 1173 case WI_RID_TX_RATE: 1174 case WI_RID_CUR_TX_RATE: 1175 switch (ltv->wi_val) { 1176 case 1: oltv->wi_val = 1; break; 1177 case 2: oltv->wi_val = 2; break; 1178 case 3: oltv->wi_val = 6; break; 1179 case 4: oltv->wi_val = 5; break; 1180 case 7: oltv->wi_val = 7; break; 1181 case 8: oltv->wi_val = 11; break; 1182 case 15: oltv->wi_val = 3; break; 1183 default: oltv->wi_val = 0x100 + ltv->wi_val; break; 1184 } 1185 break; 1186 case WI_RID_ENCRYPTION: 1187 oltv->wi_len = 2; 1188 if (ltv->wi_val & 0x01) 1189 oltv->wi_val = 1; 1190 else 1191 oltv->wi_val = 0; 1192 break; 1193 case WI_RID_TX_CRYPT_KEY: 1194 oltv->wi_len = 2; 1195 oltv->wi_val = ltv->wi_val; 1196 break; 1197 case WI_RID_CNFAUTHMODE: 1198 oltv->wi_len = 2; 1199 if (le16toh(ltv->wi_val) & 0x01) 1200 oltv->wi_val = htole16(1); 1201 else if (le16toh(ltv->wi_val) & 0x02) 1202 oltv->wi_val = htole16(2); 1203 break; 1204 } 1205 } 1206 1207 return(0); 1208} 1209 1210/* 1211 * Same as read, except we inject data instead of reading it. 1212 */ 1213static int 1214wi_write_record(sc, ltv) 1215 struct wi_softc *sc; 1216 struct wi_ltv_gen *ltv; 1217{ 1218 uint16_t *ptr; 1219 uint16_t val; 1220 int i; 1221 struct wi_ltv_gen p2ltv; 1222 1223 if (ltv->wi_type == WI_RID_PORTTYPE && 1224 le16toh(ltv->wi_val) == WI_PORTTYPE_IBSS) { 1225 /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */ 1226 p2ltv.wi_type = WI_RID_PORTTYPE; 1227 p2ltv.wi_len = 2; 1228 p2ltv.wi_val = sc->wi_ibss_port; 1229 ltv = &p2ltv; 1230 } else if (sc->sc_firmware_type != WI_LUCENT) { 1231 switch (ltv->wi_type) { 1232 case WI_RID_TX_RATE: 1233 p2ltv.wi_type = WI_RID_TX_RATE; 1234 p2ltv.wi_len = 2; 1235 switch (ltv->wi_val) { 1236 case 1: p2ltv.wi_val = 1; break; 1237 case 2: p2ltv.wi_val = 2; break; 1238 case 3: p2ltv.wi_val = 15; break; 1239 case 5: p2ltv.wi_val = 4; break; 1240 case 6: p2ltv.wi_val = 3; break; 1241 case 7: p2ltv.wi_val = 7; break; 1242 case 11: p2ltv.wi_val = 8; break; 1243 default: return EINVAL; 1244 } 1245 p2ltv.wi_val = htole16(p2ltv.wi_val); 1246 ltv = &p2ltv; 1247 break; 1248 case WI_RID_ENCRYPTION: 1249 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1250 p2ltv.wi_len = 2; 1251 if (ltv->wi_val & htole16(0x01)) { 1252 val = PRIVACY_INVOKED; 1253 /* 1254 * If using shared key WEP we must set the 1255 * EXCLUDE_UNENCRYPTED bit. Symbol cards 1256 * need this bit set even when not using 1257 * shared key. We can't just test for 1258 * IEEE80211_AUTH_SHARED since Symbol cards 1259 * have 2 shared key modes. 1260 */ 1261 if (sc->wi_authtype != IEEE80211_AUTH_OPEN || 1262 sc->sc_firmware_type == WI_SYMBOL) 1263 val |= EXCLUDE_UNENCRYPTED; 1264 /* TX encryption is broken in Host AP mode. */ 1265 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) 1266 val |= HOST_ENCRYPT; 1267 } else 1268 val = HOST_ENCRYPT | HOST_DECRYPT; 1269 p2ltv.wi_val = htole16(val); 1270 ltv = &p2ltv; 1271 break; 1272 case WI_RID_TX_CRYPT_KEY: 1273 if (ltv->wi_val > WI_NLTV_KEYS) 1274 return (EINVAL); 1275 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1276 p2ltv.wi_len = 2; 1277 p2ltv.wi_val = ltv->wi_val; 1278 ltv = &p2ltv; 1279 break; 1280 case WI_RID_DEFLT_CRYPT_KEYS: 1281 { 1282 int error; 1283 int keylen; 1284 struct wi_ltv_str ws; 1285 struct wi_ltv_keys *wk = 1286 (struct wi_ltv_keys *)ltv; 1287 1288 keylen = wk->wi_keys[sc->wi_tx_key].wi_keylen; 1289 1290 for (i = 0; i < 4; i++) { 1291 bzero(&ws, sizeof(ws)); 1292 ws.wi_len = (keylen > 5) ? 8 : 4; 1293 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 1294 memcpy(ws.wi_str, 1295 &wk->wi_keys[i].wi_keydat, keylen); 1296 error = wi_write_record(sc, 1297 (struct wi_ltv_gen *)&ws); 1298 if (error) 1299 return error; 1300 } 1301 return 0; 1302 } 1303 case WI_RID_CNFAUTHMODE: 1304 p2ltv.wi_type = WI_RID_CNFAUTHMODE; 1305 p2ltv.wi_len = 2; 1306 if (le16toh(ltv->wi_val) == 1) 1307 p2ltv.wi_val = htole16(0x01); 1308 else if (le16toh(ltv->wi_val) == 2) 1309 p2ltv.wi_val = htole16(0x02); 1310 ltv = &p2ltv; 1311 break; 1312 case WI_RID_ROAMING_MODE: 1313 if (sc->sc_firmware_type == WI_INTERSIL) 1314 break; 1315 /* not supported */ 1316 return 0; 1317 case WI_RID_MICROWAVE_OVEN: 1318 /* not supported */ 1319 return 0; 1320 } 1321 } else { 1322 /* LUCENT */ 1323 switch (ltv->wi_type) { 1324 case WI_RID_TX_RATE: 1325 switch (ltv->wi_val) { 1326 case 1: ltv->wi_val = 1; break; /* 1Mb/s fixed */ 1327 case 2: ltv->wi_val = 2; break; /* 2Mb/s fixed */ 1328 case 3: ltv->wi_val = 3; break; /* 11Mb/s auto */ 1329 case 5: ltv->wi_val = 4; break; /* 5.5Mb/s fixed */ 1330 case 6: ltv->wi_val = 6; break; /* 2Mb/s auto */ 1331 case 7: ltv->wi_val = 7; break; /* 5.5Mb/s auto */ 1332 case 11: ltv->wi_val = 5; break; /* 11Mb/s fixed */ 1333 default: return EINVAL; 1334 } 1335 case WI_RID_TX_CRYPT_KEY: 1336 if (ltv->wi_val > WI_NLTV_KEYS) 1337 return (EINVAL); 1338 break; 1339 } 1340 } 1341 1342 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1343 return(EIO); 1344 1345 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 1346 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 1347 1348 ptr = <v->wi_val; 1349 for (i = 0; i < ltv->wi_len - 1; i++) 1350 CSR_WRITE_2(sc, WI_DATA1, ptr[i]); 1351 1352 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0)) 1353 return(EIO); 1354 1355 return(0); 1356} 1357 1358static int 1359wi_seek(sc, id, off, chan) 1360 struct wi_softc *sc; 1361 int id, off, chan; 1362{ 1363 int i; 1364 int selreg, offreg; 1365 int status; 1366 1367 switch (chan) { 1368 case WI_BAP0: 1369 selreg = WI_SEL0; 1370 offreg = WI_OFF0; 1371 break; 1372 case WI_BAP1: 1373 selreg = WI_SEL1; 1374 offreg = WI_OFF1; 1375 break; 1376 default: 1377 device_printf(sc->dev, "invalid data path: %x\n", chan); 1378 return(EIO); 1379 } 1380 1381 CSR_WRITE_2(sc, selreg, id); 1382 CSR_WRITE_2(sc, offreg, off); 1383 1384 for (i = 0; i < WI_TIMEOUT; i++) { 1385 status = CSR_READ_2(sc, offreg); 1386 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR))) 1387 break; 1388 DELAY(WI_DELAY); 1389 } 1390 1391 if (i == WI_TIMEOUT) { 1392 device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n", 1393 id, off, status); 1394 return(ETIMEDOUT); 1395 } 1396 1397 return(0); 1398} 1399 1400static int 1401wi_read_data(sc, id, off, buf, len) 1402 struct wi_softc *sc; 1403 int id, off; 1404 caddr_t buf; 1405 int len; 1406{ 1407 int i; 1408 u_int16_t *ptr; 1409 1410 if (wi_seek(sc, id, off, WI_BAP1)) 1411 return(EIO); 1412 1413 ptr = (u_int16_t *)buf; 1414 for (i = 0; i < len / 2; i++) 1415 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1416 1417 return(0); 1418} 1419 1420/* 1421 * According to the comments in the HCF Light code, there is a bug in 1422 * the Hermes (or possibly in certain Hermes firmware revisions) where 1423 * the chip's internal autoincrement counter gets thrown off during 1424 * data writes: the autoincrement is missed, causing one data word to 1425 * be overwritten and subsequent words to be written to the wrong memory 1426 * locations. The end result is that we could end up transmitting bogus 1427 * frames without realizing it. The workaround for this is to write a 1428 * couple of extra guard words after the end of the transfer, then 1429 * attempt to read then back. If we fail to locate the guard words where 1430 * we expect them, we preform the transfer over again. 1431 */ 1432static int 1433wi_write_data(sc, id, off, buf, len) 1434 struct wi_softc *sc; 1435 int id, off; 1436 caddr_t buf; 1437 int len; 1438{ 1439 int i; 1440 u_int16_t *ptr; 1441#ifdef WI_HERMES_AUTOINC_WAR 1442 int retries; 1443 1444 retries = 512; 1445again: 1446#endif 1447 1448 if (wi_seek(sc, id, off, WI_BAP0)) 1449 return(EIO); 1450 1451 ptr = (u_int16_t *)buf; 1452 for (i = 0; i < (len / 2); i++) 1453 CSR_WRITE_2(sc, WI_DATA0, ptr[i]); 1454 1455#ifdef WI_HERMES_AUTOINC_WAR 1456 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 1457 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 1458 1459 if (wi_seek(sc, id, off + len, WI_BAP0)) 1460 return(EIO); 1461 1462 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 1463 CSR_READ_2(sc, WI_DATA0) != 0x5678) { 1464 if (--retries >= 0) 1465 goto again; 1466 device_printf(sc->dev, "wi_write_data device timeout\n"); 1467 return (EIO); 1468 } 1469#endif 1470 1471 return(0); 1472} 1473 1474/* 1475 * Allocate a region of memory inside the NIC and zero 1476 * it out. 1477 */ 1478static int 1479wi_alloc_nicmem(sc, len, id) 1480 struct wi_softc *sc; 1481 int len; 1482 int *id; 1483{ 1484 int i; 1485 1486 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) { 1487 device_printf(sc->dev, 1488 "failed to allocate %d bytes on NIC\n", len); 1489 return(ENOMEM); 1490 } 1491 1492 for (i = 0; i < WI_TIMEOUT; i++) { 1493 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 1494 break; 1495 DELAY(WI_DELAY); 1496 } 1497 1498 if (i == WI_TIMEOUT) { 1499 device_printf(sc->dev, "time out allocating memory on card\n"); 1500 return(ETIMEDOUT); 1501 } 1502 1503 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 1504 *id = CSR_READ_2(sc, WI_ALLOC_FID); 1505 1506 if (wi_seek(sc, *id, 0, WI_BAP0)) { 1507 device_printf(sc->dev, "seek failed while allocating memory on card\n"); 1508 return(EIO); 1509 } 1510 1511 for (i = 0; i < len / 2; i++) 1512 CSR_WRITE_2(sc, WI_DATA0, 0); 1513 1514 return(0); 1515} 1516 1517static void 1518wi_setmulti(sc) 1519 struct wi_softc *sc; 1520{ 1521 struct ifnet *ifp; 1522 int i = 0; 1523 struct ifmultiaddr *ifma; 1524 struct wi_ltv_mcast mcast; 1525 1526 ifp = &sc->arpcom.ac_if; 1527 1528 bzero((char *)&mcast, sizeof(mcast)); 1529 1530 mcast.wi_type = WI_RID_MCAST_LIST; 1531 mcast.wi_len = (3 * 16) + 1; 1532 1533 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 1534 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1535 return; 1536 } 1537 1538#if __FreeBSD_version < 500000 1539 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1540#else 1541 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1542#endif 1543 if (ifma->ifma_addr->sa_family != AF_LINK) 1544 continue; 1545 if (i < 16) { 1546 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 1547 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN); 1548 i++; 1549 } else { 1550 bzero((char *)&mcast, sizeof(mcast)); 1551 break; 1552 } 1553 } 1554 1555 mcast.wi_len = (i * 3) + 1; 1556 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1557 1558 return; 1559} 1560 1561static void 1562wi_setdef(sc, wreq) 1563 struct wi_softc *sc; 1564 struct wi_req *wreq; 1565{ 1566 struct sockaddr_dl *sdl; 1567 struct ifaddr *ifa; 1568 struct ifnet *ifp; 1569 1570 ifp = &sc->arpcom.ac_if; 1571 1572 switch(wreq->wi_type) { 1573 case WI_RID_MAC_NODE: 1574 ifa = ifaddr_byindex(ifp->if_index); 1575 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1576 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr, 1577 ETHER_ADDR_LEN); 1578 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 1579 break; 1580 case WI_RID_PORTTYPE: 1581 sc->wi_ptype = le16toh(wreq->wi_val[0]); 1582 break; 1583 case WI_RID_TX_RATE: 1584 sc->wi_tx_rate = le16toh(wreq->wi_val[0]); 1585 break; 1586 case WI_RID_MAX_DATALEN: 1587 sc->wi_max_data_len = le16toh(wreq->wi_val[0]); 1588 break; 1589 case WI_RID_RTS_THRESH: 1590 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]); 1591 break; 1592 case WI_RID_SYSTEM_SCALE: 1593 sc->wi_ap_density = le16toh(wreq->wi_val[0]); 1594 break; 1595 case WI_RID_CREATE_IBSS: 1596 sc->wi_create_ibss = le16toh(wreq->wi_val[0]); 1597 break; 1598 case WI_RID_OWN_CHNL: 1599 sc->wi_channel = le16toh(wreq->wi_val[0]); 1600 break; 1601 case WI_RID_NODENAME: 1602 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 1603 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30); 1604 break; 1605 case WI_RID_DESIRED_SSID: 1606 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 1607 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30); 1608 break; 1609 case WI_RID_OWN_SSID: 1610 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 1611 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30); 1612 break; 1613 case WI_RID_PM_ENABLED: 1614 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]); 1615 break; 1616 case WI_RID_MICROWAVE_OVEN: 1617 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]); 1618 break; 1619 case WI_RID_MAX_SLEEP: 1620 sc->wi_max_sleep = le16toh(wreq->wi_val[0]); 1621 break; 1622 case WI_RID_CNFAUTHMODE: 1623 sc->wi_authtype = le16toh(wreq->wi_val[0]); 1624 break; 1625 case WI_RID_ROAMING_MODE: 1626 sc->wi_roaming = le16toh(wreq->wi_val[0]); 1627 break; 1628 case WI_RID_ENCRYPTION: 1629 sc->wi_use_wep = le16toh(wreq->wi_val[0]); 1630 break; 1631 case WI_RID_TX_CRYPT_KEY: 1632 sc->wi_tx_key = le16toh(wreq->wi_val[0]); 1633 break; 1634 case WI_RID_DEFLT_CRYPT_KEYS: 1635 bcopy((char *)wreq, (char *)&sc->wi_keys, 1636 sizeof(struct wi_ltv_keys)); 1637 break; 1638 default: 1639 break; 1640 } 1641 1642 /* Reinitialize WaveLAN. */ 1643 wi_init(sc); 1644 1645 return; 1646} 1647 1648static int 1649wi_ioctl(ifp, command, data) 1650 struct ifnet *ifp; 1651 u_long command; 1652 caddr_t data; 1653{ 1654 int error = 0; 1655 int len; 1656 int s; 1657 uint16_t mif; 1658 uint16_t val; 1659 u_int8_t tmpkey[14]; 1660 char tmpssid[IEEE80211_NWID_LEN]; 1661 struct wi_softc *sc; 1662 struct wi_req wreq; 1663 struct ifreq *ifr; 1664 struct ieee80211req *ireq; 1665#if __FreeBSD_version >= 500000 1666 struct thread *td = curthread; 1667#else 1668 struct proc *td = curproc; /* Little white lie */ 1669#endif 1670 1671 sc = ifp->if_softc; 1672 WI_LOCK(sc, s); 1673 ifr = (struct ifreq *)data; 1674 ireq = (struct ieee80211req *)data; 1675 1676 if (sc->wi_gone) { 1677 error = ENODEV; 1678 goto out; 1679 } 1680 1681 switch(command) { 1682 case SIOCSIFADDR: 1683 case SIOCGIFADDR: 1684 case SIOCSIFMTU: 1685 error = ether_ioctl(ifp, command, data); 1686 break; 1687 case SIOCSIFFLAGS: 1688 /* 1689 * Can't do promisc and hostap at the same time. If all that's 1690 * changing is the promisc flag, try to short-circuit a call to 1691 * wi_init() by just setting PROMISC in the hardware. 1692 */ 1693 if (ifp->if_flags & IFF_UP) { 1694 if (sc->wi_ptype != WI_PORTTYPE_HOSTAP && 1695 ifp->if_flags & IFF_RUNNING) { 1696 if (ifp->if_flags & IFF_PROMISC && 1697 !(sc->wi_if_flags & IFF_PROMISC)) { 1698 WI_SETVAL(WI_RID_PROMISC, 1); 1699 } else if (!(ifp->if_flags & IFF_PROMISC) && 1700 sc->wi_if_flags & IFF_PROMISC) { 1701 WI_SETVAL(WI_RID_PROMISC, 0); 1702 } else { 1703 wi_init(sc); 1704 } 1705 } else { 1706 wi_init(sc); 1707 } 1708 } else { 1709 if (ifp->if_flags & IFF_RUNNING) { 1710 wi_stop(sc); 1711 } 1712 } 1713 sc->wi_if_flags = ifp->if_flags; 1714 error = 0; 1715 break; 1716 case SIOCSIFMEDIA: 1717 case SIOCGIFMEDIA: 1718 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1719 break; 1720 case SIOCADDMULTI: 1721 case SIOCDELMULTI: 1722 wi_setmulti(sc); 1723 error = 0; 1724 break; 1725 case SIOCGWAVELAN: 1726 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1727 if (error) 1728 break; 1729 if (wreq.wi_len > WI_MAX_DATALEN) { 1730 error = EINVAL; 1731 break; 1732 } 1733 /* Don't show WEP keys to non-root users. */ 1734 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td)) 1735 break; 1736 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1737 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1738 sizeof(sc->wi_stats)); 1739 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1740 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) { 1741 bcopy((char *)&sc->wi_keys, (char *)&wreq, 1742 sizeof(struct wi_ltv_keys)); 1743 } 1744#ifdef WICACHE 1745 else if (wreq.wi_type == WI_RID_ZERO_CACHE) { 1746 sc->wi_sigitems = sc->wi_nextitem = 0; 1747 } else if (wreq.wi_type == WI_RID_READ_CACHE) { 1748 char *pt = (char *)&wreq.wi_val; 1749 bcopy((char *)&sc->wi_sigitems, 1750 (char *)pt, sizeof(int)); 1751 pt += (sizeof (int)); 1752 wreq.wi_len = sizeof(int) / 2; 1753 bcopy((char *)&sc->wi_sigcache, (char *)pt, 1754 sizeof(struct wi_sigcache) * sc->wi_sigitems); 1755 wreq.wi_len += ((sizeof(struct wi_sigcache) * 1756 sc->wi_sigitems) / 2) + 1; 1757 } 1758#endif 1759 else if (wreq.wi_type == WI_RID_PROCFRAME) { 1760 wreq.wi_len = 2; 1761 wreq.wi_val[0] = sc->wi_procframe; 1762 } else if (wreq.wi_type == WI_RID_PRISM2) { 1763 wreq.wi_len = 2; 1764 wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT; 1765 } else if (wreq.wi_type == WI_RID_SCAN_RES && 1766 sc->sc_firmware_type == WI_LUCENT) { 1767 memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf, 1768 sc->wi_scanbuf_len * 2); 1769 wreq.wi_len = sc->wi_scanbuf_len; 1770 } else if (wreq.wi_type == WI_RID_MIF) { 1771 mif = wreq.wi_val[0]; 1772 error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0); 1773 val = CSR_READ_2(sc, WI_RESP0); 1774 wreq.wi_len = 2; 1775 wreq.wi_val[0] = val; 1776 } else { 1777 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1778 error = EINVAL; 1779 break; 1780 } 1781 } 1782 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1783 break; 1784 case SIOCSWAVELAN: 1785 if ((error = suser(td))) 1786 goto out; 1787 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1788 if (error) 1789 break; 1790 if (wreq.wi_len > WI_MAX_DATALEN) { 1791 error = EINVAL; 1792 break; 1793 } 1794 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1795 error = EINVAL; 1796 break; 1797 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) { 1798 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1799 wreq.wi_len); 1800 } else if (wreq.wi_type == WI_RID_PROCFRAME) { 1801 sc->wi_procframe = wreq.wi_val[0]; 1802 /* 1803 * if we're getting a scan request from a wavelan card 1804 * (non-prism2), send out a cmd_inquire to the card to scan 1805 * results for the scan will be received through the info 1806 * interrupt handler. otherwise the scan request can be 1807 * directly handled by a prism2 card's rid interface. 1808 */ 1809 } else if (wreq.wi_type == WI_RID_SCAN_REQ && 1810 sc->sc_firmware_type == WI_LUCENT) { 1811 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); 1812 } else if (wreq.wi_type == WI_RID_MIF) { 1813 mif = wreq.wi_val[0]; 1814 val = wreq.wi_val[1]; 1815 error = wi_cmd(sc, WI_CMD_WRITEMIF, mif, val, 0); 1816 } else { 1817 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1818 if (!error) 1819 wi_setdef(sc, &wreq); 1820 } 1821 break; 1822 case SIOCGPRISM2DEBUG: 1823 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1824 if (error) 1825 break; 1826 if (!(ifp->if_flags & IFF_RUNNING) || 1827 sc->sc_firmware_type == WI_LUCENT) { 1828 error = EIO; 1829 break; 1830 } 1831 error = wi_get_debug(sc, &wreq); 1832 if (error == 0) 1833 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1834 break; 1835 case SIOCSPRISM2DEBUG: 1836 if ((error = suser(td))) 1837 goto out; 1838 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1839 if (error) 1840 break; 1841 error = wi_set_debug(sc, &wreq); 1842 break; 1843 case SIOCG80211: 1844 switch(ireq->i_type) { 1845 case IEEE80211_IOC_SSID: 1846 if(ireq->i_val == -1) { 1847 bzero(tmpssid, IEEE80211_NWID_LEN); 1848 error = wi_get_cur_ssid(sc, tmpssid, &len); 1849 if (error != 0) 1850 break; 1851 error = copyout(tmpssid, ireq->i_data, 1852 IEEE80211_NWID_LEN); 1853 ireq->i_len = len; 1854 } else if (ireq->i_val == 0) { 1855 error = copyout(sc->wi_net_name, 1856 ireq->i_data, 1857 IEEE80211_NWID_LEN); 1858 ireq->i_len = IEEE80211_NWID_LEN; 1859 } else 1860 error = EINVAL; 1861 break; 1862 case IEEE80211_IOC_NUMSSIDS: 1863 ireq->i_val = 1; 1864 break; 1865 case IEEE80211_IOC_WEP: 1866 if(!sc->wi_has_wep) { 1867 ireq->i_val = IEEE80211_WEP_NOSUP; 1868 } else { 1869 if(sc->wi_use_wep) { 1870 ireq->i_val = 1871 IEEE80211_WEP_MIXED; 1872 } else { 1873 ireq->i_val = 1874 IEEE80211_WEP_OFF; 1875 } 1876 } 1877 break; 1878 case IEEE80211_IOC_WEPKEY: 1879 if(!sc->wi_has_wep || 1880 ireq->i_val < 0 || ireq->i_val > 3) { 1881 error = EINVAL; 1882 break; 1883 } 1884 len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen; 1885 if (suser(td)) 1886 bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1887 tmpkey, len); 1888 else 1889 bzero(tmpkey, len); 1890 1891 ireq->i_len = len; 1892 error = copyout(tmpkey, ireq->i_data, len); 1893 1894 break; 1895 case IEEE80211_IOC_NUMWEPKEYS: 1896 if(!sc->wi_has_wep) 1897 error = EINVAL; 1898 else 1899 ireq->i_val = 4; 1900 break; 1901 case IEEE80211_IOC_WEPTXKEY: 1902 if(!sc->wi_has_wep) 1903 error = EINVAL; 1904 else 1905 ireq->i_val = sc->wi_tx_key; 1906 break; 1907 case IEEE80211_IOC_AUTHMODE: 1908 ireq->i_val = sc->wi_authmode; 1909 break; 1910 case IEEE80211_IOC_STATIONNAME: 1911 error = copyout(sc->wi_node_name, 1912 ireq->i_data, IEEE80211_NWID_LEN); 1913 ireq->i_len = IEEE80211_NWID_LEN; 1914 break; 1915 case IEEE80211_IOC_CHANNEL: 1916 wreq.wi_type = WI_RID_CURRENT_CHAN; 1917 wreq.wi_len = WI_MAX_DATALEN; 1918 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) 1919 error = EINVAL; 1920 else { 1921 ireq->i_val = wreq.wi_val[0]; 1922 } 1923 break; 1924 case IEEE80211_IOC_POWERSAVE: 1925 if(sc->wi_pm_enabled) 1926 ireq->i_val = IEEE80211_POWERSAVE_ON; 1927 else 1928 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1929 break; 1930 case IEEE80211_IOC_POWERSAVESLEEP: 1931 ireq->i_val = sc->wi_max_sleep; 1932 break; 1933 default: 1934 error = EINVAL; 1935 } 1936 break; 1937 case SIOCS80211: 1938 if ((error = suser(td))) 1939 goto out; 1940 switch(ireq->i_type) { 1941 case IEEE80211_IOC_SSID: 1942 if (ireq->i_val != 0 || 1943 ireq->i_len > IEEE80211_NWID_LEN) { 1944 error = EINVAL; 1945 break; 1946 } 1947 /* We set both of them */ 1948 bzero(sc->wi_net_name, IEEE80211_NWID_LEN); 1949 error = copyin(ireq->i_data, 1950 sc->wi_net_name, ireq->i_len); 1951 bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN); 1952 break; 1953 case IEEE80211_IOC_WEP: 1954 /* 1955 * These cards only support one mode so 1956 * we just turn wep on what ever is 1957 * passed in if it's not OFF. 1958 */ 1959 if (ireq->i_val == IEEE80211_WEP_OFF) { 1960 sc->wi_use_wep = 0; 1961 } else { 1962 sc->wi_use_wep = 1; 1963 } 1964 break; 1965 case IEEE80211_IOC_WEPKEY: 1966 if (ireq->i_val < 0 || ireq->i_val > 3 || 1967 ireq->i_len > 13) { 1968 error = EINVAL; 1969 break; 1970 } 1971 bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13); 1972 error = copyin(ireq->i_data, 1973 sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1974 ireq->i_len); 1975 if(error) 1976 break; 1977 sc->wi_keys.wi_keys[ireq->i_val].wi_keylen = 1978 ireq->i_len; 1979 break; 1980 case IEEE80211_IOC_WEPTXKEY: 1981 if (ireq->i_val < 0 || ireq->i_val > 3) { 1982 error = EINVAL; 1983 break; 1984 } 1985 sc->wi_tx_key = ireq->i_val; 1986 break; 1987 case IEEE80211_IOC_AUTHMODE: 1988 sc->wi_authmode = ireq->i_val; 1989 break; 1990 case IEEE80211_IOC_STATIONNAME: 1991 if (ireq->i_len > 32) { 1992 error = EINVAL; 1993 break; 1994 } 1995 bzero(sc->wi_node_name, 32); 1996 error = copyin(ireq->i_data, 1997 sc->wi_node_name, ireq->i_len); 1998 break; 1999 case IEEE80211_IOC_CHANNEL: 2000 /* 2001 * The actual range is 1-14, but if you 2002 * set it to 0 you get the default. So 2003 * we let that work too. 2004 */ 2005 if (ireq->i_val < 0 || ireq->i_val > 14) { 2006 error = EINVAL; 2007 break; 2008 } 2009 sc->wi_channel = ireq->i_val; 2010 break; 2011 case IEEE80211_IOC_POWERSAVE: 2012 switch (ireq->i_val) { 2013 case IEEE80211_POWERSAVE_OFF: 2014 sc->wi_pm_enabled = 0; 2015 break; 2016 case IEEE80211_POWERSAVE_ON: 2017 sc->wi_pm_enabled = 1; 2018 break; 2019 default: 2020 error = EINVAL; 2021 break; 2022 } 2023 break; 2024 case IEEE80211_IOC_POWERSAVESLEEP: 2025 if (ireq->i_val < 0) { 2026 error = EINVAL; 2027 break; 2028 } 2029 sc->wi_max_sleep = ireq->i_val; 2030 break; 2031 default: 2032 error = EINVAL; 2033 break; 2034 } 2035 2036 /* Reinitialize WaveLAN. */ 2037 wi_init(sc); 2038 2039 break; 2040 case SIOCHOSTAP_ADD: 2041 case SIOCHOSTAP_DEL: 2042 case SIOCHOSTAP_GET: 2043 case SIOCHOSTAP_GETALL: 2044 case SIOCHOSTAP_GFLAGS: 2045 case SIOCHOSTAP_SFLAGS: 2046 /* Send all Host AP specific ioctl's to Host AP code. */ 2047 error = wihap_ioctl(sc, command, data); 2048 break; 2049 default: 2050 error = EINVAL; 2051 break; 2052 } 2053out: 2054 WI_UNLOCK(sc, s); 2055 2056 return(error); 2057} 2058 2059static void 2060wi_init(xsc) 2061 void *xsc; 2062{ 2063 struct wi_softc *sc = xsc; 2064 struct ifnet *ifp = &sc->arpcom.ac_if; 2065 struct wi_ltv_macaddr mac; 2066 int id = 0; 2067 int s; 2068 2069 WI_LOCK(sc, s); 2070 2071 if (sc->wi_gone) { 2072 WI_UNLOCK(sc, s); 2073 return; 2074 } 2075 2076 if (ifp->if_flags & IFF_RUNNING) 2077 wi_stop(sc); 2078 2079 wi_reset(sc); 2080 2081 /* Program max data length. */ 2082 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 2083 2084 /* Set the port type. */ 2085 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 2086 2087 /* Enable/disable IBSS creation. */ 2088 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 2089 2090 /* Program the RTS/CTS threshold. */ 2091 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 2092 2093 /* Program the TX rate */ 2094 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 2095 2096 /* Access point density */ 2097 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 2098 2099 /* Power Management Enabled */ 2100 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 2101 2102 /* Power Managment Max Sleep */ 2103 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 2104 2105 /* Roaming type */ 2106 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming); 2107 2108 /* Specify the IBSS name */ 2109 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name); 2110 2111 /* Specify the network name */ 2112 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name); 2113 2114 /* Specify the frequency to use */ 2115 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 2116 2117 /* Program the nodename. */ 2118 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name); 2119 2120 /* Specify the authentication mode. */ 2121 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authmode); 2122 2123 /* Set our MAC address. */ 2124 mac.wi_len = 4; 2125 mac.wi_type = WI_RID_MAC_NODE; 2126 bcopy((char *)&sc->arpcom.ac_enaddr, 2127 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN); 2128 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 2129 2130 /* 2131 * Initialize promisc mode. 2132 * Being in the Host-AP mode causes 2133 * great deal of pain if promisc mode is set. 2134 * Therefore we avoid confusing the firmware 2135 * and always reset promisc mode in Host-AP regime, 2136 * it shows us all the packets anyway. 2137 */ 2138 if (sc->wi_ptype != WI_PORTTYPE_HOSTAP && ifp->if_flags & IFF_PROMISC) 2139 WI_SETVAL(WI_RID_PROMISC, 1); 2140 else 2141 WI_SETVAL(WI_RID_PROMISC, 0); 2142 2143 /* Configure WEP. */ 2144 if (sc->wi_has_wep) { 2145 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 2146 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 2147 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 2148 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 2149 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 2150 if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) { 2151 /* 2152 * ONLY HWB3163 EVAL-CARD Firmware version 2153 * less than 0.8 variant2 2154 * 2155 * If promiscuous mode disable, Prism2 chip 2156 * does not work with WEP. 2157 * It is under investigation for details. 2158 * (ichiro@netbsd.org) 2159 * 2160 * And make sure that we don't need to do it 2161 * in hostap mode, since it interferes with 2162 * the above hostap workaround. 2163 */ 2164 if (sc->wi_ptype != WI_PORTTYPE_HOSTAP && 2165 sc->sc_firmware_type == WI_INTERSIL && 2166 sc->sc_sta_firmware_ver < 802 ) { 2167 /* firm ver < 0.8 variant 2 */ 2168 WI_SETVAL(WI_RID_PROMISC, 1); 2169 } 2170 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authtype); 2171 } 2172 } 2173 2174 /* Set multicast filter. */ 2175 wi_setmulti(sc); 2176 2177 /* Enable desired port */ 2178 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0); 2179 2180 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 2181 device_printf(sc->dev, "tx buffer allocation failed\n"); 2182 sc->wi_tx_data_id = id; 2183 2184 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 2185 device_printf(sc->dev, "mgmt. buffer allocation failed\n"); 2186 sc->wi_tx_mgmt_id = id; 2187 2188 /* enable interrupts */ 2189 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 2190 2191 wihap_init(sc); 2192 2193 ifp->if_flags |= IFF_RUNNING; 2194 ifp->if_flags &= ~IFF_OACTIVE; 2195 2196 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 2197 WI_UNLOCK(sc, s); 2198 2199 return; 2200} 2201 2202#define RC4STATE 256 2203#define RC4KEYLEN 16 2204#define RC4SWAP(x,y) \ 2205 do { u_int8_t t = state[x]; state[x] = state[y]; state[y] = t; } while(0) 2206 2207static void 2208wi_do_hostencrypt(struct wi_softc *sc, caddr_t buf, int len) 2209{ 2210 u_int32_t i, crc, klen; 2211 u_int8_t state[RC4STATE], key[RC4KEYLEN]; 2212 u_int8_t x, y, *dat; 2213 2214 if (!sc->wi_icv_flag) { 2215 sc->wi_icv = arc4random(); 2216 sc->wi_icv_flag++; 2217 } else 2218 sc->wi_icv++; 2219 /* 2220 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir: 2221 * (B, 255, N) with 3 <= B < 8 2222 */ 2223 if (sc->wi_icv >= 0x03ff00 && 2224 (sc->wi_icv & 0xf8ff00) == 0x00ff00) 2225 sc->wi_icv += 0x000100; 2226 2227 /* prepend 24bit IV to tx key, byte order does not matter */ 2228 key[0] = sc->wi_icv >> 16; 2229 key[1] = sc->wi_icv >> 8; 2230 key[2] = sc->wi_icv; 2231 2232 klen = sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keylen + 2233 IEEE80211_WEP_IVLEN; 2234 klen = (klen >= RC4KEYLEN) ? RC4KEYLEN : RC4KEYLEN/2; 2235 bcopy((char *)&sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keydat, 2236 (char *)key + IEEE80211_WEP_IVLEN, klen - IEEE80211_WEP_IVLEN); 2237 2238 /* rc4 keysetup */ 2239 x = y = 0; 2240 for (i = 0; i < RC4STATE; i++) 2241 state[i] = i; 2242 for (i = 0; i < RC4STATE; i++) { 2243 y = (key[x] + state[i] + y) % RC4STATE; 2244 RC4SWAP(i, y); 2245 x = (x + 1) % klen; 2246 } 2247 2248 /* output: IV, tx keyid, rc4(data), rc4(crc32(data)) */ 2249 dat = buf; 2250 dat[0] = key[0]; 2251 dat[1] = key[1]; 2252 dat[2] = key[2]; 2253 dat[3] = sc->wi_tx_key << 6; /* pad and keyid */ 2254 dat += 4; 2255 2256 /* compute rc4 over data, crc32 over data */ 2257 crc = ~0; 2258 x = y = 0; 2259 for (i = 0; i < len; i++) { 2260 x = (x + 1) % RC4STATE; 2261 y = (state[x] + y) % RC4STATE; 2262 RC4SWAP(x, y); 2263 crc = crc32_tab[(crc ^ dat[i]) & 0xff] ^ (crc >> 8); 2264 dat[i] ^= state[(state[x] + state[y]) % RC4STATE]; 2265 } 2266 crc = ~crc; 2267 dat += len; 2268 2269 /* append little-endian crc32 and encrypt */ 2270 dat[0] = crc; 2271 dat[1] = crc >> 8; 2272 dat[2] = crc >> 16; 2273 dat[3] = crc >> 24; 2274 for (i = 0; i < IEEE80211_WEP_CRCLEN; i++) { 2275 x = (x + 1) % RC4STATE; 2276 y = (state[x] + y) % RC4STATE; 2277 RC4SWAP(x, y); 2278 dat[i] ^= state[(state[x] + state[y]) % RC4STATE]; 2279 } 2280} 2281 2282static void 2283wi_start(ifp) 2284 struct ifnet *ifp; 2285{ 2286 struct wi_softc *sc; 2287 struct mbuf *m0; 2288 struct wi_frame tx_frame; 2289 struct ether_header *eh; 2290 int id; 2291 int s; 2292 2293 sc = ifp->if_softc; 2294 WI_LOCK(sc, s); 2295 2296 if (sc->wi_gone) { 2297 WI_UNLOCK(sc, s); 2298 return; 2299 } 2300 2301 if (ifp->if_flags & IFF_OACTIVE) { 2302 WI_UNLOCK(sc, s); 2303 return; 2304 } 2305 2306nextpkt: 2307 IF_DEQUEUE(&ifp->if_snd, m0); 2308 if (m0 == NULL) { 2309 WI_UNLOCK(sc, s); 2310 return; 2311 } 2312 2313 bzero((char *)&tx_frame, sizeof(tx_frame)); 2314 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA); 2315 id = sc->wi_tx_data_id; 2316 eh = mtod(m0, struct ether_header *); 2317 2318 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) { 2319 if (!wihap_check_tx(&sc->wi_hostap_info, 2320 eh->ether_dhost, &tx_frame.wi_tx_rate)) { 2321 if (ifp->if_flags & IFF_DEBUG) 2322 printf("wi_start: dropping unassoc " 2323 "dst %6D\n", eh->ether_dhost, ":"); 2324 m_freem(m0); 2325 goto nextpkt; 2326 } 2327 } 2328 /* 2329 * Use RFC1042 encoding for IP and ARP datagrams, 2330 * 802.3 for anything else. 2331 */ 2332 if (ntohs(eh->ether_type) > ETHER_MAX_LEN) { 2333 bcopy((char *)&eh->ether_dhost, 2334 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN); 2335 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) { 2336 tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; /* XXX */ 2337 tx_frame.wi_frame_ctl |= WI_FCTL_FROMDS; 2338 if (sc->wi_use_wep) 2339 tx_frame.wi_frame_ctl |= WI_FCTL_WEP; 2340 bcopy((char *)&sc->arpcom.ac_enaddr, 2341 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 2342 bcopy((char *)&eh->ether_shost, 2343 (char *)&tx_frame.wi_addr3, ETHER_ADDR_LEN); 2344 } 2345 else 2346 bcopy((char *)&eh->ether_shost, 2347 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 2348 bcopy((char *)&eh->ether_dhost, 2349 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN); 2350 bcopy((char *)&eh->ether_shost, 2351 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN); 2352 2353 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN; 2354 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 2355 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 2356 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 2357 tx_frame.wi_type = eh->ether_type; 2358 2359 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) { 2360 /* Do host encryption. */ 2361 bcopy(&tx_frame.wi_dat[0], &sc->wi_txbuf[4], 8); 2362 m_copydata(m0, sizeof(struct ether_header), 2363 m0->m_pkthdr.len - sizeof(struct ether_header), 2364 (caddr_t)&sc->wi_txbuf[12]); 2365 wi_do_hostencrypt(sc, &sc->wi_txbuf[0], 2366 tx_frame.wi_dat_len); 2367 tx_frame.wi_dat_len += IEEE80211_WEP_IVLEN + 2368 IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; 2369 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2370 sizeof(struct wi_frame)); 2371 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, 2372 (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len - 2373 sizeof(struct ether_header)) + 18); 2374 } else { 2375 m_copydata(m0, sizeof(struct ether_header), 2376 m0->m_pkthdr.len - sizeof(struct ether_header), 2377 (caddr_t)&sc->wi_txbuf); 2378 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2379 sizeof(struct wi_frame)); 2380 wi_write_data(sc, id, WI_802_11_OFFSET, 2381 (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len - 2382 sizeof(struct ether_header)) + 2); 2383 } 2384 } else { 2385 tx_frame.wi_dat_len = m0->m_pkthdr.len; 2386 2387 if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) { 2388 /* Do host encryption. */ 2389 printf( "XXX: host encrypt not implemented for 802.3\n" ); 2390 } else { 2391 eh->ether_type = htons(m0->m_pkthdr.len - 2392 WI_SNAPHDR_LEN); 2393 m_copydata(m0, 0, m0->m_pkthdr.len, 2394 (caddr_t)&sc->wi_txbuf); 2395 2396 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2397 sizeof(struct wi_frame)); 2398 wi_write_data(sc, id, WI_802_3_OFFSET, 2399 (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2); 2400 } 2401 } 2402 2403 /* 2404 * If there's a BPF listner, bounce a copy of 2405 * this frame to him. Also, don't send this to the bpf sniffer 2406 * if we're in procframe or monitor sniffing mode. 2407 */ 2408 if (!(sc->wi_procframe || sc->wi_debug.wi_monitor) && ifp->if_bpf) 2409 bpf_mtap(ifp, m0); 2410 2411 m_freem(m0); 2412 2413 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) 2414 device_printf(sc->dev, "xmit failed\n"); 2415 2416 ifp->if_flags |= IFF_OACTIVE; 2417 2418 /* 2419 * Set a timeout in case the chip goes out to lunch. 2420 */ 2421 ifp->if_timer = 5; 2422 2423 WI_UNLOCK(sc, s); 2424 return; 2425} 2426 2427int 2428wi_mgmt_xmit(sc, data, len) 2429 struct wi_softc *sc; 2430 caddr_t data; 2431 int len; 2432{ 2433 struct wi_frame tx_frame; 2434 int id; 2435 struct wi_80211_hdr *hdr; 2436 caddr_t dptr; 2437 2438 if (sc->wi_gone) 2439 return(ENODEV); 2440 2441 hdr = (struct wi_80211_hdr *)data; 2442 dptr = data + sizeof(struct wi_80211_hdr); 2443 2444 bzero((char *)&tx_frame, sizeof(tx_frame)); 2445 id = sc->wi_tx_mgmt_id; 2446 2447 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl, 2448 sizeof(struct wi_80211_hdr)); 2449 2450 tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; 2451 tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr); 2452 tx_frame.wi_len = htons(tx_frame.wi_dat_len); 2453 2454 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 2455 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 2456 len - sizeof(struct wi_80211_hdr) + 2); 2457 2458 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) { 2459 device_printf(sc->dev, "xmit failed\n"); 2460 return(EIO); 2461 } 2462 2463 return(0); 2464} 2465 2466static void 2467wi_stop(sc) 2468 struct wi_softc *sc; 2469{ 2470 struct ifnet *ifp; 2471 int s; 2472 2473 WI_LOCK(sc, s); 2474 2475 if (sc->wi_gone) { 2476 WI_UNLOCK(sc, s); 2477 return; 2478 } 2479 2480 wihap_shutdown(sc); 2481 2482 ifp = &sc->arpcom.ac_if; 2483 2484 /* 2485 * If the card is gone and the memory port isn't mapped, we will 2486 * (hopefully) get 0xffff back from the status read, which is not 2487 * a valid status value. 2488 */ 2489 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) { 2490 CSR_WRITE_2(sc, WI_INT_EN, 0); 2491 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0); 2492 } 2493 2494 untimeout(wi_inquire, sc, sc->wi_stat_ch); 2495 2496 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 2497 2498 WI_UNLOCK(sc, s); 2499 return; 2500} 2501 2502static void 2503wi_watchdog(ifp) 2504 struct ifnet *ifp; 2505{ 2506 struct wi_softc *sc; 2507 2508 sc = ifp->if_softc; 2509 2510 device_printf(sc->dev, "watchdog timeout\n"); 2511 2512 wi_init(sc); 2513 2514 ifp->if_oerrors++; 2515 2516 return; 2517} 2518 2519int 2520wi_alloc(dev, rid) 2521 device_t dev; 2522 int rid; 2523{ 2524 struct wi_softc *sc = device_get_softc(dev); 2525 2526 if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { 2527 sc->iobase_rid = rid; 2528 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, 2529 &sc->iobase_rid, 0, ~0, (1 << 6), 2530 rman_make_alignment_flags(1 << 6) | RF_ACTIVE); 2531 if (!sc->iobase) { 2532 device_printf(dev, "No I/O space?!\n"); 2533 return (ENXIO); 2534 } 2535 2536 sc->wi_io_addr = rman_get_start(sc->iobase); 2537 sc->wi_btag = rman_get_bustag(sc->iobase); 2538 sc->wi_bhandle = rman_get_bushandle(sc->iobase); 2539 } else { 2540 sc->mem_rid = rid; 2541 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, 2542 &sc->mem_rid, 0, ~0, 1, RF_ACTIVE); 2543 2544 if (!sc->mem) { 2545 device_printf(dev, "No Mem space on prism2.5?\n"); 2546 return (ENXIO); 2547 } 2548 2549 sc->wi_btag = rman_get_bustag(sc->mem); 2550 sc->wi_bhandle = rman_get_bushandle(sc->mem); 2551 } 2552 2553 2554 sc->irq_rid = 0; 2555 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 2556 0, ~0, 1, RF_ACTIVE | 2557 ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE)); 2558 2559 if (!sc->irq) { 2560 wi_free(dev); 2561 device_printf(dev, "No irq?!\n"); 2562 return (ENXIO); 2563 } 2564 2565 sc->dev = dev; 2566 sc->wi_unit = device_get_unit(dev); 2567 2568 return (0); 2569} 2570 2571void 2572wi_free(dev) 2573 device_t dev; 2574{ 2575 struct wi_softc *sc = device_get_softc(dev); 2576 2577 if (sc->iobase != NULL) { 2578 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase); 2579 sc->iobase = NULL; 2580 } 2581 if (sc->irq != NULL) { 2582 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 2583 sc->irq = NULL; 2584 } 2585 if (sc->mem != NULL) { 2586 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 2587 sc->mem = NULL; 2588 } 2589 2590 return; 2591} 2592 2593void 2594wi_shutdown(dev) 2595 device_t dev; 2596{ 2597 struct wi_softc *sc; 2598 2599 sc = device_get_softc(dev); 2600 wi_stop(sc); 2601 2602 return; 2603} 2604 2605#ifdef WICACHE 2606/* wavelan signal strength cache code. 2607 * store signal/noise/quality on per MAC src basis in 2608 * a small fixed cache. The cache wraps if > MAX slots 2609 * used. The cache may be zeroed out to start over. 2610 * Two simple filters exist to reduce computation: 2611 * 1. ip only (literally 0x800) which may be used 2612 * to ignore some packets. It defaults to ip only. 2613 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2614 * 2. multicast/broadcast only. This may be used to 2615 * ignore unicast packets and only cache signal strength 2616 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2617 * beacons and not unicast traffic. 2618 * 2619 * The cache stores (MAC src(index), IP src (major clue), signal, 2620 * quality, noise) 2621 * 2622 * No apologies for storing IP src here. It's easy and saves much 2623 * trouble elsewhere. The cache is assumed to be INET dependent, 2624 * although it need not be. 2625 */ 2626 2627#ifdef documentation 2628 2629int wi_sigitems; /* number of cached entries */ 2630struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */ 2631int wi_nextitem; /* index/# of entries */ 2632 2633 2634#endif 2635 2636/* control variables for cache filtering. Basic idea is 2637 * to reduce cost (e.g., to only Mobile-IP agent beacons 2638 * which are broadcast or multicast). Still you might 2639 * want to measure signal strength with unicast ping packets 2640 * on a pt. to pt. ant. setup. 2641 */ 2642/* set true if you want to limit cache items to broadcast/mcast 2643 * only packets (not unicast). Useful for mobile-ip beacons which 2644 * are broadcast/multicast at network layer. Default is all packets 2645 * so ping/unicast will work say with pt. to pt. antennae setup. 2646 */ 2647static int wi_cache_mcastonly = 0; 2648SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 2649 &wi_cache_mcastonly, 0, ""); 2650 2651/* set true if you want to limit cache items to IP packets only 2652*/ 2653static int wi_cache_iponly = 1; 2654SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 2655 &wi_cache_iponly, 0, ""); 2656 2657/* 2658 * Original comments: 2659 * ----------------- 2660 * wi_cache_store, per rx packet store signal 2661 * strength in MAC (src) indexed cache. 2662 * 2663 * follows linux driver in how signal strength is computed. 2664 * In ad hoc mode, we use the rx_quality field. 2665 * signal and noise are trimmed to fit in the range from 47..138. 2666 * rx_quality field MSB is signal strength. 2667 * rx_quality field LSB is noise. 2668 * "quality" is (signal - noise) as is log value. 2669 * note: quality CAN be negative. 2670 * 2671 * In BSS mode, we use the RID for communication quality. 2672 * TBD: BSS mode is currently untested. 2673 * 2674 * Bill's comments: 2675 * --------------- 2676 * Actually, we use the rx_quality field all the time for both "ad-hoc" 2677 * and BSS modes. Why? Because reading an RID is really, really expensive: 2678 * there's a bunch of PIO operations that have to be done to read a record 2679 * from the NIC, and reading the comms quality RID each time a packet is 2680 * received can really hurt performance. We don't have to do this anyway: 2681 * the comms quality field only reflects the values in the rx_quality field 2682 * anyway. The comms quality RID is only meaningful in infrastructure mode, 2683 * but the values it contains are updated based on the rx_quality from 2684 * frames received from the access point. 2685 * 2686 * Also, according to Lucent, the signal strength and noise level values 2687 * can be converted to dBms by subtracting 149, so I've modified the code 2688 * to do that instead of the scaling it did originally. 2689 */ 2690static void 2691wi_cache_store(struct wi_softc *sc, struct ether_header *eh, 2692 struct mbuf *m, unsigned short rx_quality) 2693{ 2694 struct ip *ip = 0; 2695 int i; 2696 static int cache_slot = 0; /* use this cache entry */ 2697 static int wrapindex = 0; /* next "free" cache entry */ 2698 int sig, noise; 2699 int sawip=0; 2700 2701 /* 2702 * filters: 2703 * 1. ip only 2704 * 2. configurable filter to throw out unicast packets, 2705 * keep multicast only. 2706 */ 2707 2708 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 2709 sawip = 1; 2710 } 2711 2712 /* 2713 * filter for ip packets only 2714 */ 2715 if (wi_cache_iponly && !sawip) { 2716 return; 2717 } 2718 2719 /* 2720 * filter for broadcast/multicast only 2721 */ 2722 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2723 return; 2724 } 2725 2726#ifdef SIGDEBUG 2727 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit, 2728 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2729#endif 2730 2731 /* 2732 * find the ip header. we want to store the ip_src 2733 * address. 2734 */ 2735 if (sawip) 2736 ip = mtod(m, struct ip *); 2737 2738 /* 2739 * do a linear search for a matching MAC address 2740 * in the cache table 2741 * . MAC address is 6 bytes, 2742 * . var w_nextitem holds total number of entries already cached 2743 */ 2744 for(i = 0; i < sc->wi_nextitem; i++) { 2745 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) { 2746 /* 2747 * Match!, 2748 * so we already have this entry, 2749 * update the data 2750 */ 2751 break; 2752 } 2753 } 2754 2755 /* 2756 * did we find a matching mac address? 2757 * if yes, then overwrite a previously existing cache entry 2758 */ 2759 if (i < sc->wi_nextitem ) { 2760 cache_slot = i; 2761 } 2762 /* 2763 * else, have a new address entry,so 2764 * add this new entry, 2765 * if table full, then we need to replace LRU entry 2766 */ 2767 else { 2768 2769 /* 2770 * check for space in cache table 2771 * note: wi_nextitem also holds number of entries 2772 * added in the cache table 2773 */ 2774 if ( sc->wi_nextitem < MAXWICACHE ) { 2775 cache_slot = sc->wi_nextitem; 2776 sc->wi_nextitem++; 2777 sc->wi_sigitems = sc->wi_nextitem; 2778 } 2779 /* no space found, so simply wrap with wrap index 2780 * and "zap" the next entry 2781 */ 2782 else { 2783 if (wrapindex == MAXWICACHE) { 2784 wrapindex = 0; 2785 } 2786 cache_slot = wrapindex++; 2787 } 2788 } 2789 2790 /* 2791 * invariant: cache_slot now points at some slot 2792 * in cache. 2793 */ 2794 if (cache_slot < 0 || cache_slot >= MAXWICACHE) { 2795 log(LOG_ERR, "wi_cache_store, bad index: %d of " 2796 "[0..%d], gross cache error\n", 2797 cache_slot, MAXWICACHE); 2798 return; 2799 } 2800 2801 /* 2802 * store items in cache 2803 * .ip source address 2804 * .mac src 2805 * .signal, etc. 2806 */ 2807 if (sawip) 2808 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2809 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6); 2810 2811 sig = (rx_quality >> 8) & 0xFF; 2812 noise = rx_quality & 0xFF; 2813 2814 /* 2815 * -149 is Lucent specific to convert to dBm. Prism2 cards do 2816 * things differently, sometimes don't have a noise measurement, 2817 * and is firmware dependent :-( 2818 */ 2819 sc->wi_sigcache[cache_slot].signal = sig - 149; 2820 sc->wi_sigcache[cache_slot].noise = noise - 149; 2821 sc->wi_sigcache[cache_slot].quality = sig - noise; 2822 2823 return; 2824} 2825#endif 2826 2827static int 2828wi_get_cur_ssid(sc, ssid, len) 2829 struct wi_softc *sc; 2830 char *ssid; 2831 int *len; 2832{ 2833 int error = 0; 2834 struct wi_req wreq; 2835 2836 wreq.wi_len = WI_MAX_DATALEN; 2837 switch (sc->wi_ptype) { 2838 case WI_PORTTYPE_HOSTAP: 2839 *len = IEEE80211_NWID_LEN; 2840 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN); 2841 break; 2842 case WI_PORTTYPE_IBSS: 2843 case WI_PORTTYPE_ADHOC: 2844 wreq.wi_type = WI_RID_CURRENT_SSID; 2845 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2846 if (error != 0) 2847 break; 2848 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2849 error = EINVAL; 2850 break; 2851 } 2852 *len = wreq.wi_val[0]; 2853 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2854 break; 2855 case WI_PORTTYPE_BSS: 2856 wreq.wi_type = WI_RID_COMMQUAL; 2857 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2858 if (error != 0) 2859 break; 2860 if (wreq.wi_val[0] != 0) /* associated */ { 2861 wreq.wi_type = WI_RID_CURRENT_SSID; 2862 wreq.wi_len = WI_MAX_DATALEN; 2863 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2864 if (error != 0) 2865 break; 2866 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2867 error = EINVAL; 2868 break; 2869 } 2870 *len = wreq.wi_val[0]; 2871 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2872 } else { 2873 *len = IEEE80211_NWID_LEN; 2874 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN); 2875 } 2876 break; 2877 default: 2878 error = EINVAL; 2879 break; 2880 } 2881 2882 return error; 2883} 2884 2885static int 2886wi_media_change(ifp) 2887 struct ifnet *ifp; 2888{ 2889 struct wi_softc *sc = ifp->if_softc; 2890 int otype = sc->wi_ptype; 2891 int orate = sc->wi_tx_rate; 2892 int ocreate_ibss = sc->wi_create_ibss; 2893 2894 if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) && 2895 sc->sc_firmware_type != WI_INTERSIL) 2896 return (EINVAL); 2897 2898 sc->wi_create_ibss = 0; 2899 2900 switch (sc->ifmedia.ifm_cur->ifm_media & IFM_OMASK) { 2901 case 0: 2902 sc->wi_ptype = WI_PORTTYPE_BSS; 2903 break; 2904 case IFM_IEEE80211_ADHOC: 2905 sc->wi_ptype = WI_PORTTYPE_ADHOC; 2906 break; 2907 case IFM_IEEE80211_HOSTAP: 2908 sc->wi_ptype = WI_PORTTYPE_HOSTAP; 2909 break; 2910 case IFM_IEEE80211_IBSSMASTER: 2911 case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS: 2912 if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) 2913 return (EINVAL); 2914 sc->wi_create_ibss = 1; 2915 /* FALLTHROUGH */ 2916 case IFM_IEEE80211_IBSS: 2917 sc->wi_ptype = WI_PORTTYPE_IBSS; 2918 break; 2919 default: 2920 /* Invalid combination. */ 2921 return (EINVAL); 2922 } 2923 2924 switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) { 2925 case IFM_IEEE80211_DS1: 2926 sc->wi_tx_rate = 1; 2927 break; 2928 case IFM_IEEE80211_DS2: 2929 sc->wi_tx_rate = 2; 2930 break; 2931 case IFM_IEEE80211_DS5: 2932 sc->wi_tx_rate = 5; 2933 break; 2934 case IFM_IEEE80211_DS11: 2935 sc->wi_tx_rate = 11; 2936 break; 2937 case IFM_AUTO: 2938 sc->wi_tx_rate = 3; 2939 break; 2940 } 2941 2942 if (ocreate_ibss != sc->wi_create_ibss || otype != sc->wi_ptype || 2943 orate != sc->wi_tx_rate) 2944 wi_init(sc); 2945 2946 return(0); 2947} 2948 2949static void 2950wi_media_status(ifp, imr) 2951 struct ifnet *ifp; 2952 struct ifmediareq *imr; 2953{ 2954 struct wi_req wreq; 2955 struct wi_softc *sc = ifp->if_softc; 2956 2957 if (sc->wi_tx_rate == 3) { 2958 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2959 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) 2960 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2961 else if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) 2962 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 2963 else if (sc->wi_ptype == WI_PORTTYPE_IBSS) { 2964 if (sc->wi_create_ibss) 2965 imr->ifm_active |= IFM_IEEE80211_IBSSMASTER; 2966 else 2967 imr->ifm_active |= IFM_IEEE80211_IBSS; 2968 } 2969 wreq.wi_type = WI_RID_CUR_TX_RATE; 2970 wreq.wi_len = WI_MAX_DATALEN; 2971 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) { 2972 switch(wreq.wi_val[0]) { 2973 case 1: 2974 imr->ifm_active |= IFM_IEEE80211_DS1; 2975 break; 2976 case 2: 2977 imr->ifm_active |= IFM_IEEE80211_DS2; 2978 break; 2979 case 6: 2980 imr->ifm_active |= IFM_IEEE80211_DS5; 2981 break; 2982 case 11: 2983 imr->ifm_active |= IFM_IEEE80211_DS11; 2984 break; 2985 } 2986 } 2987 } else { 2988 imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; 2989 } 2990 2991 imr->ifm_status = IFM_AVALID; 2992 if (sc->wi_ptype == WI_PORTTYPE_ADHOC || 2993 sc->wi_ptype == WI_PORTTYPE_IBSS) 2994 /* 2995 * XXX: It would be nice if we could give some actually 2996 * useful status like whether we joined another IBSS or 2997 * created one ourselves. 2998 */ 2999 imr->ifm_status |= IFM_ACTIVE; 3000 else if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) 3001 imr->ifm_status |= IFM_ACTIVE; 3002 else { 3003 wreq.wi_type = WI_RID_COMMQUAL; 3004 wreq.wi_len = WI_MAX_DATALEN; 3005 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 && 3006 wreq.wi_val[0] != 0) 3007 imr->ifm_status |= IFM_ACTIVE; 3008 } 3009} 3010 3011static int 3012wi_get_debug(sc, wreq) 3013 struct wi_softc *sc; 3014 struct wi_req *wreq; 3015{ 3016 int error = 0; 3017 3018 wreq->wi_len = 1; 3019 3020 switch (wreq->wi_type) { 3021 case WI_DEBUG_SLEEP: 3022 wreq->wi_len++; 3023 wreq->wi_val[0] = sc->wi_debug.wi_sleep; 3024 break; 3025 case WI_DEBUG_DELAYSUPP: 3026 wreq->wi_len++; 3027 wreq->wi_val[0] = sc->wi_debug.wi_delaysupp; 3028 break; 3029 case WI_DEBUG_TXSUPP: 3030 wreq->wi_len++; 3031 wreq->wi_val[0] = sc->wi_debug.wi_txsupp; 3032 break; 3033 case WI_DEBUG_MONITOR: 3034 wreq->wi_len++; 3035 wreq->wi_val[0] = sc->wi_debug.wi_monitor; 3036 break; 3037 case WI_DEBUG_LEDTEST: 3038 wreq->wi_len += 3; 3039 wreq->wi_val[0] = sc->wi_debug.wi_ledtest; 3040 wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0; 3041 wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1; 3042 break; 3043 case WI_DEBUG_CONTTX: 3044 wreq->wi_len += 2; 3045 wreq->wi_val[0] = sc->wi_debug.wi_conttx; 3046 wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0; 3047 break; 3048 case WI_DEBUG_CONTRX: 3049 wreq->wi_len++; 3050 wreq->wi_val[0] = sc->wi_debug.wi_contrx; 3051 break; 3052 case WI_DEBUG_SIGSTATE: 3053 wreq->wi_len += 2; 3054 wreq->wi_val[0] = sc->wi_debug.wi_sigstate; 3055 wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0; 3056 break; 3057 case WI_DEBUG_CONFBITS: 3058 wreq->wi_len += 2; 3059 wreq->wi_val[0] = sc->wi_debug.wi_confbits; 3060 wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0; 3061 break; 3062 default: 3063 error = EIO; 3064 break; 3065 } 3066 3067 return (error); 3068} 3069 3070static int 3071wi_set_debug(sc, wreq) 3072 struct wi_softc *sc; 3073 struct wi_req *wreq; 3074{ 3075 int error = 0; 3076 u_int16_t cmd, param0 = 0, param1 = 0; 3077 3078 switch (wreq->wi_type) { 3079 case WI_DEBUG_RESET: 3080 case WI_DEBUG_INIT: 3081 case WI_DEBUG_CALENABLE: 3082 break; 3083 case WI_DEBUG_SLEEP: 3084 sc->wi_debug.wi_sleep = 1; 3085 break; 3086 case WI_DEBUG_WAKE: 3087 sc->wi_debug.wi_sleep = 0; 3088 break; 3089 case WI_DEBUG_CHAN: 3090 param0 = wreq->wi_val[0]; 3091 break; 3092 case WI_DEBUG_DELAYSUPP: 3093 sc->wi_debug.wi_delaysupp = 1; 3094 break; 3095 case WI_DEBUG_TXSUPP: 3096 sc->wi_debug.wi_txsupp = 1; 3097 break; 3098 case WI_DEBUG_MONITOR: 3099 sc->wi_debug.wi_monitor = 1; 3100 break; 3101 case WI_DEBUG_LEDTEST: 3102 param0 = wreq->wi_val[0]; 3103 param1 = wreq->wi_val[1]; 3104 sc->wi_debug.wi_ledtest = 1; 3105 sc->wi_debug.wi_ledtest_param0 = param0; 3106 sc->wi_debug.wi_ledtest_param1 = param1; 3107 break; 3108 case WI_DEBUG_CONTTX: 3109 param0 = wreq->wi_val[0]; 3110 sc->wi_debug.wi_conttx = 1; 3111 sc->wi_debug.wi_conttx_param0 = param0; 3112 break; 3113 case WI_DEBUG_STOPTEST: 3114 sc->wi_debug.wi_delaysupp = 0; 3115 sc->wi_debug.wi_txsupp = 0; 3116 sc->wi_debug.wi_monitor = 0; 3117 sc->wi_debug.wi_ledtest = 0; 3118 sc->wi_debug.wi_ledtest_param0 = 0; 3119 sc->wi_debug.wi_ledtest_param1 = 0; 3120 sc->wi_debug.wi_conttx = 0; 3121 sc->wi_debug.wi_conttx_param0 = 0; 3122 sc->wi_debug.wi_contrx = 0; 3123 sc->wi_debug.wi_sigstate = 0; 3124 sc->wi_debug.wi_sigstate_param0 = 0; 3125 break; 3126 case WI_DEBUG_CONTRX: 3127 sc->wi_debug.wi_contrx = 1; 3128 break; 3129 case WI_DEBUG_SIGSTATE: 3130 param0 = wreq->wi_val[0]; 3131 sc->wi_debug.wi_sigstate = 1; 3132 sc->wi_debug.wi_sigstate_param0 = param0; 3133 break; 3134 case WI_DEBUG_CONFBITS: 3135 param0 = wreq->wi_val[0]; 3136 param1 = wreq->wi_val[1]; 3137 sc->wi_debug.wi_confbits = param0; 3138 sc->wi_debug.wi_confbits_param0 = param1; 3139 break; 3140 default: 3141 error = EIO; 3142 break; 3143 } 3144 3145 if (error) 3146 return (error); 3147 3148 cmd = WI_CMD_DEBUG | (wreq->wi_type << 8); 3149 error = wi_cmd(sc, cmd, param0, param1, 0); 3150 3151 return (error); 3152} 3153 3154#if __FreeBSD_version >= 500000 3155/* 3156 * Special routines to download firmware for Symbol CF card. 3157 * XXX: This should be modified generic into any PRISM-2 based card. 3158 */ 3159 3160#define WI_SBCF_PDIADDR 0x3100 3161 3162/* unaligned load little endian */ 3163#define GETLE32(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)) 3164#define GETLE16(p) ((p)[0] | ((p)[1]<<8)) 3165 3166int 3167wi_symbol_load_firm(struct wi_softc *sc, const void *primsym, int primlen, 3168 const void *secsym, int seclen) 3169{ 3170 uint8_t ebuf[256]; 3171 int i; 3172 3173 /* load primary code and run it */ 3174 wi_symbol_set_hcr(sc, WI_HCR_EEHOLD); 3175 if (wi_symbol_write_firm(sc, primsym, primlen, NULL, 0)) 3176 return EIO; 3177 wi_symbol_set_hcr(sc, WI_HCR_RUN); 3178 for (i = 0; ; i++) { 3179 if (i == 10) 3180 return ETIMEDOUT; 3181 tsleep(sc, PWAIT, "wiinit", 1); 3182 if (CSR_READ_2(sc, WI_CNTL) == WI_CNTL_AUX_ENA_STAT) 3183 break; 3184 /* write the magic key value to unlock aux port */ 3185 CSR_WRITE_2(sc, WI_PARAM0, WI_AUX_KEY0); 3186 CSR_WRITE_2(sc, WI_PARAM1, WI_AUX_KEY1); 3187 CSR_WRITE_2(sc, WI_PARAM2, WI_AUX_KEY2); 3188 CSR_WRITE_2(sc, WI_CNTL, WI_CNTL_AUX_ENA_CNTL); 3189 } 3190 3191 /* issue read EEPROM command: XXX copied from wi_cmd() */ 3192 CSR_WRITE_2(sc, WI_PARAM0, 0); 3193 CSR_WRITE_2(sc, WI_PARAM1, 0); 3194 CSR_WRITE_2(sc, WI_PARAM2, 0); 3195 CSR_WRITE_2(sc, WI_COMMAND, WI_CMD_READEE); 3196 for (i = 0; i < WI_TIMEOUT; i++) { 3197 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD) 3198 break; 3199 DELAY(1); 3200 } 3201 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 3202 3203 CSR_WRITE_2(sc, WI_AUX_PAGE, WI_SBCF_PDIADDR / WI_AUX_PGSZ); 3204 CSR_WRITE_2(sc, WI_AUX_OFFSET, WI_SBCF_PDIADDR % WI_AUX_PGSZ); 3205 CSR_READ_MULTI_STREAM_2(sc, WI_AUX_DATA, 3206 (uint16_t *)ebuf, sizeof(ebuf) / 2); 3207 if (GETLE16(ebuf) > sizeof(ebuf)) 3208 return EIO; 3209 if (wi_symbol_write_firm(sc, secsym, seclen, ebuf + 4, GETLE16(ebuf))) 3210 return EIO; 3211 return 0; 3212} 3213 3214static int 3215wi_symbol_write_firm(struct wi_softc *sc, const void *buf, int buflen, 3216 const void *ebuf, int ebuflen) 3217{ 3218 const uint8_t *p, *ep, *q, *eq; 3219 char *tp; 3220 uint32_t addr, id, eid; 3221 int i, len, elen, nblk, pdrlen; 3222 3223 /* 3224 * Parse the header of the firmware image. 3225 */ 3226 p = buf; 3227 ep = p + buflen; 3228 while (p < ep && *p++ != ' '); /* FILE: */ 3229 while (p < ep && *p++ != ' '); /* filename */ 3230 while (p < ep && *p++ != ' '); /* type of the firmware */ 3231 nblk = strtoul(p, &tp, 10); 3232 p = tp; 3233 pdrlen = strtoul(p + 1, &tp, 10); 3234 p = tp; 3235 while (p < ep && *p++ != 0x1a); /* skip rest of header */ 3236 3237 /* 3238 * Block records: address[4], length[2], data[length]; 3239 */ 3240 for (i = 0; i < nblk; i++) { 3241 addr = GETLE32(p); p += 4; 3242 len = GETLE16(p); p += 2; 3243 CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ); 3244 CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ); 3245 CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA, 3246 (const uint16_t *)p, len / 2); 3247 p += len; 3248 } 3249 3250 /* 3251 * PDR: id[4], address[4], length[4]; 3252 */ 3253 for (i = 0; i < pdrlen; ) { 3254 id = GETLE32(p); p += 4; i += 4; 3255 addr = GETLE32(p); p += 4; i += 4; 3256 len = GETLE32(p); p += 4; i += 4; 3257 /* replace PDR entry with the values from EEPROM, if any */ 3258 for (q = ebuf, eq = q + ebuflen; q < eq; q += elen * 2) { 3259 elen = GETLE16(q); q += 2; 3260 eid = GETLE16(q); q += 2; 3261 elen--; /* elen includes eid */ 3262 if (eid == 0) 3263 break; 3264 if (eid != id) 3265 continue; 3266 CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ); 3267 CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ); 3268 CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA, 3269 (const uint16_t *)q, len / 2); 3270 break; 3271 } 3272 } 3273 return 0; 3274} 3275 3276static int 3277wi_symbol_set_hcr(struct wi_softc *sc, int mode) 3278{ 3279 uint16_t hcr; 3280 3281 CSR_WRITE_2(sc, WI_COR, WI_COR_RESET); 3282 tsleep(sc, PWAIT, "wiinit", 1); 3283 hcr = CSR_READ_2(sc, WI_HCR); 3284 hcr = (hcr & WI_HCR_4WIRE) | (mode & ~WI_HCR_4WIRE); 3285 CSR_WRITE_2(sc, WI_HCR, hcr); 3286 tsleep(sc, PWAIT, "wiinit", 1); 3287 CSR_WRITE_2(sc, WI_COR, WI_COR_IOMODE); 3288 tsleep(sc, PWAIT, "wiinit", 1); 3289 return 0; 3290} 3291#endif 3292