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