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