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