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