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