1 /* $NetBSD: wi.c,v 1.27 2001/10/14 12:33:18 ichiro 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 void 711 wi_pci_reset(sc) 712 struct wi_softc *sc; 713 { 714 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 715 WI_PCI_COR, WI_PCI_SOFT_RESET); 716 DELAY(100*1000); /* 100 m sec */ 717 718 bus_space_write_2(sc->sc_iot, sc->sc_ioh, WI_PCI_COR, 0x0); 719 DELAY(100*1000); /* 100 m sec */ 720 721 return; 722 } 723 724 /* 725 * Read an LTV record from the NIC. 726 */ 727 static int wi_read_record(sc, ltv) 728 struct wi_softc *sc; 729 struct wi_ltv_gen *ltv; 730 { 731 u_int16_t *ptr; 732 int len, code; 733 struct wi_ltv_gen *oltv, p2ltv; 734 735 if (sc->sc_prism2) { 736 oltv = ltv; 737 switch (ltv->wi_type) { 738 case WI_RID_ENCRYPTION: 739 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 740 p2ltv.wi_len = 2; 741 ltv = &p2ltv; 742 break; 743 case WI_RID_TX_CRYPT_KEY: 744 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 745 p2ltv.wi_len = 2; 746 ltv = &p2ltv; 747 break; 748 } 749 } 750 751 /* Tell the NIC to enter record read mode. */ 752 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) 753 return(EIO); 754 755 /* Seek to the record. */ 756 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 757 return(EIO); 758 759 /* 760 * Read the length and record type and make sure they 761 * match what we expect (this verifies that we have enough 762 * room to hold all of the returned data). 763 */ 764 len = CSR_READ_2(sc, WI_DATA1); 765 if (len > ltv->wi_len) 766 return(ENOSPC); 767 code = CSR_READ_2(sc, WI_DATA1); 768 if (code != ltv->wi_type) 769 return(EIO); 770 771 ltv->wi_len = len; 772 ltv->wi_type = code; 773 774 /* Now read the data. */ 775 ptr = <v->wi_val; 776 if (ltv->wi_len > 1) 777 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1); 778 779 if (sc->sc_prism2) { 780 int v; 781 782 switch (oltv->wi_type) { 783 case WI_RID_TX_RATE: 784 case WI_RID_CUR_TX_RATE: 785 switch (le16toh(ltv->wi_val)) { 786 case 1: v = 1; break; 787 case 2: v = 2; break; 788 case 3: v = 6; break; 789 case 4: v = 5; break; 790 case 7: v = 7; break; 791 case 8: v = 11; break; 792 case 15: v = 3; break; 793 default: v = 0x100 + le16toh(ltv->wi_val); break; 794 } 795 oltv->wi_val = htole16(v); 796 break; 797 case WI_RID_ENCRYPTION: 798 oltv->wi_len = 2; 799 if (le16toh(ltv->wi_val) & 0x01) 800 oltv->wi_val = htole16(1); 801 else 802 oltv->wi_val = htole16(0); 803 break; 804 case WI_RID_TX_CRYPT_KEY: 805 oltv->wi_len = 2; 806 oltv->wi_val = ltv->wi_val; 807 break; 808 case WI_RID_AUTH_CNTL: 809 oltv->wi_len = 2; 810 if (le16toh(ltv->wi_val) & 0x01) 811 oltv->wi_val = htole16(1); 812 else if (le16toh(ltv->wi_val) & 0x02) 813 oltv->wi_val = htole16(2); 814 break; 815 } 816 } 817 818 return(0); 819 } 820 821 /* 822 * Same as read, except we inject data instead of reading it. 823 */ 824 static int wi_write_record(sc, ltv) 825 struct wi_softc *sc; 826 struct wi_ltv_gen *ltv; 827 { 828 u_int16_t *ptr; 829 int i; 830 struct wi_ltv_gen p2ltv; 831 832 if (sc->sc_prism2) { 833 int v; 834 835 switch (ltv->wi_type) { 836 case WI_RID_TX_RATE: 837 p2ltv.wi_type = WI_RID_TX_RATE; 838 p2ltv.wi_len = 2; 839 switch (le16toh(ltv->wi_val)) { 840 case 1: v = 1; break; 841 case 2: v = 2; break; 842 case 3: v = 15; break; 843 case 5: v = 4; break; 844 case 6: v = 3; break; 845 case 7: v = 7; break; 846 case 11: v = 8; break; 847 default: return EINVAL; 848 } 849 p2ltv.wi_val = htole16(v); 850 ltv = &p2ltv; 851 break; 852 case WI_RID_ENCRYPTION: 853 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 854 p2ltv.wi_len = 2; 855 if (le16toh(ltv->wi_val)) 856 p2ltv.wi_val = htole16(0x03); 857 else 858 p2ltv.wi_val = htole16(0x90); 859 ltv = &p2ltv; 860 break; 861 case WI_RID_TX_CRYPT_KEY: 862 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 863 p2ltv.wi_len = 2; 864 p2ltv.wi_val = ltv->wi_val; 865 ltv = &p2ltv; 866 break; 867 case WI_RID_DEFLT_CRYPT_KEYS: 868 { 869 int error; 870 struct wi_ltv_str ws; 871 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv; 872 for (i = 0; i < 4; i++) { 873 ws.wi_len = 4; 874 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 875 memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5); 876 ws.wi_str[5] = '\0'; 877 error = wi_write_record(sc, 878 (struct wi_ltv_gen *)&ws); 879 if (error) 880 return error; 881 } 882 return 0; 883 } 884 case WI_RID_AUTH_CNTL: 885 p2ltv.wi_type = WI_RID_AUTH_CNTL; 886 p2ltv.wi_len = 2; 887 if (le16toh(ltv->wi_val) == 1) 888 p2ltv.wi_val = htole16(0x01); 889 else if (le16toh(ltv->wi_val) == 2) 890 p2ltv.wi_val = htole16(0x02); 891 ltv = &p2ltv; 892 break; 893 } 894 } 895 896 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 897 return(EIO); 898 899 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 900 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 901 902 /* Write data */ 903 ptr = <v->wi_val; 904 if (ltv->wi_len > 1) 905 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1); 906 907 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type)) 908 return(EIO); 909 910 return(0); 911 } 912 913 static int wi_seek(sc, id, off, chan) 914 struct wi_softc *sc; 915 int id, off, chan; 916 { 917 int i; 918 int selreg, offreg; 919 int status; 920 921 switch (chan) { 922 case WI_BAP0: 923 selreg = WI_SEL0; 924 offreg = WI_OFF0; 925 break; 926 case WI_BAP1: 927 selreg = WI_SEL1; 928 offreg = WI_OFF1; 929 break; 930 default: 931 printf("%s: invalid data path: %x\n", 932 sc->sc_dev.dv_xname, chan); 933 return(EIO); 934 } 935 936 CSR_WRITE_2(sc, selreg, id); 937 CSR_WRITE_2(sc, offreg, off); 938 939 for (i = 0; i < WI_TIMEOUT; i++) { 940 status = CSR_READ_2(sc, offreg); 941 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR))) 942 break; 943 } 944 945 if (i == WI_TIMEOUT) { 946 printf("%s: timeout in wi_seek to %x/%x; last status %x\n", 947 sc->sc_dev.dv_xname, id, off, status); 948 return(ETIMEDOUT); 949 } 950 return(0); 951 } 952 953 static int wi_read_data(sc, id, off, buf, len) 954 struct wi_softc *sc; 955 int id, off; 956 caddr_t buf; 957 int len; 958 { 959 u_int16_t *ptr; 960 961 if (wi_seek(sc, id, off, WI_BAP1)) 962 return(EIO); 963 964 ptr = (u_int16_t *)buf; 965 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, len / 2); 966 967 return(0); 968 } 969 970 /* 971 * According to the comments in the HCF Light code, there is a bug in 972 * the Hermes (or possibly in certain Hermes firmware revisions) where 973 * the chip's internal autoincrement counter gets thrown off during 974 * data writes: the autoincrement is missed, causing one data word to 975 * be overwritten and subsequent words to be written to the wrong memory 976 * locations. The end result is that we could end up transmitting bogus 977 * frames without realizing it. The workaround for this is to write a 978 * couple of extra guard words after the end of the transfer, then 979 * attempt to read then back. If we fail to locate the guard words where 980 * we expect them, we preform the transfer over again. 981 */ 982 static int wi_write_data(sc, id, off, buf, len) 983 struct wi_softc *sc; 984 int id, off; 985 caddr_t buf; 986 int len; 987 { 988 u_int16_t *ptr; 989 990 #ifdef WI_HERMES_AUTOINC_WAR 991 again: 992 #endif 993 994 if (wi_seek(sc, id, off, WI_BAP0)) 995 return(EIO); 996 997 ptr = (u_int16_t *)buf; 998 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, ptr, len / 2); 999 1000 #ifdef WI_HERMES_AUTOINC_WAR 1001 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 1002 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 1003 1004 if (wi_seek(sc, id, off + len, WI_BAP0)) 1005 return(EIO); 1006 1007 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 1008 CSR_READ_2(sc, WI_DATA0) != 0x5678) 1009 goto again; 1010 #endif 1011 1012 return(0); 1013 } 1014 1015 /* 1016 * Allocate a region of memory inside the NIC and zero 1017 * it out. 1018 */ 1019 static int wi_alloc_nicmem(sc, len, id) 1020 struct wi_softc *sc; 1021 int len; 1022 int *id; 1023 { 1024 int i; 1025 1026 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { 1027 printf("%s: failed to allocate %d bytes on NIC\n", 1028 sc->sc_dev.dv_xname, len); 1029 return(ENOMEM); 1030 } 1031 1032 for (i = 0; i < WI_TIMEOUT; i++) { 1033 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 1034 break; 1035 } 1036 1037 if (i == WI_TIMEOUT) { 1038 printf("%s: TIMED OUT in alloc\n", sc->sc_dev.dv_xname); 1039 return(ETIMEDOUT); 1040 } 1041 1042 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 1043 *id = CSR_READ_2(sc, WI_ALLOC_FID); 1044 1045 if (wi_seek(sc, *id, 0, WI_BAP0)) { 1046 printf("%s: seek failed in alloc\n", sc->sc_dev.dv_xname); 1047 return(EIO); 1048 } 1049 1050 for (i = 0; i < len / 2; i++) 1051 CSR_WRITE_2(sc, WI_DATA0, 0); 1052 1053 return(0); 1054 } 1055 1056 static void wi_setmulti(sc) 1057 struct wi_softc *sc; 1058 { 1059 struct ifnet *ifp; 1060 int i = 0; 1061 struct wi_ltv_mcast mcast; 1062 struct ether_multi *enm; 1063 struct ether_multistep estep; 1064 struct ethercom *ec = &sc->sc_ethercom; 1065 1066 ifp = &sc->sc_ethercom.ec_if; 1067 1068 if ((ifp->if_flags & IFF_PROMISC) != 0) { 1069 allmulti: 1070 ifp->if_flags |= IFF_ALLMULTI; 1071 memset((char *)&mcast, 0, sizeof(mcast)); 1072 mcast.wi_type = WI_RID_MCAST; 1073 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1; 1074 1075 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1076 return; 1077 } 1078 1079 i = 0; 1080 ETHER_FIRST_MULTI(estep, ec, enm); 1081 while (enm != NULL) { 1082 /* Punt on ranges or too many multicast addresses. */ 1083 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1084 ETHER_ADDR_LEN) != 0 || 1085 i >= 16) 1086 goto allmulti; 1087 1088 memcpy((char *)&mcast.wi_mcast[i], enm->enm_addrlo, 1089 ETHER_ADDR_LEN); 1090 i++; 1091 ETHER_NEXT_MULTI(estep, enm); 1092 } 1093 1094 ifp->if_flags &= ~IFF_ALLMULTI; 1095 mcast.wi_type = WI_RID_MCAST; 1096 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * i) + 1; 1097 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1098 } 1099 1100 static int 1101 wi_setdef(sc, wreq) 1102 struct wi_softc *sc; 1103 struct wi_req *wreq; 1104 { 1105 struct sockaddr_dl *sdl; 1106 struct ifnet *ifp; 1107 int error = 0; 1108 1109 ifp = &sc->sc_ethercom.ec_if; 1110 1111 switch(wreq->wi_type) { 1112 case WI_RID_MAC_NODE: 1113 sdl = (struct sockaddr_dl *)ifp->if_sadl; 1114 memcpy((char *)&sc->sc_macaddr, (char *)&wreq->wi_val, 1115 ETHER_ADDR_LEN); 1116 memcpy(LLADDR(sdl), (char *)&wreq->wi_val, ETHER_ADDR_LEN); 1117 break; 1118 case WI_RID_PORTTYPE: 1119 error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate); 1120 break; 1121 case WI_RID_TX_RATE: 1122 error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0])); 1123 break; 1124 case WI_RID_MAX_DATALEN: 1125 sc->wi_max_data_len = le16toh(wreq->wi_val[0]); 1126 break; 1127 case WI_RID_RTS_THRESH: 1128 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]); 1129 break; 1130 case WI_RID_SYSTEM_SCALE: 1131 sc->wi_ap_density = le16toh(wreq->wi_val[0]); 1132 break; 1133 case WI_RID_CREATE_IBSS: 1134 sc->wi_create_ibss = le16toh(wreq->wi_val[0]); 1135 break; 1136 case WI_RID_OWN_CHNL: 1137 sc->wi_channel = le16toh(wreq->wi_val[0]); 1138 break; 1139 case WI_RID_NODENAME: 1140 error = wi_set_ssid(&sc->wi_nodeid, 1141 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1142 break; 1143 case WI_RID_DESIRED_SSID: 1144 error = wi_set_ssid(&sc->wi_netid, 1145 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1146 break; 1147 case WI_RID_OWN_SSID: 1148 error = wi_set_ssid(&sc->wi_ibssid, 1149 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0])); 1150 break; 1151 case WI_RID_PM_ENABLED: 1152 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]); 1153 break; 1154 case WI_RID_MICROWAVE_OVEN: 1155 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]); 1156 break; 1157 case WI_RID_MAX_SLEEP: 1158 sc->wi_max_sleep = le16toh(wreq->wi_val[0]); 1159 break; 1160 case WI_RID_AUTH_CNTL: 1161 sc->wi_authtype = le16toh(wreq->wi_val[0]); 1162 break; 1163 case WI_RID_ROAMING_MODE: 1164 sc->wi_roaming = le16toh(wreq->wi_val[0]); 1165 break; 1166 case WI_RID_ENCRYPTION: 1167 sc->wi_use_wep = le16toh(wreq->wi_val[0]); 1168 break; 1169 case WI_RID_TX_CRYPT_KEY: 1170 sc->wi_tx_key = le16toh(wreq->wi_val[0]); 1171 break; 1172 case WI_RID_DEFLT_CRYPT_KEYS: 1173 memcpy((char *)&sc->wi_keys, (char *)wreq, 1174 sizeof(struct wi_ltv_keys)); 1175 break; 1176 default: 1177 error = EINVAL; 1178 break; 1179 } 1180 1181 return (error); 1182 } 1183 1184 static int 1185 wi_getdef(sc, wreq) 1186 struct wi_softc *sc; 1187 struct wi_req *wreq; 1188 { 1189 struct sockaddr_dl *sdl; 1190 struct ifnet *ifp; 1191 int error = 0; 1192 1193 ifp = &sc->sc_ethercom.ec_if; 1194 1195 wreq->wi_len = 2; /* XXX */ 1196 switch (wreq->wi_type) { 1197 case WI_RID_MAC_NODE: 1198 wreq->wi_len += ETHER_ADDR_LEN / 2 - 1; 1199 sdl = (struct sockaddr_dl *)ifp->if_sadl; 1200 memcpy(&wreq->wi_val, &sc->sc_macaddr, ETHER_ADDR_LEN); 1201 memcpy(&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 1202 break; 1203 case WI_RID_PORTTYPE: 1204 wreq->wi_val[0] = htole16(sc->wi_ptype); 1205 break; 1206 case WI_RID_TX_RATE: 1207 wreq->wi_val[0] = htole16(sc->wi_tx_rate); 1208 break; 1209 case WI_RID_MAX_DATALEN: 1210 wreq->wi_val[0] = htole16(sc->wi_max_data_len); 1211 break; 1212 case WI_RID_RTS_THRESH: 1213 wreq->wi_val[0] = htole16(sc->wi_rts_thresh); 1214 break; 1215 case WI_RID_SYSTEM_SCALE: 1216 wreq->wi_val[0] = htole16(sc->wi_ap_density); 1217 break; 1218 case WI_RID_CREATE_IBSS: 1219 wreq->wi_val[0] = htole16(sc->wi_create_ibss); 1220 break; 1221 case WI_RID_OWN_CHNL: 1222 wreq->wi_val[0] = htole16(sc->wi_channel); 1223 break; 1224 case WI_RID_NODENAME: 1225 wi_request_fill_ssid(wreq, &sc->wi_nodeid); 1226 break; 1227 case WI_RID_DESIRED_SSID: 1228 wi_request_fill_ssid(wreq, &sc->wi_netid); 1229 break; 1230 case WI_RID_OWN_SSID: 1231 wi_request_fill_ssid(wreq, &sc->wi_ibssid); 1232 break; 1233 case WI_RID_PM_ENABLED: 1234 wreq->wi_val[0] = htole16(sc->wi_pm_enabled); 1235 break; 1236 case WI_RID_MICROWAVE_OVEN: 1237 wreq->wi_val[0] = htole16(sc->wi_mor_enabled); 1238 break; 1239 case WI_RID_MAX_SLEEP: 1240 wreq->wi_val[0] = htole16(sc->wi_max_sleep); 1241 break; 1242 case WI_RID_AUTH_CNTL: 1243 wreq->wi_val[0] = htole16(sc->wi_authtype); 1244 break; 1245 case WI_RID_ROAMING_MODE: 1246 wreq->wi_val[0] = htole16(sc->wi_roaming); 1247 break; 1248 case WI_RID_WEP_AVAIL: 1249 wreq->wi_val[0] = htole16(sc->wi_has_wep); 1250 break; 1251 case WI_RID_ENCRYPTION: 1252 wreq->wi_val[0] = htole16(sc->wi_use_wep); 1253 break; 1254 case WI_RID_TX_CRYPT_KEY: 1255 wreq->wi_val[0] = htole16(sc->wi_tx_key); 1256 break; 1257 case WI_RID_DEFLT_CRYPT_KEYS: 1258 wreq->wi_len += sizeof(struct wi_ltv_keys) / 2 - 1; 1259 memcpy(wreq, &sc->wi_keys, sizeof(struct wi_ltv_keys)); 1260 break; 1261 default: 1262 #if 0 1263 error = EIO; 1264 #else 1265 #ifdef WI_DEBUG 1266 printf("%s: wi_getdef: unknown request %d\n", 1267 sc->sc_dev.dv_xname, wreq->wi_type); 1268 #endif 1269 #endif 1270 break; 1271 } 1272 1273 return (error); 1274 } 1275 1276 static int 1277 wi_ioctl(ifp, command, data) 1278 struct ifnet *ifp; 1279 u_long command; 1280 caddr_t data; 1281 { 1282 int i, s, error = 0; 1283 struct wi_softc *sc = ifp->if_softc; 1284 struct wi_req wreq; 1285 struct ifreq *ifr; 1286 struct ifdrv *ifd; 1287 struct proc *p = curproc; 1288 struct ieee80211_nwid nwid; 1289 1290 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 1291 return (ENXIO); 1292 1293 s = splnet(); 1294 1295 ifr = (struct ifreq *)data; 1296 switch (command) { 1297 case SIOCSIFADDR: 1298 case SIOCGIFADDR: 1299 case SIOCSIFMTU: 1300 error = ether_ioctl(ifp, command, data); 1301 break; 1302 case SIOCSIFFLAGS: 1303 if (ifp->if_flags & IFF_UP) { 1304 if (ifp->if_flags & IFF_RUNNING && 1305 ifp->if_flags & IFF_PROMISC && 1306 !(sc->wi_if_flags & IFF_PROMISC)) { 1307 WI_SETVAL(WI_RID_PROMISC, 1); 1308 } else if (ifp->if_flags & IFF_RUNNING && 1309 !(ifp->if_flags & IFF_PROMISC) && 1310 sc->wi_if_flags & IFF_PROMISC) { 1311 WI_SETVAL(WI_RID_PROMISC, 0); 1312 } 1313 wi_init(ifp); 1314 } else { 1315 if (ifp->if_flags & IFF_RUNNING) { 1316 wi_stop(ifp, 0); 1317 } 1318 } 1319 sc->wi_if_flags = ifp->if_flags; 1320 1321 if (!(ifp->if_flags & IFF_UP)) { 1322 if (sc->sc_enabled) { 1323 if (sc->sc_disable) 1324 (*sc->sc_disable)(sc); 1325 sc->sc_enabled = 0; 1326 ifp->if_flags &= ~IFF_RUNNING; 1327 } 1328 } 1329 error = 0; 1330 break; 1331 case SIOCADDMULTI: 1332 case SIOCDELMULTI: 1333 error = (command == SIOCADDMULTI) ? 1334 ether_addmulti(ifr, &sc->sc_ethercom) : 1335 ether_delmulti(ifr, &sc->sc_ethercom); 1336 if (error == ENETRESET) { 1337 if (sc->sc_enabled != 0) { 1338 /* 1339 * Multicast list has changed. Set the 1340 * hardware filter accordingly. 1341 */ 1342 wi_setmulti(sc); 1343 } 1344 error = 0; 1345 } 1346 break; 1347 case SIOCSIFMEDIA: 1348 case SIOCGIFMEDIA: 1349 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 1350 break; 1351 case SIOCGWAVELAN: 1352 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1353 if (error) 1354 break; 1355 switch (wreq.wi_type) { 1356 case WI_RID_IFACE_STATS: 1357 /* XXX native byte order */ 1358 memcpy((char *)&wreq.wi_val, (char *)&sc->wi_stats, 1359 sizeof(sc->wi_stats)); 1360 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1361 break; 1362 case WI_RID_DEFLT_CRYPT_KEYS: 1363 /* For non-root user, return all-zeroes keys */ 1364 if (suser(p->p_ucred, &p->p_acflag)) 1365 memset((char *)&wreq, 0, 1366 sizeof(struct wi_ltv_keys)); 1367 else 1368 memcpy((char *)&wreq, (char *)&sc->wi_keys, 1369 sizeof(struct wi_ltv_keys)); 1370 break; 1371 default: 1372 if (sc->sc_enabled == 0) 1373 error = wi_getdef(sc, &wreq); 1374 else if (wi_read_record(sc, 1375 (struct wi_ltv_gen *)&wreq)) 1376 error = EINVAL; 1377 break; 1378 } 1379 if (error == 0) 1380 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1381 break; 1382 1383 case SIOCSWAVELAN: 1384 error = suser(p->p_ucred, &p->p_acflag); 1385 if (error) 1386 break; 1387 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1388 if (error) 1389 break; 1390 switch (wreq.wi_type) { 1391 case WI_RID_IFACE_STATS: 1392 error = EINVAL; 1393 break; 1394 case WI_RID_MGMT_XMIT: 1395 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1396 wreq.wi_len); 1397 break; 1398 1399 default: 1400 if (sc->sc_enabled != 0) 1401 error = wi_write_record(sc, 1402 (struct wi_ltv_gen *)&wreq); 1403 if (error == 0) 1404 error = wi_setdef(sc, &wreq); 1405 if (error == 0 && sc->sc_enabled != 0) 1406 /* Reinitialize WaveLAN. */ 1407 wi_init(ifp); 1408 break; 1409 } 1410 break; 1411 1412 case SIOCSDRVSPEC: 1413 error = suser(p->p_ucred, &p->p_acflag); 1414 if (error) 1415 break; 1416 ifd = (struct ifdrv *)data; 1417 switch (ifd->ifd_cmd) { 1418 case WI_IOCTL_SET_SCAN: 1419 error = copyin(ifd->ifd_data, &i, sizeof (i)); 1420 if (error) 1421 break; 1422 1423 sc->wi_results.scanning = i; 1424 if (sc->wi_results.scanning > 0) 1425 callout_reset(&sc->wi_scan_ch, 1426 sc->wi_results.scanning, 1427 wi_inquire_scan, sc); 1428 else 1429 callout_stop(&sc->wi_scan_ch); 1430 break; 1431 1432 /* 1433 * Experimental XXXMLG 1434 */ 1435 case WI_IOCTL_SET_TESTMODE: 1436 error = copyin(ifd->ifd_data, &i, sizeof (i)); 1437 if (error) 1438 break; 1439 if (i) { 1440 wi_cmd(sc, WI_CMD_TEST | WI_TEST_MONITOR << 8, 1441 0); 1442 printf("wi test mode enabled\n"); 1443 } else { 1444 wi_cmd(sc, WI_CMD_TEST | WI_TEST_STOP << 8, 0); 1445 printf("wi test mode disabled\n"); 1446 } 1447 break; 1448 1449 default: 1450 error = EINVAL; 1451 break; 1452 } 1453 break; 1454 1455 case SIOCGDRVSPEC: 1456 ifd = (struct ifdrv *)data; 1457 switch (ifd->ifd_cmd) { 1458 case WI_IOCTL_GET_SCAN_RESULTS: 1459 error = copyout(&sc->wi_results, ifd->ifd_data, 1460 sizeof(struct wi_scan_results)); 1461 break; 1462 1463 default: 1464 error = EINVAL; 1465 break; 1466 } 1467 break; 1468 1469 case SIOCG80211NWID: 1470 if (sc->sc_enabled == 0) { 1471 /* Return the desired ID */ 1472 error = copyout(&sc->wi_netid, ifr->ifr_data, 1473 sizeof(sc->wi_netid)); 1474 } else { 1475 wreq.wi_type = WI_RID_CURRENT_SSID; 1476 wreq.wi_len = WI_MAX_DATALEN; 1477 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) || 1478 le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) 1479 error = EINVAL; 1480 else { 1481 wi_set_ssid(&nwid, (u_int8_t *)&wreq.wi_val[1], 1482 le16toh(wreq.wi_val[0])); 1483 error = copyout(&nwid, ifr->ifr_data, 1484 sizeof(nwid)); 1485 } 1486 } 1487 break; 1488 case SIOCS80211NWID: 1489 error = copyin(ifr->ifr_data, &nwid, sizeof(nwid)); 1490 if (error != 0) 1491 break; 1492 if (nwid.i_len > IEEE80211_NWID_LEN) { 1493 error = EINVAL; 1494 break; 1495 } 1496 if (sc->wi_netid.i_len == nwid.i_len && 1497 memcmp(sc->wi_netid.i_nwid, nwid.i_nwid, nwid.i_len) == 0) 1498 break; 1499 wi_set_ssid(&sc->wi_netid, nwid.i_nwid, nwid.i_len); 1500 if (sc->sc_enabled != 0) 1501 /* Reinitialize WaveLAN. */ 1502 wi_init(ifp); 1503 break; 1504 case SIOCS80211NWKEY: 1505 error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data); 1506 break; 1507 case SIOCG80211NWKEY: 1508 error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data); 1509 break; 1510 case SIOCS80211POWER: 1511 error = wi_set_pm(sc, (struct ieee80211_power *)data); 1512 break; 1513 case SIOCG80211POWER: 1514 error = wi_get_pm(sc, (struct ieee80211_power *)data); 1515 break; 1516 1517 default: 1518 error = EINVAL; 1519 break; 1520 } 1521 1522 splx(s); 1523 return (error); 1524 } 1525 1526 static int 1527 wi_init(ifp) 1528 struct ifnet *ifp; 1529 { 1530 struct wi_softc *sc = ifp->if_softc; 1531 struct wi_req wreq; 1532 struct wi_ltv_macaddr mac; 1533 int error, id = 0; 1534 1535 if (!sc->sc_enabled) { 1536 if ((error = (*sc->sc_enable)(sc)) != 0) 1537 goto out; 1538 sc->sc_enabled = 1; 1539 } 1540 1541 wi_stop(ifp, 0); 1542 wi_reset(sc); 1543 1544 /* Program max data length. */ 1545 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 1546 1547 /* Enable/disable IBSS creation. */ 1548 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 1549 1550 /* Set the port type. */ 1551 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 1552 1553 /* Program the RTS/CTS threshold. */ 1554 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 1555 1556 /* Program the TX rate */ 1557 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 1558 1559 /* Access point density */ 1560 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 1561 1562 /* Power Management Enabled */ 1563 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 1564 1565 /* Power Managment Max Sleep */ 1566 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 1567 1568 /* Roaming type */ 1569 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming); 1570 1571 /* Specify the IBSS name */ 1572 wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid); 1573 1574 /* Specify the network name */ 1575 wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid); 1576 1577 /* Specify the frequency to use */ 1578 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 1579 1580 /* Program the nodename. */ 1581 wi_write_ssid(sc, WI_RID_NODENAME, &wreq, &sc->wi_nodeid); 1582 1583 /* Set our MAC address. */ 1584 mac.wi_len = 4; 1585 mac.wi_type = WI_RID_MAC_NODE; 1586 memcpy(&mac.wi_mac_addr, sc->sc_macaddr, ETHER_ADDR_LEN); 1587 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 1588 1589 /* Initialize promisc mode. */ 1590 if (ifp->if_flags & IFF_PROMISC) { 1591 WI_SETVAL(WI_RID_PROMISC, 1); 1592 } else { 1593 WI_SETVAL(WI_RID_PROMISC, 0); 1594 } 1595 1596 /* Configure WEP. */ 1597 if (sc->wi_has_wep) { 1598 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 1599 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 1600 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 1601 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 1602 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 1603 if (sc->sc_prism2 && sc->wi_use_wep) { 1604 /* 1605 * ONLY HWB3163 EVAL-CARD Firmware version 1606 * less than 0.8 variant3 1607 * 1608 * If promiscuous mode disable, Prism2 chip 1609 * does not work with WEP . 1610 * It is under investigation for details. 1611 * (ichiro@netbsd.org) 1612 */ 1613 if (sc->sc_prism2_ver < 83 ) { 1614 /* firm ver < 0.8 variant 3 */ 1615 WI_SETVAL(WI_RID_PROMISC, 1); 1616 } 1617 WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype); 1618 } 1619 } 1620 1621 /* Set multicast filter. */ 1622 wi_setmulti(sc); 1623 1624 /* Enable desired port */ 1625 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0); 1626 1627 if ((error = wi_alloc_nicmem(sc, 1628 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) { 1629 printf("%s: tx buffer allocation failed\n", 1630 sc->sc_dev.dv_xname); 1631 goto out; 1632 } 1633 sc->wi_tx_data_id = id; 1634 1635 if ((error = wi_alloc_nicmem(sc, 1636 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) { 1637 printf("%s: mgmt. buffer allocation failed\n", 1638 sc->sc_dev.dv_xname); 1639 goto out; 1640 } 1641 sc->wi_tx_mgmt_id = id; 1642 1643 /* Enable interrupts */ 1644 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1645 1646 ifp->if_flags |= IFF_RUNNING; 1647 ifp->if_flags &= ~IFF_OACTIVE; 1648 1649 callout_reset(&sc->wi_stats_ch, STATS_FREQUENCY, wi_inquire_stats, sc); 1650 1651 out: 1652 if (error) { 1653 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1654 ifp->if_timer = 0; 1655 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 1656 } 1657 return (error); 1658 } 1659 1660 static void 1661 wi_start(ifp) 1662 struct ifnet *ifp; 1663 { 1664 struct wi_softc *sc; 1665 struct mbuf *m0; 1666 struct wi_frame tx_frame; 1667 struct ether_header *eh; 1668 int id; 1669 1670 sc = ifp->if_softc; 1671 1672 if (ifp->if_flags & IFF_OACTIVE) 1673 return; 1674 1675 IFQ_DEQUEUE(&ifp->if_snd, m0); 1676 if (m0 == NULL) 1677 return; 1678 1679 memset((char *)&tx_frame, 0, sizeof(tx_frame)); 1680 id = sc->wi_tx_data_id; 1681 eh = mtod(m0, struct ether_header *); 1682 1683 /* 1684 * Use RFC1042 encoding for IP and ARP datagrams, 1685 * 802.3 for anything else. 1686 */ 1687 if (ntohs(eh->ether_type) == ETHERTYPE_IP || 1688 ntohs(eh->ether_type) == ETHERTYPE_ARP || 1689 ntohs(eh->ether_type) == ETHERTYPE_REVARP || 1690 ntohs(eh->ether_type) == ETHERTYPE_IPV6) { 1691 memcpy((char *)&tx_frame.wi_addr1, (char *)&eh->ether_dhost, 1692 ETHER_ADDR_LEN); 1693 memcpy((char *)&tx_frame.wi_addr2, (char *)&eh->ether_shost, 1694 ETHER_ADDR_LEN); 1695 memcpy((char *)&tx_frame.wi_dst_addr, (char *)&eh->ether_dhost, 1696 ETHER_ADDR_LEN); 1697 memcpy((char *)&tx_frame.wi_src_addr, (char *)&eh->ether_shost, 1698 ETHER_ADDR_LEN); 1699 1700 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1701 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA); 1702 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 1703 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 1704 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1705 tx_frame.wi_type = eh->ether_type; 1706 1707 m_copydata(m0, sizeof(struct ether_header), 1708 m0->m_pkthdr.len - sizeof(struct ether_header), 1709 (caddr_t)&sc->wi_txbuf); 1710 1711 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1712 sizeof(struct wi_frame)); 1713 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf, 1714 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2); 1715 } else { 1716 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len); 1717 1718 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf); 1719 1720 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1721 sizeof(struct wi_frame)); 1722 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf, 1723 m0->m_pkthdr.len + 2); 1724 } 1725 1726 #if NBPFILTER > 0 1727 /* 1728 * If there's a BPF listener, bounce a copy of 1729 * this frame to him. 1730 */ 1731 if (ifp->if_bpf) 1732 bpf_mtap(ifp->if_bpf, m0); 1733 #endif 1734 1735 m_freem(m0); 1736 1737 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) 1738 printf("%s: xmit failed\n", sc->sc_dev.dv_xname); 1739 1740 ifp->if_flags |= IFF_OACTIVE; 1741 1742 /* 1743 * Set a timeout in case the chip goes out to lunch. 1744 */ 1745 ifp->if_timer = 5; 1746 1747 return; 1748 } 1749 1750 static int 1751 wi_mgmt_xmit(sc, data, len) 1752 struct wi_softc *sc; 1753 caddr_t data; 1754 int len; 1755 { 1756 struct wi_frame tx_frame; 1757 int id; 1758 struct wi_80211_hdr *hdr; 1759 caddr_t dptr; 1760 1761 hdr = (struct wi_80211_hdr *)data; 1762 dptr = data + sizeof(struct wi_80211_hdr); 1763 1764 memset((char *)&tx_frame, 0, sizeof(tx_frame)); 1765 id = sc->wi_tx_mgmt_id; 1766 1767 memcpy((char *)&tx_frame.wi_frame_ctl, (char *)hdr, 1768 sizeof(struct wi_80211_hdr)); 1769 1770 tx_frame.wi_dat_len = htole16(len - WI_SNAPHDR_LEN); 1771 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 1772 1773 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 1774 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 1775 (len - sizeof(struct wi_80211_hdr)) + 2); 1776 1777 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { 1778 printf("%s: xmit failed\n", sc->sc_dev.dv_xname); 1779 return(EIO); 1780 } 1781 1782 return(0); 1783 } 1784 1785 static void 1786 wi_stop(ifp, disable) 1787 struct ifnet *ifp; 1788 { 1789 struct wi_softc *sc = ifp->if_softc; 1790 1791 CSR_WRITE_2(sc, WI_INT_EN, 0); 1792 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0); 1793 1794 callout_stop(&sc->wi_stats_ch); 1795 callout_stop(&sc->wi_scan_ch); 1796 1797 if (disable) { 1798 if (sc->sc_enabled) { 1799 if (sc->sc_disable) 1800 (*sc->sc_disable)(sc); 1801 sc->sc_enabled = 0; 1802 } 1803 } 1804 1805 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING); 1806 ifp->if_timer = 0; 1807 } 1808 1809 static void 1810 wi_watchdog(ifp) 1811 struct ifnet *ifp; 1812 { 1813 struct wi_softc *sc; 1814 1815 sc = ifp->if_softc; 1816 1817 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 1818 1819 wi_init(ifp); 1820 1821 ifp->if_oerrors++; 1822 1823 return; 1824 } 1825 1826 void 1827 wi_shutdown(sc) 1828 struct wi_softc *sc; 1829 { 1830 int s; 1831 1832 s = splnet(); 1833 if (sc->sc_enabled) { 1834 if (sc->sc_disable) 1835 (*sc->sc_disable)(sc); 1836 sc->sc_enabled = 0; 1837 } 1838 splx(s); 1839 } 1840 1841 int 1842 wi_activate(self, act) 1843 struct device *self; 1844 enum devact act; 1845 { 1846 struct wi_softc *sc = (struct wi_softc *)self; 1847 int rv = 0, s; 1848 1849 s = splnet(); 1850 switch (act) { 1851 case DVACT_ACTIVATE: 1852 rv = EOPNOTSUPP; 1853 break; 1854 1855 case DVACT_DEACTIVATE: 1856 if_deactivate(&sc->sc_ethercom.ec_if); 1857 break; 1858 } 1859 splx(s); 1860 return (rv); 1861 } 1862 1863 static void 1864 wi_get_id(sc) 1865 struct wi_softc *sc; 1866 { 1867 struct wi_ltv_ver ver; 1868 1869 /* getting chip identity */ 1870 memset(&ver, 0, sizeof(ver)); 1871 ver.wi_type = WI_RID_CARDID; 1872 ver.wi_len = 5; 1873 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 1874 printf("%s: using ", sc->sc_dev.dv_xname); 1875 switch (le16toh(ver.wi_ver[0])) { 1876 case WI_NIC_EVB2: 1877 printf("RF:PRISM2 MAC:HFA3841"); 1878 sc->sc_prism2 = 1; 1879 break; 1880 case WI_NIC_HWB3763: 1881 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B"); 1882 sc->sc_prism2 = 1; 1883 break; 1884 case WI_NIC_HWB3163: 1885 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A"); 1886 sc->sc_prism2 = 1; 1887 break; 1888 case WI_NIC_HWB3163B: 1889 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B"); 1890 sc->sc_prism2 = 1; 1891 break; 1892 case WI_NIC_EVB3: 1893 printf("RF:PRISM2 MAC:HFA3842"); 1894 sc->sc_prism2 = 1; 1895 break; 1896 case WI_NIC_HWB1153: 1897 printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153"); 1898 sc->sc_prism2 = 1; 1899 break; 1900 case WI_NIC_P2_SST: 1901 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash"); 1902 sc->sc_prism2 = 1; 1903 break; 1904 case WI_NIC_PRISM2_5: 1905 printf("RF:PRISM2.5 MAC:ISL3873"); 1906 sc->sc_prism2 = 1; 1907 break; 1908 case WI_NIC_3874A: 1909 printf("RF:PRISM2.5 MAC:ISL3874A(PCI)"); 1910 sc->sc_prism2 = 1; 1911 break; 1912 default: 1913 printf("Lucent chip or unknown chip\n"); 1914 sc->sc_prism2 = 0; 1915 break; 1916 } 1917 1918 if (sc->sc_prism2) { 1919 /* try to get prism2 firm version */ 1920 memset(&ver, 0, sizeof(ver)); 1921 ver.wi_type = WI_RID_IDENT; 1922 ver.wi_len = 5; 1923 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 1924 LE16TOH(ver.wi_ver[1]); 1925 LE16TOH(ver.wi_ver[2]); 1926 LE16TOH(ver.wi_ver[3]); 1927 printf(", Firmware: %i.%i variant %i\n", ver.wi_ver[2], 1928 ver.wi_ver[3], ver.wi_ver[1]); 1929 sc->sc_prism2_ver = ver.wi_ver[2] * 100 + 1930 ver.wi_ver[3] * 10 + ver.wi_ver[1]; 1931 } 1932 1933 return; 1934 } 1935 1936 int 1937 wi_detach(sc) 1938 struct wi_softc *sc; 1939 { 1940 struct ifnet *ifp = sc->sc_ifp; 1941 int s; 1942 1943 if (!sc->sc_attached) 1944 return (0); 1945 1946 s = splnet(); 1947 callout_stop(&sc->wi_stats_ch); 1948 callout_stop(&sc->wi_scan_ch); 1949 1950 /* Delete all remaining media. */ 1951 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 1952 1953 ether_ifdetach(ifp); 1954 if_detach(ifp); 1955 if (sc->sc_enabled) { 1956 if (sc->sc_disable) 1957 (*sc->sc_disable)(sc); 1958 sc->sc_enabled = 0; 1959 } 1960 splx(s); 1961 return (0); 1962 } 1963 1964 void 1965 wi_power(sc, why) 1966 struct wi_softc *sc; 1967 int why; 1968 { 1969 int s; 1970 1971 if (!sc->sc_enabled) 1972 return; 1973 1974 s = splnet(); 1975 switch (why) { 1976 case PWR_SUSPEND: 1977 case PWR_STANDBY: 1978 wi_stop(sc->sc_ifp, 0); 1979 if (sc->sc_enabled) { 1980 if (sc->sc_disable) 1981 (*sc->sc_disable)(sc); 1982 } 1983 break; 1984 case PWR_RESUME: 1985 sc->sc_enabled = 0; 1986 wi_init(sc->sc_ifp); 1987 (void)wi_intr(sc); 1988 break; 1989 case PWR_SOFTSUSPEND: 1990 case PWR_SOFTSTANDBY: 1991 case PWR_SOFTRESUME: 1992 break; 1993 } 1994 splx(s); 1995 } 1996 1997 static int 1998 wi_set_ssid(ws, id, len) 1999 struct ieee80211_nwid *ws; 2000 u_int8_t *id; 2001 int len; 2002 { 2003 2004 if (len > IEEE80211_NWID_LEN) 2005 return (EINVAL); 2006 ws->i_len = len; 2007 memcpy(ws->i_nwid, id, len); 2008 return (0); 2009 } 2010 2011 static void 2012 wi_request_fill_ssid(wreq, ws) 2013 struct wi_req *wreq; 2014 struct ieee80211_nwid *ws; 2015 { 2016 int len = ws->i_len; 2017 2018 memset(&wreq->wi_val[0], 0, sizeof(wreq->wi_val)); 2019 wreq->wi_val[0] = htole16(len); 2020 wreq->wi_len = roundup(len, 2) / 2 + 2; 2021 memcpy(&wreq->wi_val[1], ws->i_nwid, len); 2022 } 2023 2024 static int 2025 wi_write_ssid(sc, type, wreq, ws) 2026 struct wi_softc *sc; 2027 int type; 2028 struct wi_req *wreq; 2029 struct ieee80211_nwid *ws; 2030 { 2031 2032 wreq->wi_type = type; 2033 wi_request_fill_ssid(wreq, ws); 2034 return (wi_write_record(sc, (struct wi_ltv_gen *)wreq)); 2035 } 2036 2037 static int 2038 wi_sync_media(sc, ptype, txrate) 2039 struct wi_softc *sc; 2040 int ptype; 2041 int txrate; 2042 { 2043 int media = sc->sc_media.ifm_cur->ifm_media; 2044 int options = IFM_OPTIONS(media); 2045 int subtype; 2046 2047 switch (txrate) { 2048 case 1: 2049 subtype = IFM_IEEE80211_DS1; 2050 break; 2051 case 2: 2052 subtype = IFM_IEEE80211_DS2; 2053 break; 2054 case 3: 2055 subtype = IFM_AUTO; 2056 break; 2057 case 11: 2058 subtype = IFM_IEEE80211_DS11; 2059 break; 2060 default: 2061 subtype = IFM_MANUAL; /* Unable to represent */ 2062 break; 2063 } 2064 switch (ptype) { 2065 case WI_PORTTYPE_ADHOC: 2066 options |= IFM_IEEE80211_ADHOC; 2067 break; 2068 case WI_PORTTYPE_BSS: 2069 options &= ~IFM_IEEE80211_ADHOC; 2070 break; 2071 default: 2072 subtype = IFM_MANUAL; /* Unable to represent */ 2073 break; 2074 } 2075 media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options, 2076 IFM_INST(media)); 2077 if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL) 2078 return (EINVAL); 2079 ifmedia_set(&sc->sc_media, media); 2080 sc->wi_ptype = ptype; 2081 sc->wi_tx_rate = txrate; 2082 return (0); 2083 } 2084 2085 static int 2086 wi_media_change(ifp) 2087 struct ifnet *ifp; 2088 { 2089 struct wi_softc *sc = ifp->if_softc; 2090 int otype = sc->wi_ptype; 2091 int orate = sc->wi_tx_rate; 2092 2093 if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2094 sc->wi_ptype = WI_PORTTYPE_ADHOC; 2095 else 2096 sc->wi_ptype = WI_PORTTYPE_BSS; 2097 2098 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) { 2099 case IFM_IEEE80211_DS1: 2100 sc->wi_tx_rate = 1; 2101 break; 2102 case IFM_IEEE80211_DS2: 2103 sc->wi_tx_rate = 2; 2104 break; 2105 case IFM_AUTO: 2106 sc->wi_tx_rate = 3; 2107 break; 2108 case IFM_IEEE80211_DS11: 2109 sc->wi_tx_rate = 11; 2110 break; 2111 } 2112 2113 if (sc->sc_enabled != 0) { 2114 if (otype != sc->wi_ptype || 2115 orate != sc->wi_tx_rate) 2116 wi_init(ifp); 2117 } 2118 2119 ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media); 2120 2121 return (0); 2122 } 2123 2124 static void 2125 wi_media_status(ifp, imr) 2126 struct ifnet *ifp; 2127 struct ifmediareq *imr; 2128 { 2129 struct wi_softc *sc = ifp->if_softc; 2130 2131 if (sc->sc_enabled == 0) { 2132 imr->ifm_active = IFM_IEEE80211|IFM_NONE; 2133 imr->ifm_status = 0; 2134 return; 2135 } 2136 2137 imr->ifm_active = sc->sc_media.ifm_cur->ifm_media; 2138 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2139 } 2140 2141 static int 2142 wi_set_nwkey(sc, nwkey) 2143 struct wi_softc *sc; 2144 struct ieee80211_nwkey *nwkey; 2145 { 2146 int i, error; 2147 size_t len; 2148 struct wi_req wreq; 2149 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq; 2150 2151 if (!sc->wi_has_wep) 2152 return ENODEV; 2153 if (nwkey->i_defkid <= 0 || 2154 nwkey->i_defkid > IEEE80211_WEP_NKID) 2155 return EINVAL; 2156 memcpy(wk, &sc->wi_keys, sizeof(*wk)); 2157 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2158 if (nwkey->i_key[i].i_keydat == NULL) 2159 continue; 2160 len = nwkey->i_key[i].i_keylen; 2161 if (len > sizeof(wk->wi_keys[i].wi_keydat)) 2162 return EINVAL; 2163 error = copyin(nwkey->i_key[i].i_keydat, 2164 wk->wi_keys[i].wi_keydat, len); 2165 if (error) 2166 return error; 2167 wk->wi_keys[i].wi_keylen = htole16(len); 2168 } 2169 2170 wk->wi_len = (sizeof(*wk) / 2) + 1; 2171 wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS; 2172 if (sc->sc_enabled != 0) { 2173 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2174 if (error) 2175 return error; 2176 } 2177 error = wi_setdef(sc, &wreq); 2178 if (error) 2179 return error; 2180 2181 wreq.wi_len = 2; 2182 wreq.wi_type = WI_RID_TX_CRYPT_KEY; 2183 wreq.wi_val[0] = htole16(nwkey->i_defkid - 1); 2184 if (sc->sc_enabled != 0) { 2185 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2186 if (error) 2187 return error; 2188 } 2189 error = wi_setdef(sc, &wreq); 2190 if (error) 2191 return error; 2192 2193 wreq.wi_type = WI_RID_ENCRYPTION; 2194 wreq.wi_val[0] = htole16(nwkey->i_wepon); 2195 if (sc->sc_enabled != 0) { 2196 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 2197 if (error) 2198 return error; 2199 } 2200 error = wi_setdef(sc, &wreq); 2201 if (error) 2202 return error; 2203 2204 if (sc->sc_enabled != 0) 2205 wi_init(&sc->sc_ethercom.ec_if); 2206 return 0; 2207 } 2208 2209 static int 2210 wi_get_nwkey(sc, nwkey) 2211 struct wi_softc *sc; 2212 struct ieee80211_nwkey *nwkey; 2213 { 2214 int i, len, error; 2215 struct wi_ltv_keys *wk = &sc->wi_keys; 2216 2217 if (!sc->wi_has_wep) 2218 return ENODEV; 2219 nwkey->i_wepon = sc->wi_use_wep; 2220 nwkey->i_defkid = sc->wi_tx_key + 1; 2221 2222 /* do not show any keys to non-root user */ 2223 error = suser(curproc->p_ucred, &curproc->p_acflag); 2224 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 2225 if (nwkey->i_key[i].i_keydat == NULL) 2226 continue; 2227 /* error holds results of suser() for the first time */ 2228 if (error) 2229 return error; 2230 len = le16toh(wk->wi_keys[i].wi_keylen); 2231 if (nwkey->i_key[i].i_keylen < len) 2232 return ENOSPC; 2233 nwkey->i_key[i].i_keylen = len; 2234 error = copyout(wk->wi_keys[i].wi_keydat, 2235 nwkey->i_key[i].i_keydat, len); 2236 if (error) 2237 return error; 2238 } 2239 return 0; 2240 } 2241 2242 static int 2243 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power) 2244 { 2245 2246 sc->wi_pm_enabled = power->i_enabled; 2247 sc->wi_max_sleep = power->i_maxsleep; 2248 2249 if (sc->sc_enabled) 2250 return (wi_init(&sc->sc_ethercom.ec_if)); 2251 2252 return (0); 2253 } 2254 2255 static int 2256 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power) 2257 { 2258 2259 power->i_enabled = sc->wi_pm_enabled; 2260 power->i_maxsleep = sc->wi_max_sleep; 2261 2262 return (0); 2263 } 2264