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