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