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