1 /* $NetBSD: wi.c,v 1.16 2001/06/04 03:34:47 toshii 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 35 /* 36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD. 37 * 38 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City 41 */ 42 43 /* 44 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 45 * from Lucent. Unlike the older cards, the new ones are programmed 46 * entirely via a firmware-driven controller called the Hermes. 47 * Unfortunately, Lucent will not release the Hermes programming manual 48 * without an NDA (if at all). What they do release is an API library 49 * called the HCF (Hardware Control Functions) which is supposed to 50 * do the device-specific operations of a device driver for you. The 51 * publically available version of the HCF library (the 'HCF Light') is 52 * a) extremely gross, b) lacks certain features, particularly support 53 * for 802.11 frames, and c) is contaminated by the GNU Public License. 54 * 55 * This driver does not use the HCF or HCF Light at all. Instead, it 56 * programs the Hermes controller directly, using information gleaned 57 * from the HCF Light code and corresponding documentation. 58 * 59 * This driver supports both the PCMCIA and ISA versions of the 60 * WaveLAN/IEEE cards. Note however that the ISA card isn't really 61 * anything of the sort: it's actually a PCMCIA bridge adapter 62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 63 * inserted. Consequently, you need to use the pccard support for 64 * both the ISA and PCMCIA adapters. 65 */ 66 67 /* 68 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the 69 * Oslo IETF plenary meeting. 70 */ 71 72 #define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 73 #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ 74 75 #include "opt_inet.h" 76 #include "bpfilter.h" 77 78 #include <sys/param.h> 79 #include <sys/systm.h> 80 #include <sys/callout.h> 81 #include <sys/device.h> 82 #include <sys/socket.h> 83 #include <sys/mbuf.h> 84 #include <sys/ioctl.h> 85 #include <sys/kernel.h> /* for hz */ 86 #include <sys/proc.h> 87 88 #include <net/if.h> 89 #include <net/if_dl.h> 90 #include <net/if_media.h> 91 #include <net/if_ether.h> 92 #include <net/if_ieee80211.h> 93 94 #ifdef INET 95 #include <netinet/in.h> 96 #include <netinet/in_systm.h> 97 #include <netinet/in_var.h> 98 #include <netinet/ip.h> 99 #include <netinet/if_inarp.h> 100 #endif 101 102 #if NBPFILTER > 0 103 #include <net/bpf.h> 104 #include <net/bpfdesc.h> 105 #endif 106 107 #include <dev/pcmcia/pcmciareg.h> 108 #include <dev/pcmcia/pcmciavar.h> 109 #include <dev/pcmcia/pcmciadevs.h> 110 111 #include <dev/ic/wi_ieee.h> 112 #include <dev/ic/wireg.h> 113 #include <dev/ic/wivar.h> 114 115 static void wi_reset __P((struct wi_softc *)); 116 static int wi_ioctl __P((struct ifnet *, u_long, caddr_t)); 117 static void wi_start __P((struct ifnet *)); 118 static void wi_watchdog __P((struct ifnet *)); 119 static int wi_init __P((struct ifnet *)); 120 static void wi_stop __P((struct ifnet *, int)); 121 static void wi_rxeof __P((struct wi_softc *)); 122 static void wi_txeof __P((struct wi_softc *, int)); 123 static void wi_update_stats __P((struct wi_softc *)); 124 static void wi_setmulti __P((struct wi_softc *)); 125 126 static int wi_cmd __P((struct wi_softc *, int, int)); 127 static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *)); 128 static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *)); 129 static int wi_read_data __P((struct wi_softc *, int, 130 int, caddr_t, int)); 131 static int wi_write_data __P((struct wi_softc *, int, 132 int, caddr_t, int)); 133 static int wi_seek __P((struct wi_softc *, int, int, int)); 134 static int wi_alloc_nicmem __P((struct wi_softc *, int, int *)); 135 static void wi_inquire __P((void *)); 136 static int wi_setdef __P((struct wi_softc *, struct wi_req *)); 137 static int wi_getdef __P((struct wi_softc *, struct wi_req *)); 138 static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int)); 139 140 static int wi_media_change __P((struct ifnet *)); 141 static void wi_media_status __P((struct ifnet *, struct ifmediareq *)); 142 143 static void wi_get_id __P((struct wi_softc *)); 144 145 static int wi_set_ssid __P((struct ieee80211_nwid *, u_int8_t *, int)); 146 static void wi_request_fill_ssid __P((struct wi_req *, 147 struct ieee80211_nwid *)); 148 static int wi_write_ssid __P((struct wi_softc *, int, struct wi_req *, 149 struct ieee80211_nwid *)); 150 static int wi_set_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *)); 151 static int wi_get_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *)); 152 static int wi_sync_media __P((struct wi_softc *, int, int)); 153 static int wi_set_pm(struct wi_softc *, struct ieee80211_power *); 154 static int wi_get_pm(struct wi_softc *, struct ieee80211_power *); 155 156 int 157 wi_attach(sc) 158 struct wi_softc *sc; 159 { 160 struct ifnet *ifp = sc->sc_ifp; 161 struct wi_ltv_macaddr mac; 162 struct wi_ltv_gen gen; 163 static const u_int8_t empty_macaddr[ETHER_ADDR_LEN] = { 164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 165 }; 166 int s; 167 168 s = splnet(); 169 170 callout_init(&sc->wi_inquire_ch); 171 172 /* Make sure interrupts are disabled. */ 173 CSR_WRITE_2(sc, WI_INT_EN, 0); 174 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 175 176 /* Reset the NIC. */ 177 wi_reset(sc); 178 179 memset(&mac, 0, sizeof(mac)); 180 /* Read the station address. */ 181 mac.wi_type = WI_RID_MAC_NODE; 182 mac.wi_len = 4; 183 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 184 memcpy(sc->sc_macaddr, mac.wi_mac_addr, ETHER_ADDR_LEN); 185 186 /* 187 * Check if we got anything meaningful. 188 * 189 * Is it really enough just checking against null ethernet address? 190 * Or, check against possible vendor? XXX. 191 */ 192 if (bcmp(sc->sc_macaddr, empty_macaddr, ETHER_ADDR_LEN) == 0) { 193 printf("%s: could not get mac address, attach failed\n", 194 sc->sc_dev.dv_xname); 195 return 1; 196 } 197 198 printf(" 802.11 address %s\n", ether_sprintf(sc->sc_macaddr)); 199 200 /* Read NIC identification */ 201 wi_get_id(sc); 202 203 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 204 ifp->if_softc = sc; 205 ifp->if_start = wi_start; 206 ifp->if_ioctl = wi_ioctl; 207 ifp->if_watchdog = wi_watchdog; 208 ifp->if_init = wi_init; 209 ifp->if_stop = wi_stop; 210 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 211 #ifdef IFF_NOTRAILERS 212 ifp->if_flags |= IFF_NOTRAILERS; 213 #endif 214 IFQ_SET_READY(&ifp->if_snd); 215 216 (void)wi_set_ssid(&sc->wi_nodeid, WI_DEFAULT_NODENAME, 217 sizeof(WI_DEFAULT_NODENAME) - 1); 218 (void)wi_set_ssid(&sc->wi_netid, WI_DEFAULT_NETNAME, 219 sizeof(WI_DEFAULT_NETNAME) - 1); 220 (void)wi_set_ssid(&sc->wi_ibssid, WI_DEFAULT_IBSS, 221 sizeof(WI_DEFAULT_IBSS) - 1); 222 223 sc->wi_portnum = WI_DEFAULT_PORT; 224 sc->wi_ptype = WI_PORTTYPE_BSS; 225 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 226 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 227 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 228 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 229 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 230 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 231 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 232 sc->wi_roaming = WI_DEFAULT_ROAMING; 233 sc->wi_authtype = WI_DEFAULT_AUTHTYPE; 234 235 /* 236 * Read the default channel from the NIC. This may vary 237 * depending on the country where the NIC was purchased, so 238 * we can't hard-code a default and expect it to work for 239 * everyone. 240 */ 241 gen.wi_type = WI_RID_OWN_CHNL; 242 gen.wi_len = 2; 243 wi_read_record(sc, &gen); 244 sc->wi_channel = le16toh(gen.wi_val); 245 246 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 247 248 /* 249 * Find out if we support WEP on this card. 250 */ 251 gen.wi_type = WI_RID_WEP_AVAIL; 252 gen.wi_len = 2; 253 wi_read_record(sc, &gen); 254 sc->wi_has_wep = le16toh(gen.wi_val); 255 256 ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status); 257 #define IFM_AUTOADHOC \ 258 IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0) 259 #define ADD(m, c) ifmedia_add(&sc->sc_media, (m), (c), NULL) 260 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 261 ADD(IFM_AUTOADHOC, 0); 262 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 263 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 264 IFM_IEEE80211_ADHOC, 0), 0); 265 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 266 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 267 IFM_IEEE80211_ADHOC, 0), 0); 268 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 269 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 270 IFM_IEEE80211_ADHOC, 0), 0); 271 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0); 272 #undef ADD 273 ifmedia_set(&sc->sc_media, IFM_AUTOADHOC); 274 275 /* 276 * Call MI attach routines. 277 */ 278 if_attach(ifp); 279 ether_ifattach(ifp, mac.wi_mac_addr); 280 281 ifp->if_baudrate = IF_Mbps(2); 282 283 /* Attach is successful. */ 284 sc->sc_attached = 1; 285 286 splx(s); 287 return 0; 288 } 289 290 static void wi_rxeof(sc) 291 struct wi_softc *sc; 292 { 293 struct ifnet *ifp; 294 struct ether_header *eh; 295 struct wi_frame rx_frame; 296 struct mbuf *m; 297 int id; 298 299 ifp = sc->sc_ifp; 300 301 id = CSR_READ_2(sc, WI_RX_FID); 302 303 /* First read in the frame header */ 304 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) { 305 ifp->if_ierrors++; 306 return; 307 } 308 309 if (le16toh(rx_frame.wi_status) & WI_STAT_ERRSTAT) { 310 ifp->if_ierrors++; 311 return; 312 } 313 314 MGETHDR(m, M_DONTWAIT, MT_DATA); 315 if (m == NULL) { 316 ifp->if_ierrors++; 317 return; 318 } 319 MCLGET(m, M_DONTWAIT); 320 if (!(m->m_flags & M_EXT)) { 321 m_freem(m); 322 ifp->if_ierrors++; 323 return; 324 } 325 326 /* Align the data after the ethernet header */ 327 m->m_data = (caddr_t) ALIGN(m->m_data + sizeof(struct ether_header)) 328 - sizeof(struct ether_header); 329 330 eh = mtod(m, struct ether_header *); 331 m->m_pkthdr.rcvif = ifp; 332 333 if (le16toh(rx_frame.wi_status) == WI_STAT_1042 || 334 le16toh(rx_frame.wi_status) == WI_STAT_TUNNEL || 335 le16toh(rx_frame.wi_status) == WI_STAT_WMP_MSG) { 336 if ((le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) > MCLBYTES) { 337 printf("%s: oversized packet received " 338 "(wi_dat_len=%d, wi_status=0x%x)\n", 339 sc->sc_dev.dv_xname, 340 le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status)); 341 m_freem(m); 342 ifp->if_ierrors++; 343 return; 344 } 345 m->m_pkthdr.len = m->m_len = 346 le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN; 347 348 bcopy((char *)&rx_frame.wi_dst_addr, 349 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 350 bcopy((char *)&rx_frame.wi_src_addr, 351 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 352 bcopy((char *)&rx_frame.wi_type, 353 (char *)&eh->ether_type, sizeof(u_int16_t)); 354 355 if (wi_read_data(sc, id, WI_802_11_OFFSET, 356 mtod(m, caddr_t) + sizeof(struct ether_header), 357 m->m_len + 2)) { 358 m_freem(m); 359 ifp->if_ierrors++; 360 return; 361 } 362 } else { 363 if ((le16toh(rx_frame.wi_dat_len) + 364 sizeof(struct ether_header)) > MCLBYTES) { 365 printf("%s: oversized packet received " 366 "(wi_dat_len=%d, wi_status=0x%x)\n", 367 sc->sc_dev.dv_xname, 368 le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status)); 369 m_freem(m); 370 ifp->if_ierrors++; 371 return; 372 } 373 m->m_pkthdr.len = m->m_len = 374 le16toh(rx_frame.wi_dat_len) + sizeof(struct ether_header); 375 376 if (wi_read_data(sc, id, WI_802_3_OFFSET, 377 mtod(m, caddr_t), m->m_len + 2)) { 378 m_freem(m); 379 ifp->if_ierrors++; 380 return; 381 } 382 } 383 384 ifp->if_ipackets++; 385 386 #if NBPFILTER > 0 387 /* Handle BPF listeners. */ 388 if (ifp->if_bpf) 389 bpf_mtap(ifp->if_bpf, m); 390 #endif 391 392 /* Receive packet. */ 393 (*ifp->if_input)(ifp, m); 394 } 395 396 static void wi_txeof(sc, status) 397 struct wi_softc *sc; 398 int status; 399 { 400 struct ifnet *ifp = sc->sc_ifp; 401 402 ifp->if_timer = 0; 403 ifp->if_flags &= ~IFF_OACTIVE; 404 405 if (status & WI_EV_TX_EXC) 406 ifp->if_oerrors++; 407 else 408 ifp->if_opackets++; 409 410 return; 411 } 412 413 void wi_inquire(xsc) 414 void *xsc; 415 { 416 struct wi_softc *sc; 417 struct ifnet *ifp; 418 419 sc = xsc; 420 ifp = &sc->sc_ethercom.ec_if; 421 422 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 423 return; 424 425 callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc); 426 427 /* Don't do this while we're transmitting */ 428 if (ifp->if_flags & IFF_OACTIVE) 429 return; 430 431 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS); 432 433 return; 434 } 435 436 void wi_update_stats(sc) 437 struct wi_softc *sc; 438 { 439 struct wi_ltv_gen gen; 440 u_int16_t id; 441 struct ifnet *ifp; 442 u_int32_t *ptr; 443 int len, i; 444 u_int16_t t; 445 446 ifp = &sc->sc_ethercom.ec_if; 447 448 id = CSR_READ_2(sc, WI_INFO_FID); 449 450 wi_read_data(sc, id, 0, (char *)&gen, 4); 451 452 if (gen.wi_type != WI_INFO_COUNTERS) 453 return; 454 455 /* some card versions have a larger stats structure */ 456 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ? 457 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4; 458 ptr = (u_int32_t *)&sc->wi_stats; 459 460 for (i = 0; i < len; i++) { 461 t = CSR_READ_2(sc, WI_DATA1); 462 #ifdef WI_HERMES_STATS_WAR 463 if (t > 0xF000) 464 t = ~t & 0xFFFF; 465 #endif 466 ptr[i] += t; 467 } 468 469 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 470 sc->wi_stats.wi_tx_multi_retries + 471 sc->wi_stats.wi_tx_retry_limit; 472 473 return; 474 } 475 476 int wi_intr(arg) 477 void *arg; 478 { 479 struct wi_softc *sc = arg; 480 struct ifnet *ifp; 481 u_int16_t status; 482 483 if (sc->sc_enabled == 0 || 484 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || 485 (sc->sc_ethercom.ec_if.if_flags & IFF_RUNNING) == 0) 486 return (0); 487 488 ifp = &sc->sc_ethercom.ec_if; 489 490 if (!(ifp->if_flags & IFF_UP)) { 491 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 492 CSR_WRITE_2(sc, WI_INT_EN, 0); 493 return 1; 494 } 495 496 /* Disable interrupts. */ 497 CSR_WRITE_2(sc, WI_INT_EN, 0); 498 499 status = CSR_READ_2(sc, WI_EVENT_STAT); 500 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS); 501 502 if (status & WI_EV_RX) { 503 wi_rxeof(sc); 504 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); 505 } 506 507 if (status & WI_EV_TX) { 508 wi_txeof(sc, status); 509 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX); 510 } 511 512 if (status & WI_EV_ALLOC) { 513 int id; 514 id = CSR_READ_2(sc, WI_ALLOC_FID); 515 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 516 if (id == sc->wi_tx_data_id) 517 wi_txeof(sc, status); 518 } 519 520 if (status & WI_EV_INFO) { 521 wi_update_stats(sc); 522 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); 523 } 524 525 if (status & WI_EV_TX_EXC) { 526 wi_txeof(sc, status); 527 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); 528 } 529 530 if (status & WI_EV_INFO_DROP) { 531 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP); 532 } 533 534 /* Re-enable interrupts. */ 535 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 536 537 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 538 wi_start(ifp); 539 540 return 1; 541 } 542 543 static int 544 wi_cmd(sc, cmd, val) 545 struct wi_softc *sc; 546 int cmd; 547 int val; 548 { 549 int i, s = 0; 550 551 /* wait for the busy bit to clear */ 552 for (i = 0; i < WI_TIMEOUT; i++) { 553 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) 554 break; 555 } 556 557 CSR_WRITE_2(sc, WI_PARAM0, val); 558 CSR_WRITE_2(sc, WI_PARAM1, 0); 559 CSR_WRITE_2(sc, WI_PARAM2, 0); 560 CSR_WRITE_2(sc, WI_COMMAND, cmd); 561 562 /* wait for the cmd completed bit */ 563 for (i = 0; i < WI_TIMEOUT; i++) { 564 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD) 565 break; 566 DELAY(1); 567 } 568 569 /* Ack the command */ 570 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 571 572 s = CSR_READ_2(sc, WI_STATUS); 573 if (s & WI_STAT_CMD_RESULT) 574 return(EIO); 575 576 if (i == WI_TIMEOUT) 577 return(ETIMEDOUT); 578 579 return(0); 580 } 581 582 static void 583 wi_reset(sc) 584 struct wi_softc *sc; 585 { 586 DELAY(100*1000); /* 100 m sec */ 587 if (wi_cmd(sc, WI_CMD_INI, 0)) 588 printf("%s: init failed\n", sc->sc_dev.dv_xname); 589 CSR_WRITE_2(sc, WI_INT_EN, 0); 590 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 591 592 /* Calibrate timer. */ 593 WI_SETVAL(WI_RID_TICK_TIME, 8); 594 595 return; 596 } 597 598 /* 599 * Read an LTV record from the NIC. 600 */ 601 static int wi_read_record(sc, ltv) 602 struct wi_softc *sc; 603 struct wi_ltv_gen *ltv; 604 { 605 u_int16_t *ptr; 606 int len, code; 607 struct wi_ltv_gen *oltv, p2ltv; 608 609 if (sc->sc_prism2) { 610 oltv = ltv; 611 switch (ltv->wi_type) { 612 case WI_RID_ENCRYPTION: 613 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 614 p2ltv.wi_len = 2; 615 ltv = &p2ltv; 616 break; 617 case WI_RID_TX_CRYPT_KEY: 618 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 619 p2ltv.wi_len = 2; 620 ltv = &p2ltv; 621 break; 622 } 623 } 624 625 /* Tell the NIC to enter record read mode. */ 626 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) 627 return(EIO); 628 629 /* Seek to the record. */ 630 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 631 return(EIO); 632 633 /* 634 * Read the length and record type and make sure they 635 * match what we expect (this verifies that we have enough 636 * room to hold all of the returned data). 637 */ 638 len = CSR_READ_2(sc, WI_DATA1); 639 if (len > ltv->wi_len) 640 return(ENOSPC); 641 code = CSR_READ_2(sc, WI_DATA1); 642 if (code != ltv->wi_type) 643 return(EIO); 644 645 ltv->wi_len = len; 646 ltv->wi_type = code; 647 648 /* Now read the data. */ 649 ptr = <v->wi_val; 650 if (ltv->wi_len > 1) 651 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1); 652 653 if (sc->sc_prism2) { 654 int v; 655 656 switch (oltv->wi_type) { 657 case WI_RID_TX_RATE: 658 case WI_RID_CUR_TX_RATE: 659 switch (le16toh(ltv->wi_val)) { 660 case 1: v = 1; break; 661 case 2: v = 2; break; 662 case 3: v = 6; break; 663 case 4: v = 5; break; 664 case 7: v = 7; break; 665 case 8: v = 11; break; 666 case 15: v = 3; break; 667 default: v = 0x100 + le16toh(ltv->wi_val); break; 668 } 669 oltv->wi_val = htole16(v); 670 break; 671 case WI_RID_ENCRYPTION: 672 oltv->wi_len = 2; 673 if (le16toh(ltv->wi_val) & 0x01) 674 oltv->wi_val = htole16(1); 675 else 676 oltv->wi_val = htole16(0); 677 break; 678 case WI_RID_TX_CRYPT_KEY: 679 oltv->wi_len = 2; 680 oltv->wi_val = ltv->wi_val; 681 break; 682 case WI_RID_AUTH_CNTL: 683 oltv->wi_len = 2; 684 if (le16toh(ltv->wi_val) & 0x01) 685 oltv->wi_val = htole16(1); 686 else if (le16toh(ltv->wi_val) & 0x02) 687 oltv->wi_val = htole16(2); 688 break; 689 } 690 } 691 692 return(0); 693 } 694 695 /* 696 * Same as read, except we inject data instead of reading it. 697 */ 698 static int wi_write_record(sc, ltv) 699 struct wi_softc *sc; 700 struct wi_ltv_gen *ltv; 701 { 702 u_int16_t *ptr; 703 int i; 704 struct wi_ltv_gen p2ltv; 705 706 if (sc->sc_prism2) { 707 int v; 708 709 switch (ltv->wi_type) { 710 case WI_RID_TX_RATE: 711 p2ltv.wi_type = WI_RID_TX_RATE; 712 p2ltv.wi_len = 2; 713 switch (le16toh(ltv->wi_val)) { 714 case 1: v = 1; break; 715 case 2: v = 2; break; 716 case 3: v = 15; break; 717 case 5: v = 4; break; 718 case 6: v = 3; break; 719 case 7: v = 7; break; 720 case 11: v = 8; break; 721 default: return EINVAL; 722 } 723 p2ltv.wi_val = htole16(v); 724 ltv = &p2ltv; 725 break; 726 case WI_RID_ENCRYPTION: 727 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 728 p2ltv.wi_len = 2; 729 if (le16toh(ltv->wi_val)) 730 p2ltv.wi_val = htole16(0x03); 731 else 732 p2ltv.wi_val = htole16(0x90); 733 ltv = &p2ltv; 734 break; 735 case WI_RID_TX_CRYPT_KEY: 736 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 737 p2ltv.wi_len = 2; 738 p2ltv.wi_val = ltv->wi_val; 739 ltv = &p2ltv; 740 break; 741 case WI_RID_DEFLT_CRYPT_KEYS: 742 { 743 int error; 744 struct wi_ltv_str ws; 745 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv; 746 for (i = 0; i < 4; i++) { 747 ws.wi_len = 4; 748 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 749 memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5); 750 ws.wi_str[5] = '\0'; 751 error = wi_write_record(sc, 752 (struct wi_ltv_gen *)&ws); 753 if (error) 754 return error; 755 } 756 return 0; 757 } 758 case WI_RID_AUTH_CNTL: 759 p2ltv.wi_type = WI_RID_AUTH_CNTL; 760 p2ltv.wi_len = 2; 761 if (le16toh(ltv->wi_val) == 1) 762 p2ltv.wi_val = htole16(0x01); 763 else if (le16toh(ltv->wi_val) == 2) 764 p2ltv.wi_val = htole16(0x02); 765 ltv = &p2ltv; 766 break; 767 } 768 } 769 770 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 771 return(EIO); 772 773 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 774 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 775 776 /* Write data */ 777 ptr = <v->wi_val; 778 if (ltv->wi_len > 1) 779 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1); 780 781 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type)) 782 return(EIO); 783 784 return(0); 785 } 786 787 static int wi_seek(sc, id, off, chan) 788 struct wi_softc *sc; 789 int id, off, chan; 790 { 791 int i; 792 int selreg, offreg; 793 int status; 794 795 switch (chan) { 796 case WI_BAP0: 797 selreg = WI_SEL0; 798 offreg = WI_OFF0; 799 break; 800 case WI_BAP1: 801 selreg = WI_SEL1; 802 offreg = WI_OFF1; 803 break; 804 default: 805 printf("%s: invalid data path: %x\n", 806 sc->sc_dev.dv_xname, chan); 807 return(EIO); 808 } 809 810 CSR_WRITE_2(sc, selreg, id); 811 CSR_WRITE_2(sc, offreg, off); 812 813 for (i = 0; i < WI_TIMEOUT; i++) { 814 status = CSR_READ_2(sc, offreg); 815 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR))) 816 break; 817 } 818 819 if (i == WI_TIMEOUT) { 820 printf("%s: timeout in wi_seek to %x/%x; last status %x\n", 821 sc->sc_dev.dv_xname, id, off, status); 822 return(ETIMEDOUT); 823 } 824 return(0); 825 } 826 827 static int wi_read_data(sc, id, off, buf, len) 828 struct wi_softc *sc; 829 int id, off; 830 caddr_t buf; 831 int len; 832 { 833 u_int16_t *ptr; 834 835 if (wi_seek(sc, id, off, WI_BAP1)) 836 return(EIO); 837 838 ptr = (u_int16_t *)buf; 839 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, len / 2); 840 841 return(0); 842 } 843 844 /* 845 * According to the comments in the HCF Light code, there is a bug in 846 * the Hermes (or possibly in certain Hermes firmware revisions) where 847 * the chip's internal autoincrement counter gets thrown off during 848 * data writes: the autoincrement is missed, causing one data word to 849 * be overwritten and subsequent words to be written to the wrong memory 850 * locations. The end result is that we could end up transmitting bogus 851 * frames without realizing it. The workaround for this is to write a 852 * couple of extra guard words after the end of the transfer, then 853 * attempt to read then back. If we fail to locate the guard words where 854 * we expect them, we preform the transfer over again. 855 */ 856 static int wi_write_data(sc, id, off, buf, len) 857 struct wi_softc *sc; 858 int id, off; 859 caddr_t buf; 860 int len; 861 { 862 u_int16_t *ptr; 863 864 #ifdef WI_HERMES_AUTOINC_WAR 865 again: 866 #endif 867 868 if (wi_seek(sc, id, off, WI_BAP0)) 869 return(EIO); 870 871 ptr = (u_int16_t *)buf; 872 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, ptr, len / 2); 873 874 #ifdef WI_HERMES_AUTOINC_WAR 875 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 876 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 877 878 if (wi_seek(sc, id, off + len, WI_BAP0)) 879 return(EIO); 880 881 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 882 CSR_READ_2(sc, WI_DATA0) != 0x5678) 883 goto again; 884 #endif 885 886 return(0); 887 } 888 889 /* 890 * Allocate a region of memory inside the NIC and zero 891 * it out. 892 */ 893 static int wi_alloc_nicmem(sc, len, id) 894 struct wi_softc *sc; 895 int len; 896 int *id; 897 { 898 int i; 899 900 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { 901 printf("%s: failed to allocate %d bytes on NIC\n", 902 sc->sc_dev.dv_xname, len); 903 return(ENOMEM); 904 } 905 906 for (i = 0; i < WI_TIMEOUT; i++) { 907 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 908 break; 909 } 910 911 if (i == WI_TIMEOUT) { 912 printf("%s: TIMED OUT in alloc\n", sc->sc_dev.dv_xname); 913 return(ETIMEDOUT); 914 } 915 916 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 917 *id = CSR_READ_2(sc, WI_ALLOC_FID); 918 919 if (wi_seek(sc, *id, 0, WI_BAP0)) { 920 printf("%s: seek failed in alloc\n", sc->sc_dev.dv_xname); 921 return(EIO); 922 } 923 924 for (i = 0; i < len / 2; i++) 925 CSR_WRITE_2(sc, WI_DATA0, 0); 926 927 return(0); 928 } 929 930 static void wi_setmulti(sc) 931 struct wi_softc *sc; 932 { 933 struct ifnet *ifp; 934 int i = 0; 935 struct wi_ltv_mcast mcast; 936 struct ether_multi *enm; 937 struct ether_multistep estep; 938 struct ethercom *ec = &sc->sc_ethercom; 939 940 ifp = &sc->sc_ethercom.ec_if; 941 942 if ((ifp->if_flags & IFF_PROMISC) != 0) { 943 allmulti: 944 ifp->if_flags |= IFF_ALLMULTI; 945 bzero((char *)&mcast, sizeof(mcast)); 946 mcast.wi_type = WI_RID_MCAST; 947 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1; 948 949 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 950 return; 951 } 952 953 i = 0; 954 ETHER_FIRST_MULTI(estep, ec, enm); 955 while (enm != NULL) { 956 /* Punt on ranges or too many multicast addresses. */ 957 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 958 ETHER_ADDR_LEN) != 0 || 959 i >= 16) 960 goto allmulti; 961 962 bcopy(enm->enm_addrlo, 963 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN); 964 i++; 965 ETHER_NEXT_MULTI(estep, enm); 966 } 967 968 ifp->if_flags &= ~IFF_ALLMULTI; 969 mcast.wi_type = WI_RID_MCAST; 970 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * i) + 1; 971 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 972 } 973 974 static int 975 wi_setdef(sc, wreq) 976 struct wi_softc *sc; 977 struct wi_req *wreq; 978 { 979 struct sockaddr_dl *sdl; 980 struct ifnet *ifp; 981 int error = 0; 982 983 ifp = &sc->sc_ethercom.ec_if; 984 985 switch(wreq->wi_type) { 986 case WI_RID_MAC_NODE: 987 sdl = (struct sockaddr_dl *)ifp->if_sadl; 988 bcopy((char *)&wreq->wi_val, (char *)&sc->sc_macaddr, 989 ETHER_ADDR_LEN); 990 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 991 break; 992 case WI_RID_PORTTYPE: 993 error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate); 994 break; 995 case WI_RID_TX_RATE: 996 error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0])); 997 break; 998 case WI_RID_MAX_DATALEN: 999 sc->wi_max_data_len = le16toh(wreq->wi_val[0]); 1000 break; 1001 case WI_RID_RTS_THRESH: 1002 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]); 1003 break; 1004 case WI_RID_SYSTEM_SCALE: 1005 sc->wi_ap_density = le16toh(wreq->wi_val[0]); 1006 break; 1007 case WI_RID_CREATE_IBSS: 1008 sc->wi_create_ibss = le16toh(wreq->wi_val[0]); 1009 break; 1010 case WI_RID_OWN_CHNL: 1011 sc->wi_channel = le16toh(wreq->wi_val[0]); 1012 break; 1013 case WI_RID_NODENAME: 1014 error = wi_set_ssid(&sc->wi_nodeid, 1015 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1016 break; 1017 case WI_RID_DESIRED_SSID: 1018 error = wi_set_ssid(&sc->wi_netid, 1019 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1020 break; 1021 case WI_RID_OWN_SSID: 1022 error = wi_set_ssid(&sc->wi_ibssid, 1023 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1024 break; 1025 case WI_RID_PM_ENABLED: 1026 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]); 1027 break; 1028 case WI_RID_MICROWAVE_OVEN: 1029 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]); 1030 break; 1031 case WI_RID_MAX_SLEEP: 1032 sc->wi_max_sleep = le16toh(wreq->wi_val[0]); 1033 break; 1034 case WI_RID_AUTH_CNTL: 1035 sc->wi_authtype = le16toh(wreq->wi_val[0]); 1036 break; 1037 case WI_RID_ROAMING_MODE: 1038 sc->wi_roaming = le16toh(wreq->wi_val[0]); 1039 break; 1040 case WI_RID_ENCRYPTION: 1041 sc->wi_use_wep = le16toh(wreq->wi_val[0]); 1042 break; 1043 case WI_RID_TX_CRYPT_KEY: 1044 sc->wi_tx_key = le16toh(wreq->wi_val[0]); 1045 break; 1046 case WI_RID_DEFLT_CRYPT_KEYS: 1047 bcopy((char *)wreq, (char *)&sc->wi_keys, 1048 sizeof(struct wi_ltv_keys)); 1049 break; 1050 default: 1051 error = EINVAL; 1052 break; 1053 } 1054 1055 return (error); 1056 } 1057 1058 static int 1059 wi_getdef(sc, wreq) 1060 struct wi_softc *sc; 1061 struct wi_req *wreq; 1062 { 1063 struct sockaddr_dl *sdl; 1064 struct ifnet *ifp; 1065 int error = 0; 1066 1067 ifp = &sc->sc_ethercom.ec_if; 1068 1069 wreq->wi_len = 2; /* XXX */ 1070 switch (wreq->wi_type) { 1071 case WI_RID_MAC_NODE: 1072 wreq->wi_len += ETHER_ADDR_LEN / 2 - 1; 1073 sdl = (struct sockaddr_dl *)ifp->if_sadl; 1074 bcopy(&sc->sc_macaddr, &wreq->wi_val, ETHER_ADDR_LEN); 1075 bcopy(LLADDR(sdl), &wreq->wi_val, ETHER_ADDR_LEN); 1076 break; 1077 case WI_RID_PORTTYPE: 1078 wreq->wi_val[0] = htole16(sc->wi_ptype); 1079 break; 1080 case WI_RID_TX_RATE: 1081 wreq->wi_val[0] = htole16(sc->wi_tx_rate); 1082 break; 1083 case WI_RID_MAX_DATALEN: 1084 wreq->wi_val[0] = htole16(sc->wi_max_data_len); 1085 break; 1086 case WI_RID_RTS_THRESH: 1087 wreq->wi_val[0] = htole16(sc->wi_rts_thresh); 1088 break; 1089 case WI_RID_SYSTEM_SCALE: 1090 wreq->wi_val[0] = htole16(sc->wi_ap_density); 1091 break; 1092 case WI_RID_CREATE_IBSS: 1093 wreq->wi_val[0] = htole16(sc->wi_create_ibss); 1094 break; 1095 case WI_RID_OWN_CHNL: 1096 wreq->wi_val[0] = htole16(sc->wi_channel); 1097 break; 1098 case WI_RID_NODENAME: 1099 wi_request_fill_ssid(wreq, &sc->wi_nodeid); 1100 break; 1101 case WI_RID_DESIRED_SSID: 1102 wi_request_fill_ssid(wreq, &sc->wi_netid); 1103 break; 1104 case WI_RID_OWN_SSID: 1105 wi_request_fill_ssid(wreq, &sc->wi_ibssid); 1106 break; 1107 case WI_RID_PM_ENABLED: 1108 wreq->wi_val[0] = htole16(sc->wi_pm_enabled); 1109 break; 1110 case WI_RID_MICROWAVE_OVEN: 1111 wreq->wi_val[0] = htole16(sc->wi_mor_enabled); 1112 break; 1113 case WI_RID_MAX_SLEEP: 1114 wreq->wi_val[0] = htole16(sc->wi_max_sleep); 1115 break; 1116 case WI_RID_AUTH_CNTL: 1117 wreq->wi_val[0] = htole16(sc->wi_authtype); 1118 break; 1119 case WI_RID_ROAMING_MODE: 1120 wreq->wi_val[0] = htole16(sc->wi_roaming); 1121 break; 1122 case WI_RID_WEP_AVAIL: 1123 wreq->wi_val[0] = htole16(sc->wi_has_wep); 1124 break; 1125 case WI_RID_ENCRYPTION: 1126 wreq->wi_val[0] = htole16(sc->wi_use_wep); 1127 break; 1128 case WI_RID_TX_CRYPT_KEY: 1129 wreq->wi_val[0] = htole16(sc->wi_tx_key); 1130 break; 1131 case WI_RID_DEFLT_CRYPT_KEYS: 1132 wreq->wi_len += sizeof(struct wi_ltv_keys) / 2 - 1; 1133 bcopy(&sc->wi_keys, wreq, sizeof(struct wi_ltv_keys)); 1134 break; 1135 default: 1136 #if 0 1137 error = EIO; 1138 #else 1139 #ifdef WI_DEBUG 1140 printf("%s: wi_getdef: unknown request %d\n", 1141 sc->sc_dev.dv_xname, wreq->wi_type); 1142 #endif 1143 #endif 1144 break; 1145 } 1146 1147 return (error); 1148 } 1149 1150 static int 1151 wi_ioctl(ifp, command, data) 1152 struct ifnet *ifp; 1153 u_long command; 1154 caddr_t data; 1155 { 1156 int s, error = 0; 1157 struct wi_softc *sc = ifp->if_softc; 1158 struct wi_req wreq; 1159 struct ifreq *ifr; 1160 struct proc *p = curproc; 1161 struct ieee80211_nwid nwid; 1162 1163 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 1164 return (ENXIO); 1165 1166 s = splnet(); 1167 1168 ifr = (struct ifreq *)data; 1169 switch (command) { 1170 case SIOCSIFADDR: 1171 case SIOCGIFADDR: 1172 case SIOCSIFMTU: 1173 error = ether_ioctl(ifp, command, data); 1174 break; 1175 case SIOCSIFFLAGS: 1176 if (ifp->if_flags & IFF_UP) { 1177 if (ifp->if_flags & IFF_RUNNING && 1178 ifp->if_flags & IFF_PROMISC && 1179 !(sc->wi_if_flags & IFF_PROMISC)) { 1180 WI_SETVAL(WI_RID_PROMISC, 1); 1181 } else if (ifp->if_flags & IFF_RUNNING && 1182 !(ifp->if_flags & IFF_PROMISC) && 1183 sc->wi_if_flags & IFF_PROMISC) { 1184 WI_SETVAL(WI_RID_PROMISC, 0); 1185 } 1186 wi_init(ifp); 1187 } else { 1188 if (ifp->if_flags & IFF_RUNNING) { 1189 wi_stop(ifp, 0); 1190 } 1191 } 1192 sc->wi_if_flags = ifp->if_flags; 1193 1194 if (!(ifp->if_flags & IFF_UP)) { 1195 if (sc->sc_enabled) { 1196 if (sc->sc_disable) 1197 (*sc->sc_disable)(sc); 1198 sc->sc_enabled = 0; 1199 ifp->if_flags &= ~IFF_RUNNING; 1200 } 1201 } 1202 error = 0; 1203 break; 1204 case SIOCADDMULTI: 1205 case SIOCDELMULTI: 1206 error = (command == SIOCADDMULTI) ? 1207 ether_addmulti(ifr, &sc->sc_ethercom) : 1208 ether_delmulti(ifr, &sc->sc_ethercom); 1209 if (error == ENETRESET) { 1210 if (sc->sc_enabled != 0) { 1211 /* 1212 * Multicast list has changed. Set the 1213 * hardware filter accordingly. 1214 */ 1215 wi_setmulti(sc); 1216 } 1217 error = 0; 1218 } 1219 break; 1220 case SIOCSIFMEDIA: 1221 case SIOCGIFMEDIA: 1222 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 1223 break; 1224 case SIOCGWAVELAN: 1225 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1226 if (error) 1227 break; 1228 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1229 /* XXX native byte order */ 1230 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1231 sizeof(sc->wi_stats)); 1232 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1233 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) { 1234 /* For non-root user, return all-zeroes keys */ 1235 if (suser(p->p_ucred, &p->p_acflag)) 1236 bzero((char *)&wreq, 1237 sizeof(struct wi_ltv_keys)); 1238 else 1239 bcopy((char *)&sc->wi_keys, (char *)&wreq, 1240 sizeof(struct wi_ltv_keys)); 1241 } else { 1242 if (sc->sc_enabled == 0) 1243 error = wi_getdef(sc, &wreq); 1244 else if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) 1245 error = EINVAL; 1246 } 1247 if (error == 0) 1248 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1249 break; 1250 case SIOCSWAVELAN: 1251 error = suser(p->p_ucred, &p->p_acflag); 1252 if (error) 1253 break; 1254 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1255 if (error) 1256 break; 1257 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1258 error = EINVAL; 1259 break; 1260 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) { 1261 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1262 wreq.wi_len); 1263 } else { 1264 if (sc->sc_enabled != 0) 1265 error = wi_write_record(sc, 1266 (struct wi_ltv_gen *)&wreq); 1267 if (error == 0) 1268 error = wi_setdef(sc, &wreq); 1269 if (error == 0 && sc->sc_enabled != 0) 1270 /* Reinitialize WaveLAN. */ 1271 wi_init(ifp); 1272 } 1273 break; 1274 case SIOCG80211NWID: 1275 if (sc->sc_enabled == 0) { 1276 /* Return the desired ID */ 1277 error = copyout(&sc->wi_netid, ifr->ifr_data, 1278 sizeof(sc->wi_netid)); 1279 } else { 1280 wreq.wi_type = WI_RID_CURRENT_SSID; 1281 wreq.wi_len = WI_MAX_DATALEN; 1282 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) || 1283 le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) 1284 error = EINVAL; 1285 else { 1286 wi_set_ssid(&nwid, (u_int8_t *)&wreq.wi_val[1], 1287 le16toh(wreq.wi_val[0])); 1288 error = copyout(&nwid, ifr->ifr_data, 1289 sizeof(nwid)); 1290 } 1291 } 1292 break; 1293 case SIOCS80211NWID: 1294 error = copyin(ifr->ifr_data, &nwid, sizeof(nwid)); 1295 if (error != 0) 1296 break; 1297 if (nwid.i_len > IEEE80211_NWID_LEN) { 1298 error = EINVAL; 1299 break; 1300 } 1301 if (sc->wi_netid.i_len == nwid.i_len && 1302 memcmp(sc->wi_netid.i_nwid, nwid.i_nwid, nwid.i_len) == 0) 1303 break; 1304 wi_set_ssid(&sc->wi_netid, nwid.i_nwid, nwid.i_len); 1305 if (sc->sc_enabled != 0) 1306 /* Reinitialize WaveLAN. */ 1307 wi_init(ifp); 1308 break; 1309 case SIOCS80211NWKEY: 1310 error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data); 1311 break; 1312 case SIOCG80211NWKEY: 1313 error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data); 1314 break; 1315 case SIOCS80211POWER: 1316 error = wi_set_pm(sc, (struct ieee80211_power *)data); 1317 break; 1318 case SIOCG80211POWER: 1319 error = wi_get_pm(sc, (struct ieee80211_power *)data); 1320 break; 1321 1322 default: 1323 error = EINVAL; 1324 break; 1325 } 1326 1327 splx(s); 1328 return (error); 1329 } 1330 1331 static int 1332 wi_init(ifp) 1333 struct ifnet *ifp; 1334 { 1335 struct wi_softc *sc = ifp->if_softc; 1336 struct wi_req wreq; 1337 struct wi_ltv_macaddr mac; 1338 int error, id = 0; 1339 1340 if (!sc->sc_enabled) { 1341 if ((error = (*sc->sc_enable)(sc)) != 0) 1342 goto out; 1343 sc->sc_enabled = 1; 1344 } 1345 1346 wi_stop(ifp, 0); 1347 wi_reset(sc); 1348 1349 /* Program max data length. */ 1350 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 1351 1352 /* Enable/disable IBSS creation. */ 1353 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 1354 1355 /* Set the port type. */ 1356 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 1357 1358 /* Program the RTS/CTS threshold. */ 1359 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 1360 1361 /* Program the TX rate */ 1362 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 1363 1364 /* Access point density */ 1365 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 1366 1367 /* Power Management Enabled */ 1368 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 1369 1370 /* Power Managment Max Sleep */ 1371 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 1372 1373 /* Roaming type */ 1374 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming); 1375 1376 /* Specify the IBSS name */ 1377 wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid); 1378 1379 /* Specify the network name */ 1380 wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid); 1381 1382 /* Specify the frequency to use */ 1383 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 1384 1385 /* Program the nodename. */ 1386 wi_write_ssid(sc, WI_RID_NODENAME, &wreq, &sc->wi_nodeid); 1387 1388 /* Set our MAC address. */ 1389 mac.wi_len = 4; 1390 mac.wi_type = WI_RID_MAC_NODE; 1391 memcpy(&mac.wi_mac_addr, sc->sc_macaddr, ETHER_ADDR_LEN); 1392 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 1393 1394 /* Initialize promisc mode. */ 1395 if (ifp->if_flags & IFF_PROMISC) { 1396 WI_SETVAL(WI_RID_PROMISC, 1); 1397 } else { 1398 WI_SETVAL(WI_RID_PROMISC, 0); 1399 } 1400 1401 /* Configure WEP. */ 1402 if (sc->wi_has_wep) { 1403 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 1404 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 1405 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 1406 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 1407 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 1408 if (sc->sc_prism2 && sc->wi_use_wep) { 1409 /* 1410 * ONLY HWB3163 EVAL-CARD Firmware version 1411 * less than 0.8 variant3 1412 * 1413 * If promiscuous mode disable, Prism2 chip 1414 * does not work with WEP . 1415 * It is under investigation for details. 1416 * (ichiro@netbsd.org) 1417 */ 1418 if (sc->sc_prism2_ver < 83 ) { 1419 /* firm ver < 0.8 variant 3 */ 1420 WI_SETVAL(WI_RID_PROMISC, 1); 1421 } 1422 WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype); 1423 } 1424 } 1425 1426 /* Set multicast filter. */ 1427 wi_setmulti(sc); 1428 1429 /* Enable desired port */ 1430 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0); 1431 1432 if ((error = wi_alloc_nicmem(sc, 1433 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) { 1434 printf("%s: tx buffer allocation failed\n", 1435 sc->sc_dev.dv_xname); 1436 goto out; 1437 } 1438 sc->wi_tx_data_id = id; 1439 1440 if ((error = wi_alloc_nicmem(sc, 1441 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) { 1442 printf("%s: mgmt. buffer allocation failed\n", 1443 sc->sc_dev.dv_xname); 1444 goto out; 1445 } 1446 sc->wi_tx_mgmt_id = id; 1447 1448 /* Enable interrupts */ 1449 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1450 1451 ifp->if_flags |= IFF_RUNNING; 1452 ifp->if_flags &= ~IFF_OACTIVE; 1453 1454 callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc); 1455 1456 out: 1457 if (error) { 1458 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1459 ifp->if_timer = 0; 1460 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 1461 } 1462 return (error); 1463 } 1464 1465 static void 1466 wi_start(ifp) 1467 struct ifnet *ifp; 1468 { 1469 struct wi_softc *sc; 1470 struct mbuf *m0; 1471 struct wi_frame tx_frame; 1472 struct ether_header *eh; 1473 int id; 1474 1475 sc = ifp->if_softc; 1476 1477 if (ifp->if_flags & IFF_OACTIVE) 1478 return; 1479 1480 IFQ_DEQUEUE(&ifp->if_snd, m0); 1481 if (m0 == NULL) 1482 return; 1483 1484 bzero((char *)&tx_frame, sizeof(tx_frame)); 1485 id = sc->wi_tx_data_id; 1486 eh = mtod(m0, struct ether_header *); 1487 1488 /* 1489 * Use RFC1042 encoding for IP and ARP datagrams, 1490 * 802.3 for anything else. 1491 */ 1492 if (ntohs(eh->ether_type) == ETHERTYPE_IP || 1493 ntohs(eh->ether_type) == ETHERTYPE_ARP || 1494 ntohs(eh->ether_type) == ETHERTYPE_REVARP || 1495 ntohs(eh->ether_type) == ETHERTYPE_IPV6) { 1496 bcopy((char *)&eh->ether_dhost, 1497 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN); 1498 bcopy((char *)&eh->ether_shost, 1499 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 1500 bcopy((char *)&eh->ether_dhost, 1501 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN); 1502 bcopy((char *)&eh->ether_shost, 1503 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN); 1504 1505 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1506 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA); 1507 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 1508 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 1509 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1510 tx_frame.wi_type = eh->ether_type; 1511 1512 m_copydata(m0, sizeof(struct ether_header), 1513 m0->m_pkthdr.len - sizeof(struct ether_header), 1514 (caddr_t)&sc->wi_txbuf); 1515 1516 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1517 sizeof(struct wi_frame)); 1518 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf, 1519 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2); 1520 } else { 1521 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len); 1522 1523 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf); 1524 1525 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1526 sizeof(struct wi_frame)); 1527 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf, 1528 m0->m_pkthdr.len + 2); 1529 } 1530 1531 #if NBPFILTER > 0 1532 /* 1533 * If there's a BPF listener, bounce a copy of 1534 * this frame to him. 1535 */ 1536 if (ifp->if_bpf) 1537 bpf_mtap(ifp->if_bpf, m0); 1538 #endif 1539 1540 m_freem(m0); 1541 1542 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) 1543 printf("%s: xmit failed\n", sc->sc_dev.dv_xname); 1544 1545 ifp->if_flags |= IFF_OACTIVE; 1546 1547 /* 1548 * Set a timeout in case the chip goes out to lunch. 1549 */ 1550 ifp->if_timer = 5; 1551 1552 return; 1553 } 1554 1555 static int 1556 wi_mgmt_xmit(sc, data, len) 1557 struct wi_softc *sc; 1558 caddr_t data; 1559 int len; 1560 { 1561 struct wi_frame tx_frame; 1562 int id; 1563 struct wi_80211_hdr *hdr; 1564 caddr_t dptr; 1565 1566 hdr = (struct wi_80211_hdr *)data; 1567 dptr = data + sizeof(struct wi_80211_hdr); 1568 1569 bzero((char *)&tx_frame, sizeof(tx_frame)); 1570 id = sc->wi_tx_mgmt_id; 1571 1572 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl, 1573 sizeof(struct wi_80211_hdr)); 1574 1575 tx_frame.wi_dat_len = htole16(len - WI_SNAPHDR_LEN); 1576 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 1577 1578 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 1579 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 1580 (len - sizeof(struct wi_80211_hdr)) + 2); 1581 1582 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { 1583 printf("%s: xmit failed\n", sc->sc_dev.dv_xname); 1584 return(EIO); 1585 } 1586 1587 return(0); 1588 } 1589 1590 static void 1591 wi_stop(ifp, disable) 1592 struct ifnet *ifp; 1593 { 1594 struct wi_softc *sc = ifp->if_softc; 1595 1596 CSR_WRITE_2(sc, WI_INT_EN, 0); 1597 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0); 1598 1599 callout_stop(&sc->wi_inquire_ch); 1600 1601 if (disable) { 1602 if (sc->sc_enabled) { 1603 if (sc->sc_disable) 1604 (*sc->sc_disable)(sc); 1605 sc->sc_enabled = 0; 1606 } 1607 } 1608 1609 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING); 1610 ifp->if_timer = 0; 1611 } 1612 1613 static void 1614 wi_watchdog(ifp) 1615 struct ifnet *ifp; 1616 { 1617 struct wi_softc *sc; 1618 1619 sc = ifp->if_softc; 1620 1621 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 1622 1623 wi_init(ifp); 1624 1625 ifp->if_oerrors++; 1626 1627 return; 1628 } 1629 1630 void 1631 wi_shutdown(sc) 1632 struct wi_softc *sc; 1633 { 1634 int s; 1635 1636 s = splnet(); 1637 if (sc->sc_enabled) { 1638 if (sc->sc_disable) 1639 (*sc->sc_disable)(sc); 1640 sc->sc_enabled = 0; 1641 } 1642 splx(s); 1643 } 1644 1645 int 1646 wi_activate(self, act) 1647 struct device *self; 1648 enum devact act; 1649 { 1650 struct wi_softc *sc = (struct wi_softc *)self; 1651 int rv = 0, s; 1652 1653 s = splnet(); 1654 switch (act) { 1655 case DVACT_ACTIVATE: 1656 rv = EOPNOTSUPP; 1657 break; 1658 1659 case DVACT_DEACTIVATE: 1660 if_deactivate(&sc->sc_ethercom.ec_if); 1661 break; 1662 } 1663 splx(s); 1664 return (rv); 1665 } 1666 1667 static void 1668 wi_get_id(sc) 1669 struct wi_softc *sc; 1670 { 1671 struct wi_ltv_ver ver; 1672 1673 /* getting chip identity */ 1674 memset(&ver, 0, sizeof(ver)); 1675 ver.wi_type = WI_RID_CARDID; 1676 ver.wi_len = 5; 1677 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 1678 printf("%s: using ", sc->sc_dev.dv_xname); 1679 switch (le16toh(ver.wi_ver[0])) { 1680 case WI_NIC_EVB2: 1681 printf("RF:PRISM2 MAC:HFA3841"); 1682 sc->sc_prism2 = 1; 1683 break; 1684 case WI_NIC_HWB3763: 1685 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B"); 1686 sc->sc_prism2 = 1; 1687 break; 1688 case WI_NIC_HWB3163: 1689 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A"); 1690 sc->sc_prism2 = 1; 1691 break; 1692 case WI_NIC_HWB3163B: 1693 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B"); 1694 sc->sc_prism2 = 1; 1695 break; 1696 case WI_NIC_EVB3: 1697 printf("RF:PRISM2 MAC:HFA3842"); 1698 sc->sc_prism2 = 1; 1699 break; 1700 case WI_NIC_HWB1153: 1701 printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153"); 1702 sc->sc_prism2 = 1; 1703 break; 1704 case WI_NIC_P2_SST: 1705 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash"); 1706 sc->sc_prism2 = 1; 1707 break; 1708 case WI_NIC_PRISM2_5: 1709 printf("RF:PRISM2.5 MAC:ISL3873"); 1710 sc->sc_prism2 = 1; 1711 break; 1712 default: 1713 printf("Lucent chip or unknown chip\n"); 1714 sc->sc_prism2 = 0; 1715 break; 1716 } 1717 1718 if (sc->sc_prism2) { 1719 /* try to get prism2 firm version */ 1720 memset(&ver, 0, sizeof(ver)); 1721 ver.wi_type = WI_RID_IDENT; 1722 ver.wi_len = 5; 1723 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 1724 LE16TOH(ver.wi_ver[1]); 1725 LE16TOH(ver.wi_ver[2]); 1726 LE16TOH(ver.wi_ver[3]); 1727 printf(" ,Firmware: %i.%i variant %i\n", ver.wi_ver[2], 1728 ver.wi_ver[3], ver.wi_ver[1]); 1729 sc->sc_prism2_ver = ver.wi_ver[2] * 100 + 1730 ver.wi_ver[3] * 10 + ver.wi_ver[1]; 1731 } 1732 1733 return; 1734 } 1735 1736 int 1737 wi_detach(sc) 1738 struct wi_softc *sc; 1739 { 1740 struct ifnet *ifp = sc->sc_ifp; 1741 int s; 1742 1743 if (!sc->sc_attached) 1744 return (0); 1745 1746 s = splnet(); 1747 callout_stop(&sc->wi_inquire_ch); 1748 1749 /* Delete all remaining media. */ 1750 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 1751 1752 ether_ifdetach(ifp); 1753 if_detach(ifp); 1754 if (sc->sc_enabled) { 1755 if (sc->sc_disable) 1756 (*sc->sc_disable)(sc); 1757 sc->sc_enabled = 0; 1758 } 1759 splx(s); 1760 return (0); 1761 } 1762 1763 void 1764 wi_power(sc, why) 1765 struct wi_softc *sc; 1766 int why; 1767 { 1768 int s; 1769 1770 if (!sc->sc_enabled) 1771 return; 1772 1773 s = splnet(); 1774 switch (why) { 1775 case PWR_SUSPEND: 1776 case PWR_STANDBY: 1777 wi_stop(sc->sc_ifp, 0); 1778 if (sc->sc_enabled) { 1779 if (sc->sc_disable) 1780 (*sc->sc_disable)(sc); 1781 } 1782 break; 1783 case PWR_RESUME: 1784 sc->sc_enabled = 0; 1785 wi_init(sc->sc_ifp); 1786 (void)wi_intr(sc); 1787 break; 1788 case PWR_SOFTSUSPEND: 1789 case PWR_SOFTSTANDBY: 1790 case PWR_SOFTRESUME: 1791 break; 1792 } 1793 splx(s); 1794 } 1795 1796 static int 1797 wi_set_ssid(ws, id, len) 1798 struct ieee80211_nwid *ws; 1799 u_int8_t *id; 1800 int len; 1801 { 1802 1803 if (len > IEEE80211_NWID_LEN) 1804 return (EINVAL); 1805 ws->i_len = len; 1806 memcpy(ws->i_nwid, id, len); 1807 return (0); 1808 } 1809 1810 static void 1811 wi_request_fill_ssid(wreq, ws) 1812 struct wi_req *wreq; 1813 struct ieee80211_nwid *ws; 1814 { 1815 int len = ws->i_len; 1816 1817 memset(&wreq->wi_val[0], 0, sizeof(wreq->wi_val)); 1818 wreq->wi_val[0] = htole16(len); 1819 wreq->wi_len = roundup(len, 2) / 2 + 2; 1820 memcpy(&wreq->wi_val[1], ws->i_nwid, len); 1821 } 1822 1823 static int 1824 wi_write_ssid(sc, type, wreq, ws) 1825 struct wi_softc *sc; 1826 int type; 1827 struct wi_req *wreq; 1828 struct ieee80211_nwid *ws; 1829 { 1830 1831 wreq->wi_type = type; 1832 wi_request_fill_ssid(wreq, ws); 1833 return (wi_write_record(sc, (struct wi_ltv_gen *)wreq)); 1834 } 1835 1836 static int 1837 wi_sync_media(sc, ptype, txrate) 1838 struct wi_softc *sc; 1839 int ptype; 1840 int txrate; 1841 { 1842 int media = sc->sc_media.ifm_cur->ifm_media; 1843 int options = IFM_OPTIONS(media); 1844 int subtype; 1845 1846 switch (txrate) { 1847 case 1: 1848 subtype = IFM_IEEE80211_DS1; 1849 break; 1850 case 2: 1851 subtype = IFM_IEEE80211_DS2; 1852 break; 1853 case 3: 1854 subtype = IFM_AUTO; 1855 break; 1856 case 11: 1857 subtype = IFM_IEEE80211_DS11; 1858 break; 1859 default: 1860 subtype = IFM_MANUAL; /* Unable to represent */ 1861 break; 1862 } 1863 switch (ptype) { 1864 case WI_PORTTYPE_ADHOC: 1865 options |= IFM_IEEE80211_ADHOC; 1866 break; 1867 case WI_PORTTYPE_BSS: 1868 options &= ~IFM_IEEE80211_ADHOC; 1869 break; 1870 default: 1871 subtype = IFM_MANUAL; /* Unable to represent */ 1872 break; 1873 } 1874 media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options, 1875 IFM_INST(media)); 1876 if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL) 1877 return (EINVAL); 1878 ifmedia_set(&sc->sc_media, media); 1879 sc->wi_ptype = ptype; 1880 sc->wi_tx_rate = txrate; 1881 return (0); 1882 } 1883 1884 static int 1885 wi_media_change(ifp) 1886 struct ifnet *ifp; 1887 { 1888 struct wi_softc *sc = ifp->if_softc; 1889 int otype = sc->wi_ptype; 1890 int orate = sc->wi_tx_rate; 1891 1892 if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 1893 sc->wi_ptype = WI_PORTTYPE_ADHOC; 1894 else 1895 sc->wi_ptype = WI_PORTTYPE_BSS; 1896 1897 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) { 1898 case IFM_IEEE80211_DS1: 1899 sc->wi_tx_rate = 1; 1900 break; 1901 case IFM_IEEE80211_DS2: 1902 sc->wi_tx_rate = 2; 1903 break; 1904 case IFM_AUTO: 1905 sc->wi_tx_rate = 3; 1906 break; 1907 case IFM_IEEE80211_DS11: 1908 sc->wi_tx_rate = 11; 1909 break; 1910 } 1911 1912 if (sc->sc_enabled != 0) { 1913 if (otype != sc->wi_ptype || 1914 orate != sc->wi_tx_rate) 1915 wi_init(ifp); 1916 } 1917 1918 ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media); 1919 1920 return (0); 1921 } 1922 1923 static void 1924 wi_media_status(ifp, imr) 1925 struct ifnet *ifp; 1926 struct ifmediareq *imr; 1927 { 1928 struct wi_softc *sc = ifp->if_softc; 1929 1930 if (sc->sc_enabled == 0) { 1931 imr->ifm_active = IFM_IEEE80211|IFM_NONE; 1932 imr->ifm_status = 0; 1933 return; 1934 } 1935 1936 imr->ifm_active = sc->sc_media.ifm_cur->ifm_media; 1937 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 1938 } 1939 1940 static int 1941 wi_set_nwkey(sc, nwkey) 1942 struct wi_softc *sc; 1943 struct ieee80211_nwkey *nwkey; 1944 { 1945 int i, len, error; 1946 struct wi_req wreq; 1947 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq; 1948 1949 if (!sc->wi_has_wep) 1950 return ENODEV; 1951 if (nwkey->i_defkid <= 0 || 1952 nwkey->i_defkid > IEEE80211_WEP_NKID) 1953 return EINVAL; 1954 memcpy(wk, &sc->wi_keys, sizeof(*wk)); 1955 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1956 if (nwkey->i_key[i].i_keydat == NULL) 1957 continue; 1958 len = nwkey->i_key[i].i_keylen; 1959 if (len > sizeof(wk->wi_keys[i].wi_keydat)) 1960 return EINVAL; 1961 error = copyin(nwkey->i_key[i].i_keydat, 1962 wk->wi_keys[i].wi_keydat, len); 1963 if (error) 1964 return error; 1965 wk->wi_keys[i].wi_keylen = htole16(len); 1966 } 1967 1968 wk->wi_len = (sizeof(*wk) / 2) + 1; 1969 wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS; 1970 if (sc->sc_enabled != 0) { 1971 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1972 if (error) 1973 return error; 1974 } 1975 error = wi_setdef(sc, &wreq); 1976 if (error) 1977 return error; 1978 1979 wreq.wi_len = 2; 1980 wreq.wi_type = WI_RID_TX_CRYPT_KEY; 1981 wreq.wi_val[0] = htole16(nwkey->i_defkid - 1); 1982 if (sc->sc_enabled != 0) { 1983 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1984 if (error) 1985 return error; 1986 } 1987 error = wi_setdef(sc, &wreq); 1988 if (error) 1989 return error; 1990 1991 wreq.wi_type = WI_RID_ENCRYPTION; 1992 wreq.wi_val[0] = htole16(nwkey->i_wepon); 1993 if (sc->sc_enabled != 0) { 1994 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1995 if (error) 1996 return error; 1997 } 1998 error = wi_setdef(sc, &wreq); 1999 if (error) 2000 return error; 2001 2002 if (sc->sc_enabled != 0) 2003 wi_init(&sc->sc_ethercom.ec_if); 2004 return 0; 2005 } 2006 2007 static int 2008 wi_get_nwkey(sc, nwkey) 2009 struct wi_softc *sc; 2010 struct ieee80211_nwkey *nwkey; 2011 { 2012 int i, len, error; 2013 struct wi_ltv_keys *wk = &sc->wi_keys; 2014 2015 if (!sc->wi_has_wep) 2016 return ENODEV; 2017 nwkey->i_wepon = sc->wi_use_wep; 2018 nwkey->i_defkid = sc->wi_tx_key + 1; 2019 2020 /* do not show any keys to non-root user */ 2021 error = suser(curproc->p_ucred, &curproc->p_acflag); 2022 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2023 if (nwkey->i_key[i].i_keydat == NULL) 2024 continue; 2025 /* error holds results of suser() for the first time */ 2026 if (error) 2027 return error; 2028 len = le16toh(wk->wi_keys[i].wi_keylen); 2029 if (nwkey->i_key[i].i_keylen < len) 2030 return ENOSPC; 2031 nwkey->i_key[i].i_keylen = len; 2032 error = copyout(wk->wi_keys[i].wi_keydat, 2033 nwkey->i_key[i].i_keydat, len); 2034 if (error) 2035 return error; 2036 } 2037 return 0; 2038 } 2039 2040 static int 2041 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power) 2042 { 2043 2044 sc->wi_pm_enabled = power->i_enabled; 2045 sc->wi_max_sleep = power->i_maxsleep; 2046 2047 if (sc->sc_enabled) 2048 return (wi_init(&sc->sc_ethercom.ec_if)); 2049 2050 return (0); 2051 } 2052 2053 static int 2054 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power) 2055 { 2056 2057 power->i_enabled = sc->wi_pm_enabled; 2058 power->i_maxsleep = sc->wi_max_sleep; 2059 2060 return (0); 2061 } 2062