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