1 /* $OpenBSD: if_wi.c,v 1.143 2008/11/28 02:44:17 brad 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.143 2008/11/28 02:44:17 brad 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_shutdown(void *); 142 STATIC void wi_rxeof(struct wi_softc *); 143 STATIC void wi_txeof(struct wi_softc *, int); 144 STATIC void wi_update_stats(struct wi_softc *); 145 STATIC void wi_setmulti(struct wi_softc *); 146 147 STATIC int wi_cmd_io(struct wi_softc *, int, int, int, int); 148 STATIC int wi_read_record_io(struct wi_softc *, struct wi_ltv_gen *); 149 STATIC int wi_write_record_io(struct wi_softc *, struct wi_ltv_gen *); 150 STATIC int wi_read_data_io(struct wi_softc *, int, 151 int, caddr_t, int); 152 STATIC int wi_write_data_io(struct wi_softc *, int, 153 int, caddr_t, int); 154 STATIC int wi_seek(struct wi_softc *, int, int, int); 155 156 STATIC void wi_inquire(void *); 157 STATIC int wi_setdef(struct wi_softc *, struct wi_req *); 158 STATIC void wi_get_id(struct wi_softc *); 159 160 STATIC int wi_media_change(struct ifnet *); 161 STATIC void wi_media_status(struct ifnet *, struct ifmediareq *); 162 163 STATIC int wi_set_ssid(struct ieee80211_nwid *, u_int8_t *, int); 164 STATIC int wi_set_nwkey(struct wi_softc *, struct ieee80211_nwkey *); 165 STATIC int wi_get_nwkey(struct wi_softc *, struct ieee80211_nwkey *); 166 STATIC int wi_sync_media(struct wi_softc *, int, int); 167 STATIC int wi_set_pm(struct wi_softc *, struct ieee80211_power *); 168 STATIC int wi_get_pm(struct wi_softc *, struct ieee80211_power *); 169 STATIC int wi_set_txpower(struct wi_softc *, struct ieee80211_txpower *); 170 STATIC int wi_get_txpower(struct wi_softc *, struct ieee80211_txpower *); 171 172 STATIC int wi_get_debug(struct wi_softc *, struct wi_req *); 173 STATIC int wi_set_debug(struct wi_softc *, struct wi_req *); 174 175 STATIC void wi_do_hostencrypt(struct wi_softc *, caddr_t, int); 176 STATIC int wi_do_hostdecrypt(struct wi_softc *, caddr_t, int); 177 178 STATIC int wi_alloc_nicmem_io(struct wi_softc *, int, int *); 179 STATIC int wi_get_fid_io(struct wi_softc *sc, int fid); 180 STATIC void wi_intr_enable(struct wi_softc *sc, int mode); 181 STATIC void wi_intr_ack(struct wi_softc *sc, int mode); 182 void wi_scan_timeout(void *); 183 184 /* Autoconfig definition of driver back-end */ 185 struct cfdriver wi_cd = { 186 NULL, "wi", DV_IFNET 187 }; 188 189 const struct wi_card_ident wi_card_ident[] = { 190 WI_CARD_IDS 191 }; 192 193 struct wi_funcs wi_func_io = { 194 wi_cmd_io, 195 wi_read_record_io, 196 wi_write_record_io, 197 wi_alloc_nicmem_io, 198 wi_read_data_io, 199 wi_write_data_io, 200 wi_get_fid_io, 201 wi_init_io, 202 203 wi_start, 204 wi_ioctl, 205 wi_watchdog, 206 wi_inquire, 207 }; 208 209 int 210 wi_attach(struct wi_softc *sc, struct wi_funcs *funcs) 211 { 212 struct ieee80211com *ic; 213 struct ifnet *ifp; 214 struct wi_ltv_macaddr mac; 215 struct wi_ltv_rates rates; 216 struct wi_ltv_gen gen; 217 int error; 218 219 ic = &sc->sc_ic; 220 ifp = &ic->ic_if; 221 222 sc->sc_funcs = funcs; 223 sc->wi_cmd_count = 500; 224 225 wi_reset(sc); 226 227 /* Read the station address. */ 228 mac.wi_type = WI_RID_MAC_NODE; 229 mac.wi_len = 4; 230 error = wi_read_record(sc, (struct wi_ltv_gen *)&mac); 231 if (error) { 232 printf(": unable to read station address\n"); 233 return (error); 234 } 235 bcopy((char *)&mac.wi_mac_addr, (char *)&ic->ic_myaddr, 236 IEEE80211_ADDR_LEN); 237 238 wi_get_id(sc); 239 printf("address %s", ether_sprintf(ic->ic_myaddr)); 240 241 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 242 ifp->if_softc = sc; 243 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 244 ifp->if_ioctl = funcs->f_ioctl; 245 ifp->if_start = funcs->f_start; 246 ifp->if_watchdog = funcs->f_watchdog; 247 ifp->if_baudrate = 10000000; 248 IFQ_SET_READY(&ifp->if_snd); 249 250 (void)wi_set_ssid(&sc->wi_node_name, WI_DEFAULT_NODENAME, 251 sizeof(WI_DEFAULT_NODENAME) - 1); 252 (void)wi_set_ssid(&sc->wi_net_name, WI_DEFAULT_NETNAME, 253 sizeof(WI_DEFAULT_NETNAME) - 1); 254 (void)wi_set_ssid(&sc->wi_ibss_name, WI_DEFAULT_IBSS, 255 sizeof(WI_DEFAULT_IBSS) - 1); 256 257 sc->wi_portnum = WI_DEFAULT_PORT; 258 sc->wi_ptype = WI_PORTTYPE_BSS; 259 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 260 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 261 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 262 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 263 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 264 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 265 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 266 sc->wi_roaming = WI_DEFAULT_ROAMING; 267 sc->wi_authtype = WI_DEFAULT_AUTHTYPE; 268 sc->wi_diversity = WI_DEFAULT_DIVERSITY; 269 sc->wi_crypto_algorithm = WI_CRYPTO_FIRMWARE_WEP; 270 271 /* 272 * Read the default channel from the NIC. This may vary 273 * depending on the country where the NIC was purchased, so 274 * we can't hard-code a default and expect it to work for 275 * everyone. 276 */ 277 gen.wi_type = WI_RID_OWN_CHNL; 278 gen.wi_len = 2; 279 if (wi_read_record(sc, &gen) == 0) 280 sc->wi_channel = letoh16(gen.wi_val); 281 else 282 sc->wi_channel = 3; 283 284 /* 285 * Set flags based on firmware version. 286 */ 287 switch (sc->sc_firmware_type) { 288 case WI_LUCENT: 289 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 290 if (sc->sc_sta_firmware_ver >= 60000) 291 sc->wi_flags |= WI_FLAGS_HAS_MOR; 292 if (sc->sc_sta_firmware_ver >= 60006) { 293 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 294 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 295 } 296 sc->wi_ibss_port = htole16(1); 297 break; 298 case WI_INTERSIL: 299 sc->wi_flags |= WI_FLAGS_HAS_ROAMING; 300 /* older prism firmware is slow so crank the count */ 301 if (sc->sc_sta_firmware_ver < 10000) 302 sc->wi_cmd_count = 5000; 303 else 304 sc->wi_cmd_count = 2000; 305 if (sc->sc_sta_firmware_ver >= 800) { 306 #ifndef SMALL_KERNEL 307 /* 308 * USB hostap is more pain than it is worth 309 * for now, things would have to be overhauled 310 */ 311 if ((sc->sc_sta_firmware_ver != 10402) && 312 (!(sc->wi_flags & WI_FLAGS_BUS_USB))) 313 sc->wi_flags |= WI_FLAGS_HAS_HOSTAP; 314 #endif 315 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 316 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 317 } 318 if (sc->sc_sta_firmware_ver >= 10603) 319 sc->wi_flags |= WI_FLAGS_HAS_ENH_SECURITY; 320 sc->wi_ibss_port = htole16(0); 321 break; 322 case WI_SYMBOL: 323 sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY; 324 if (sc->sc_sta_firmware_ver >= 20000) 325 sc->wi_flags |= WI_FLAGS_HAS_IBSS; 326 if (sc->sc_sta_firmware_ver >= 25000) 327 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; 328 sc->wi_ibss_port = htole16(4); 329 break; 330 } 331 332 /* 333 * Find out if we support WEP on this card. 334 */ 335 gen.wi_type = WI_RID_WEP_AVAIL; 336 gen.wi_len = 2; 337 if (wi_read_record(sc, &gen) == 0 && gen.wi_val != htole16(0)) 338 sc->wi_flags |= WI_FLAGS_HAS_WEP; 339 timeout_set(&sc->sc_timo, funcs->f_inquire, sc); 340 341 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 342 343 /* Find supported rates. */ 344 rates.wi_type = WI_RID_DATA_RATES; 345 rates.wi_len = sizeof(rates.wi_rates); 346 if (wi_read_record(sc, (struct wi_ltv_gen *)&rates) == 0) { 347 int i, nrates; 348 349 nrates = letoh16(*(u_int16_t *)rates.wi_rates); 350 if (nrates > sizeof(rates.wi_rates) - 2) 351 nrates = sizeof(rates.wi_rates) - 2; 352 353 sc->wi_supprates = 0; 354 for (i = 0; i < nrates; i++) 355 sc->wi_supprates |= rates.wi_rates[2 + i]; 356 } else 357 sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M | 358 WI_SUPPRATES_5M | WI_SUPPRATES_11M; 359 360 ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status); 361 #define ADD(m, c) ifmedia_add(&sc->sc_media, (m), (c), NULL) 362 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 363 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0); 364 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 365 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, 366 0), 0); 367 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 368 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 369 IFM_IEEE80211_IBSSMASTER, 0), 0); 370 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 371 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 372 IFM_IEEE80211_HOSTAP, 0), 0); 373 if (sc->wi_supprates & WI_SUPPRATES_1M) { 374 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 375 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 376 IFM_IEEE80211_ADHOC, 0), 0); 377 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 378 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 379 IFM_IEEE80211_IBSS, 0), 0); 380 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 381 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 382 IFM_IEEE80211_IBSSMASTER, 0), 0); 383 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 384 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 385 IFM_IEEE80211_HOSTAP, 0), 0); 386 } 387 if (sc->wi_supprates & WI_SUPPRATES_2M) { 388 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 389 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 390 IFM_IEEE80211_ADHOC, 0), 0); 391 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 392 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 393 IFM_IEEE80211_IBSS, 0), 0); 394 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 395 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 396 IFM_IEEE80211_IBSSMASTER, 0), 0); 397 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 398 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 399 IFM_IEEE80211_HOSTAP, 0), 0); 400 } 401 if (sc->wi_supprates & WI_SUPPRATES_5M) { 402 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 403 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 404 IFM_IEEE80211_ADHOC, 0), 0); 405 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 406 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 407 IFM_IEEE80211_IBSS, 0), 0); 408 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 409 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 410 IFM_IEEE80211_IBSSMASTER, 0), 0); 411 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 412 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 413 IFM_IEEE80211_HOSTAP, 0), 0); 414 } 415 if (sc->wi_supprates & WI_SUPPRATES_11M) { 416 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 417 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 418 IFM_IEEE80211_ADHOC, 0), 0); 419 if (sc->wi_flags & WI_FLAGS_HAS_IBSS) 420 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 421 IFM_IEEE80211_IBSS, 0), 0); 422 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) 423 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 424 IFM_IEEE80211_IBSSMASTER, 0), 0); 425 if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP) 426 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 427 IFM_IEEE80211_HOSTAP, 0), 0); 428 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0); 429 } 430 #undef ADD 431 ifmedia_set(&sc->sc_media, 432 IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0)); 433 434 /* 435 * Call MI attach routines. 436 */ 437 if_attach(ifp); 438 memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr, 439 ETHER_ADDR_LEN); 440 ether_ifattach(ifp); 441 printf("\n"); 442 443 sc->wi_flags |= WI_FLAGS_ATTACHED; 444 445 #if NBPFILTER > 0 446 BPFATTACH(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 447 #endif 448 449 sc->sc_sdhook = shutdownhook_establish(wi_shutdown, sc); 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 if (sc->sc_sdhook != NULL) 2606 shutdownhook_disestablish(sc->sc_sdhook); 2607 } 2608 } 2609 2610 STATIC void 2611 wi_shutdown(void *arg) 2612 { 2613 struct wi_softc *sc; 2614 2615 sc = arg; 2616 wi_stop(sc); 2617 2618 return; 2619 } 2620 2621 STATIC void 2622 wi_get_id(struct wi_softc *sc) 2623 { 2624 struct wi_ltv_ver ver; 2625 const struct wi_card_ident *id; 2626 u_int16_t pri_fw_ver[3]; 2627 const char *card_name; 2628 u_int16_t card_id; 2629 2630 /* get chip identity */ 2631 bzero(&ver, sizeof(ver)); 2632 ver.wi_type = WI_RID_CARD_ID; 2633 ver.wi_len = 5; 2634 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 2635 card_id = letoh16(ver.wi_ver[0]); 2636 for (id = wi_card_ident; id->firm_type != WI_NOTYPE; id++) { 2637 if (card_id == id->card_id) 2638 break; 2639 } 2640 if (id->firm_type != WI_NOTYPE) { 2641 sc->sc_firmware_type = id->firm_type; 2642 card_name = id->card_name; 2643 } else if (ver.wi_ver[0] & htole16(0x8000)) { 2644 sc->sc_firmware_type = WI_INTERSIL; 2645 card_name = "Unknown PRISM2 chip"; 2646 } else { 2647 sc->sc_firmware_type = WI_LUCENT; 2648 } 2649 2650 /* get primary firmware version (XXX - how to do Lucent?) */ 2651 if (sc->sc_firmware_type != WI_LUCENT) { 2652 bzero(&ver, sizeof(ver)); 2653 ver.wi_type = WI_RID_PRI_IDENTITY; 2654 ver.wi_len = 5; 2655 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 2656 pri_fw_ver[0] = letoh16(ver.wi_ver[2]); 2657 pri_fw_ver[1] = letoh16(ver.wi_ver[3]); 2658 pri_fw_ver[2] = letoh16(ver.wi_ver[1]); 2659 } 2660 2661 /* get station firmware version */ 2662 bzero(&ver, sizeof(ver)); 2663 ver.wi_type = WI_RID_STA_IDENTITY; 2664 ver.wi_len = 5; 2665 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 2666 ver.wi_ver[1] = letoh16(ver.wi_ver[1]); 2667 ver.wi_ver[2] = letoh16(ver.wi_ver[2]); 2668 ver.wi_ver[3] = letoh16(ver.wi_ver[3]); 2669 sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 + 2670 ver.wi_ver[3] * 100 + ver.wi_ver[1]; 2671 2672 if (sc->sc_firmware_type == WI_INTERSIL && 2673 (sc->sc_sta_firmware_ver == 10102 || sc->sc_sta_firmware_ver == 20102)) { 2674 struct wi_ltv_str sver; 2675 char *p; 2676 2677 bzero(&sver, sizeof(sver)); 2678 sver.wi_type = WI_RID_SYMBOL_IDENTITY; 2679 sver.wi_len = 7; 2680 /* value should be something like "V2.00-11" */ 2681 if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 && 2682 *(p = (char *)sver.wi_str) >= 'A' && 2683 p[2] == '.' && p[5] == '-' && p[8] == '\0') { 2684 sc->sc_firmware_type = WI_SYMBOL; 2685 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 + 2686 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + 2687 (p[6] - '0') * 10 + (p[7] - '0'); 2688 } 2689 } 2690 2691 if (sc->sc_firmware_type == WI_LUCENT) { 2692 printf("%s: Firmware %d.%02d variant %d, ", WI_PRT_ARG(sc), 2693 ver.wi_ver[2], ver.wi_ver[3], ver.wi_ver[1]); 2694 } else { 2695 printf("%s: %s%s (0x%04x), Firmware %d.%d.%d (primary), %d.%d.%d (station), ", 2696 WI_PRT_ARG(sc), 2697 sc->sc_firmware_type == WI_SYMBOL ? "Symbol " : "", 2698 card_name, card_id, pri_fw_ver[0], pri_fw_ver[1], 2699 pri_fw_ver[2], sc->sc_sta_firmware_ver / 10000, 2700 (sc->sc_sta_firmware_ver % 10000) / 100, 2701 sc->sc_sta_firmware_ver % 100); 2702 } 2703 } 2704 2705 STATIC int 2706 wi_sync_media(struct wi_softc *sc, int ptype, int txrate) 2707 { 2708 int media = sc->sc_media.ifm_cur->ifm_media; 2709 int options = IFM_OPTIONS(media); 2710 int subtype; 2711 2712 switch (txrate) { 2713 case 1: 2714 subtype = IFM_IEEE80211_DS1; 2715 break; 2716 case 2: 2717 subtype = IFM_IEEE80211_DS2; 2718 break; 2719 case 3: 2720 subtype = IFM_AUTO; 2721 break; 2722 case 5: 2723 subtype = IFM_IEEE80211_DS5; 2724 break; 2725 case 11: 2726 subtype = IFM_IEEE80211_DS11; 2727 break; 2728 default: 2729 subtype = IFM_MANUAL; /* Unable to represent */ 2730 break; 2731 } 2732 2733 options &= ~IFM_OMASK; 2734 switch (ptype) { 2735 case WI_PORTTYPE_BSS: 2736 /* default port type */ 2737 break; 2738 case WI_PORTTYPE_ADHOC: 2739 options |= IFM_IEEE80211_ADHOC; 2740 break; 2741 case WI_PORTTYPE_HOSTAP: 2742 options |= IFM_IEEE80211_HOSTAP; 2743 break; 2744 case WI_PORTTYPE_IBSS: 2745 if (sc->wi_create_ibss) 2746 options |= IFM_IEEE80211_IBSSMASTER; 2747 else 2748 options |= IFM_IEEE80211_IBSS; 2749 break; 2750 default: 2751 subtype = IFM_MANUAL; /* Unable to represent */ 2752 break; 2753 } 2754 media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options, 2755 IFM_INST(media)); 2756 if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL) 2757 return (EINVAL); 2758 ifmedia_set(&sc->sc_media, media); 2759 sc->wi_ptype = ptype; 2760 sc->wi_tx_rate = txrate; 2761 return (0); 2762 } 2763 2764 STATIC int 2765 wi_media_change(struct ifnet *ifp) 2766 { 2767 struct wi_softc *sc = ifp->if_softc; 2768 int otype = sc->wi_ptype; 2769 int orate = sc->wi_tx_rate; 2770 int ocreate_ibss = sc->wi_create_ibss; 2771 2772 if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) && 2773 sc->sc_firmware_type != WI_INTERSIL) 2774 return (EINVAL); 2775 2776 sc->wi_create_ibss = 0; 2777 2778 switch (sc->sc_media.ifm_cur->ifm_media & IFM_OMASK) { 2779 case 0: 2780 sc->wi_ptype = WI_PORTTYPE_BSS; 2781 break; 2782 case IFM_IEEE80211_ADHOC: 2783 sc->wi_ptype = WI_PORTTYPE_ADHOC; 2784 break; 2785 case IFM_IEEE80211_HOSTAP: 2786 sc->wi_ptype = WI_PORTTYPE_HOSTAP; 2787 break; 2788 case IFM_IEEE80211_IBSSMASTER: 2789 case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS: 2790 if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) 2791 return (EINVAL); 2792 sc->wi_create_ibss = 1; 2793 /* FALLTHROUGH */ 2794 case IFM_IEEE80211_IBSS: 2795 sc->wi_ptype = WI_PORTTYPE_IBSS; 2796 break; 2797 default: 2798 /* Invalid combination. */ 2799 return (EINVAL); 2800 } 2801 2802 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) { 2803 case IFM_IEEE80211_DS1: 2804 sc->wi_tx_rate = 1; 2805 break; 2806 case IFM_IEEE80211_DS2: 2807 sc->wi_tx_rate = 2; 2808 break; 2809 case IFM_AUTO: 2810 sc->wi_tx_rate = 3; 2811 break; 2812 case IFM_IEEE80211_DS5: 2813 sc->wi_tx_rate = 5; 2814 break; 2815 case IFM_IEEE80211_DS11: 2816 sc->wi_tx_rate = 11; 2817 break; 2818 } 2819 2820 if (sc->sc_ic.ic_if.if_flags & IFF_UP) { 2821 if (otype != sc->wi_ptype || orate != sc->wi_tx_rate || 2822 ocreate_ibss != sc->wi_create_ibss) 2823 wi_init(sc); 2824 } 2825 2826 ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media); 2827 2828 return (0); 2829 } 2830 2831 STATIC void 2832 wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) 2833 { 2834 struct wi_softc *sc = ifp->if_softc; 2835 struct wi_req wreq; 2836 2837 if (!(sc->sc_ic.ic_if.if_flags & IFF_UP)) { 2838 imr->ifm_active = IFM_IEEE80211|IFM_NONE; 2839 imr->ifm_status = 0; 2840 return; 2841 } 2842 2843 if (sc->wi_tx_rate == 3) { 2844 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2845 2846 wreq.wi_type = WI_RID_CUR_TX_RATE; 2847 wreq.wi_len = WI_MAX_DATALEN; 2848 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) { 2849 switch (letoh16(wreq.wi_val[0])) { 2850 case 1: 2851 imr->ifm_active |= IFM_IEEE80211_DS1; 2852 break; 2853 case 2: 2854 imr->ifm_active |= IFM_IEEE80211_DS2; 2855 break; 2856 case 6: 2857 imr->ifm_active |= IFM_IEEE80211_DS5; 2858 break; 2859 case 11: 2860 imr->ifm_active |= IFM_IEEE80211_DS11; 2861 break; 2862 } 2863 } 2864 } else { 2865 imr->ifm_active = sc->sc_media.ifm_cur->ifm_media; 2866 } 2867 2868 imr->ifm_status = IFM_AVALID; 2869 switch (sc->wi_ptype) { 2870 case WI_PORTTYPE_ADHOC: 2871 case WI_PORTTYPE_IBSS: 2872 /* 2873 * XXX: It would be nice if we could give some actually 2874 * useful status like whether we joined another IBSS or 2875 * created one ourselves. 2876 */ 2877 /* FALLTHROUGH */ 2878 case WI_PORTTYPE_HOSTAP: 2879 imr->ifm_status |= IFM_ACTIVE; 2880 break; 2881 default: 2882 wreq.wi_type = WI_RID_COMMQUAL; 2883 wreq.wi_len = WI_MAX_DATALEN; 2884 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 && 2885 letoh16(wreq.wi_val[0]) != 0) 2886 imr->ifm_status |= IFM_ACTIVE; 2887 } 2888 } 2889 2890 STATIC int 2891 wi_set_nwkey(struct wi_softc *sc, struct ieee80211_nwkey *nwkey) 2892 { 2893 int i, len, error; 2894 struct wi_req wreq; 2895 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq; 2896 2897 if (!(sc->wi_flags & WI_FLAGS_HAS_WEP)) 2898 return ENODEV; 2899 if (nwkey->i_defkid <= 0 || nwkey->i_defkid > IEEE80211_WEP_NKID) 2900 return EINVAL; 2901 memcpy(wk, &sc->wi_keys, sizeof(*wk)); 2902 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2903 if (nwkey->i_key[i].i_keydat == NULL) 2904 continue; 2905 len = nwkey->i_key[i].i_keylen; 2906 if (len > sizeof(wk->wi_keys[i].wi_keydat)) 2907 return EINVAL; 2908 error = copyin(nwkey->i_key[i].i_keydat, 2909 wk->wi_keys[i].wi_keydat, len); 2910 if (error) 2911 return error; 2912 wk->wi_keys[i].wi_keylen = htole16(len); 2913 } 2914 2915 wk->wi_len = (sizeof(*wk) / 2) + 1; 2916 wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS; 2917 if (sc->sc_ic.ic_if.if_flags & IFF_UP) { 2918 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2919 if (error) 2920 return error; 2921 } 2922 if ((error = wi_setdef(sc, &wreq))) 2923 return (error); 2924 2925 wreq.wi_len = 2; 2926 wreq.wi_type = WI_RID_TX_CRYPT_KEY; 2927 wreq.wi_val[0] = htole16(nwkey->i_defkid - 1); 2928 if (sc->sc_ic.ic_if.if_flags & IFF_UP) { 2929 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2930 if (error) 2931 return error; 2932 } 2933 if ((error = wi_setdef(sc, &wreq))) 2934 return (error); 2935 2936 wreq.wi_type = WI_RID_ENCRYPTION; 2937 wreq.wi_val[0] = htole16(nwkey->i_wepon); 2938 if (sc->sc_ic.ic_if.if_flags & IFF_UP) { 2939 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2940 if (error) 2941 return error; 2942 } 2943 if ((error = wi_setdef(sc, &wreq))) 2944 return (error); 2945 2946 if (sc->sc_ic.ic_if.if_flags & IFF_UP) 2947 wi_init(sc); 2948 return 0; 2949 } 2950 2951 STATIC int 2952 wi_get_nwkey(struct wi_softc *sc, struct ieee80211_nwkey *nwkey) 2953 { 2954 int i, len, error; 2955 struct wi_ltv_keys *wk = &sc->wi_keys; 2956 2957 if (!(sc->wi_flags & WI_FLAGS_HAS_WEP)) 2958 return ENODEV; 2959 nwkey->i_wepon = sc->wi_use_wep; 2960 nwkey->i_defkid = sc->wi_tx_key + 1; 2961 2962 /* do not show any keys to non-root user */ 2963 error = suser(curproc, 0); 2964 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2965 if (nwkey->i_key[i].i_keydat == NULL) 2966 continue; 2967 /* error holds results of suser() for the first time */ 2968 if (error) 2969 return error; 2970 len = letoh16(wk->wi_keys[i].wi_keylen); 2971 if (nwkey->i_key[i].i_keylen < len) 2972 return ENOSPC; 2973 nwkey->i_key[i].i_keylen = len; 2974 error = copyout(wk->wi_keys[i].wi_keydat, 2975 nwkey->i_key[i].i_keydat, len); 2976 if (error) 2977 return error; 2978 } 2979 return 0; 2980 } 2981 2982 STATIC int 2983 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power) 2984 { 2985 2986 sc->wi_pm_enabled = power->i_enabled; 2987 sc->wi_max_sleep = power->i_maxsleep; 2988 2989 if (sc->sc_ic.ic_if.if_flags & IFF_UP) 2990 wi_init(sc); 2991 2992 return (0); 2993 } 2994 2995 STATIC int 2996 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power) 2997 { 2998 2999 power->i_enabled = sc->wi_pm_enabled; 3000 power->i_maxsleep = sc->wi_max_sleep; 3001 3002 return (0); 3003 } 3004 3005 STATIC int 3006 wi_set_txpower(struct wi_softc *sc, struct ieee80211_txpower *txpower) 3007 { 3008 u_int16_t cmd; 3009 u_int16_t power; 3010 int8_t tmp; 3011 int error; 3012 int alc; 3013 3014 if (txpower == NULL) { 3015 if (!(sc->wi_flags & WI_FLAGS_TXPOWER)) 3016 return (EINVAL); 3017 alc = 0; /* disable ALC */ 3018 } else { 3019 if (txpower->i_mode == IEEE80211_TXPOWER_MODE_AUTO) { 3020 alc = 1; /* enable ALC */ 3021 sc->wi_flags &= ~WI_FLAGS_TXPOWER; 3022 } else { 3023 alc = 0; /* disable ALC */ 3024 sc->wi_flags |= WI_FLAGS_TXPOWER; 3025 sc->wi_txpower = txpower->i_val; 3026 } 3027 } 3028 3029 /* Set ALC */ 3030 cmd = WI_CMD_DEBUG | (WI_DEBUG_CONFBITS << 8); 3031 if ((error = wi_cmd(sc, cmd, alc, 0x8, 0)) != 0) 3032 return (error); 3033 3034 /* No need to set the TX power value if ALC is enabled */ 3035 if (alc) 3036 return (0); 3037 3038 /* Convert dBM to internal TX power value */ 3039 if (sc->wi_txpower > 20) 3040 power = 128; 3041 else if (sc->wi_txpower < -43) 3042 power = 127; 3043 else { 3044 tmp = sc->wi_txpower; 3045 tmp = -12 - tmp; 3046 tmp <<= 2; 3047 3048 power = (u_int16_t)tmp; 3049 } 3050 3051 /* Set manual TX power */ 3052 cmd = WI_CMD_WRITE_MIF; 3053 if ((error = wi_cmd(sc, cmd, 3054 WI_HFA384X_CR_MANUAL_TX_POWER, power, 0)) != 0) 3055 return (error); 3056 3057 if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG) 3058 printf("%s: %u (%d dBm)\n", sc->sc_dev.dv_xname, power, 3059 sc->wi_txpower); 3060 3061 return (0); 3062 } 3063 3064 STATIC int 3065 wi_get_txpower(struct wi_softc *sc, struct ieee80211_txpower *txpower) 3066 { 3067 u_int16_t cmd; 3068 u_int16_t power; 3069 int8_t tmp; 3070 int error; 3071 3072 if (sc->wi_flags & WI_FLAGS_BUS_USB) 3073 return (EOPNOTSUPP); 3074 3075 /* Get manual TX power */ 3076 cmd = WI_CMD_READ_MIF; 3077 if ((error = wi_cmd(sc, cmd, 3078 WI_HFA384X_CR_MANUAL_TX_POWER, 0, 0)) != 0) 3079 return (error); 3080 3081 power = CSR_READ_2(sc, WI_RESP0); 3082 3083 /* Convert internal TX power value to dBM */ 3084 if (power > 255) 3085 txpower->i_val = 255; 3086 else { 3087 tmp = power; 3088 tmp >>= 2; 3089 txpower->i_val = (u_int16_t)(-12 - tmp); 3090 } 3091 3092 if (sc->wi_flags & WI_FLAGS_TXPOWER) 3093 txpower->i_mode = IEEE80211_TXPOWER_MODE_FIXED; 3094 else 3095 txpower->i_mode = IEEE80211_TXPOWER_MODE_AUTO; 3096 3097 return (0); 3098 } 3099 3100 STATIC int 3101 wi_set_ssid(struct ieee80211_nwid *ws, u_int8_t *id, int len) 3102 { 3103 3104 if (len > IEEE80211_NWID_LEN) 3105 return (EINVAL); 3106 ws->i_len = len; 3107 memcpy(ws->i_nwid, id, len); 3108 return (0); 3109 } 3110 3111 STATIC int 3112 wi_get_debug(struct wi_softc *sc, struct wi_req *wreq) 3113 { 3114 int error = 0; 3115 3116 wreq->wi_len = 1; 3117 3118 switch (wreq->wi_type) { 3119 case WI_DEBUG_SLEEP: 3120 wreq->wi_len++; 3121 wreq->wi_val[0] = htole16(sc->wi_debug.wi_sleep); 3122 break; 3123 case WI_DEBUG_DELAYSUPP: 3124 wreq->wi_len++; 3125 wreq->wi_val[0] = htole16(sc->wi_debug.wi_delaysupp); 3126 break; 3127 case WI_DEBUG_TXSUPP: 3128 wreq->wi_len++; 3129 wreq->wi_val[0] = htole16(sc->wi_debug.wi_txsupp); 3130 break; 3131 case WI_DEBUG_MONITOR: 3132 wreq->wi_len++; 3133 wreq->wi_val[0] = htole16(sc->wi_debug.wi_monitor); 3134 break; 3135 case WI_DEBUG_LEDTEST: 3136 wreq->wi_len += 3; 3137 wreq->wi_val[0] = htole16(sc->wi_debug.wi_ledtest); 3138 wreq->wi_val[1] = htole16(sc->wi_debug.wi_ledtest_param0); 3139 wreq->wi_val[2] = htole16(sc->wi_debug.wi_ledtest_param1); 3140 break; 3141 case WI_DEBUG_CONTTX: 3142 wreq->wi_len += 2; 3143 wreq->wi_val[0] = htole16(sc->wi_debug.wi_conttx); 3144 wreq->wi_val[1] = htole16(sc->wi_debug.wi_conttx_param0); 3145 break; 3146 case WI_DEBUG_CONTRX: 3147 wreq->wi_len++; 3148 wreq->wi_val[0] = htole16(sc->wi_debug.wi_contrx); 3149 break; 3150 case WI_DEBUG_SIGSTATE: 3151 wreq->wi_len += 2; 3152 wreq->wi_val[0] = htole16(sc->wi_debug.wi_sigstate); 3153 wreq->wi_val[1] = htole16(sc->wi_debug.wi_sigstate_param0); 3154 break; 3155 case WI_DEBUG_CONFBITS: 3156 wreq->wi_len += 2; 3157 wreq->wi_val[0] = htole16(sc->wi_debug.wi_confbits); 3158 wreq->wi_val[1] = htole16(sc->wi_debug.wi_confbits_param0); 3159 break; 3160 default: 3161 error = EIO; 3162 break; 3163 } 3164 3165 return (error); 3166 } 3167 3168 STATIC int 3169 wi_set_debug(struct wi_softc *sc, struct wi_req *wreq) 3170 { 3171 int error = 0; 3172 u_int16_t cmd, param0 = 0, param1 = 0; 3173 3174 switch (wreq->wi_type) { 3175 case WI_DEBUG_RESET: 3176 case WI_DEBUG_INIT: 3177 case WI_DEBUG_CALENABLE: 3178 break; 3179 case WI_DEBUG_SLEEP: 3180 sc->wi_debug.wi_sleep = 1; 3181 break; 3182 case WI_DEBUG_WAKE: 3183 sc->wi_debug.wi_sleep = 0; 3184 break; 3185 case WI_DEBUG_CHAN: 3186 param0 = letoh16(wreq->wi_val[0]); 3187 break; 3188 case WI_DEBUG_DELAYSUPP: 3189 sc->wi_debug.wi_delaysupp = 1; 3190 break; 3191 case WI_DEBUG_TXSUPP: 3192 sc->wi_debug.wi_txsupp = 1; 3193 break; 3194 case WI_DEBUG_MONITOR: 3195 sc->wi_debug.wi_monitor = 1; 3196 break; 3197 case WI_DEBUG_LEDTEST: 3198 param0 = letoh16(wreq->wi_val[0]); 3199 param1 = letoh16(wreq->wi_val[1]); 3200 sc->wi_debug.wi_ledtest = 1; 3201 sc->wi_debug.wi_ledtest_param0 = param0; 3202 sc->wi_debug.wi_ledtest_param1 = param1; 3203 break; 3204 case WI_DEBUG_CONTTX: 3205 param0 = letoh16(wreq->wi_val[0]); 3206 sc->wi_debug.wi_conttx = 1; 3207 sc->wi_debug.wi_conttx_param0 = param0; 3208 break; 3209 case WI_DEBUG_STOPTEST: 3210 sc->wi_debug.wi_delaysupp = 0; 3211 sc->wi_debug.wi_txsupp = 0; 3212 sc->wi_debug.wi_monitor = 0; 3213 sc->wi_debug.wi_ledtest = 0; 3214 sc->wi_debug.wi_ledtest_param0 = 0; 3215 sc->wi_debug.wi_ledtest_param1 = 0; 3216 sc->wi_debug.wi_conttx = 0; 3217 sc->wi_debug.wi_conttx_param0 = 0; 3218 sc->wi_debug.wi_contrx = 0; 3219 sc->wi_debug.wi_sigstate = 0; 3220 sc->wi_debug.wi_sigstate_param0 = 0; 3221 break; 3222 case WI_DEBUG_CONTRX: 3223 sc->wi_debug.wi_contrx = 1; 3224 break; 3225 case WI_DEBUG_SIGSTATE: 3226 param0 = letoh16(wreq->wi_val[0]); 3227 sc->wi_debug.wi_sigstate = 1; 3228 sc->wi_debug.wi_sigstate_param0 = param0; 3229 break; 3230 case WI_DEBUG_CONFBITS: 3231 param0 = letoh16(wreq->wi_val[0]); 3232 param1 = letoh16(wreq->wi_val[1]); 3233 sc->wi_debug.wi_confbits = param0; 3234 sc->wi_debug.wi_confbits_param0 = param1; 3235 break; 3236 default: 3237 error = EIO; 3238 break; 3239 } 3240 3241 if (error) 3242 return (error); 3243 3244 cmd = WI_CMD_DEBUG | (wreq->wi_type << 8); 3245 error = wi_cmd(sc, cmd, param0, param1, 0); 3246 3247 return (error); 3248 } 3249