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