1 /* $OpenBSD: an.c,v 1.57 2009/08/10 20:29:54 deraadt Exp $ */ 2 /* $NetBSD: an.c,v 1.34 2005/06/20 02:49:18 atatat Exp $ */ 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 * $FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $ 35 */ 36 /* 37 * Copyright (c) 2004, 2005 David Young. All rights reserved. 38 * Copyright (c) 2004, 2005 OJC Technologies. All rights reserved. 39 * Copyright (c) 2004, 2005 Dayton Data Center Services, LLC. All 40 * rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. Neither the name of the author nor the names of any co-contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY David Young AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL David Young AND CONTRIBUTORS 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 64 * THE POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67 /* 68 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 69 * 70 * Written by Bill Paul <wpaul@ctr.columbia.edu> 71 * Electrical Engineering Department 72 * Columbia University, New York City 73 */ 74 75 /* 76 * Ported to NetBSD from FreeBSD by Atsushi Onoe at the San Diego 77 * IETF meeting. 78 */ 79 80 #include <sys/cdefs.h> 81 82 #include "bpfilter.h" 83 84 #include <sys/param.h> 85 #include <sys/systm.h> 86 #include <sys/sockio.h> 87 #include <sys/mbuf.h> 88 #include <sys/kernel.h> 89 #include <sys/ucred.h> 90 #include <sys/socket.h> 91 #include <sys/timeout.h> 92 #include <sys/device.h> 93 #include <sys/proc.h> 94 #include <sys/endian.h> 95 #include <sys/tree.h> 96 97 #include <machine/bus.h> 98 99 #include <net/if.h> 100 #include <net/if_dl.h> 101 #include <net/if_llc.h> 102 #include <net/if_media.h> 103 #include <net/if_types.h> 104 105 #ifdef INET 106 #include <netinet/in.h> 107 #include <netinet/in_systm.h> 108 #include <netinet/in_var.h> 109 #include <netinet/ip.h> 110 #include <netinet/if_ether.h> 111 #endif 112 113 #include <net80211/ieee80211_radiotap.h> 114 #include <net80211/ieee80211_var.h> 115 116 #if NBPFILTER > 0 117 #include <net/bpf.h> 118 #endif 119 120 #include <dev/ic/anreg.h> 121 #include <dev/ic/anvar.h> 122 123 struct cfdriver an_cd = { 124 NULL, "an", DV_IFNET 125 }; 126 127 int an_reset(struct an_softc *); 128 void an_wait(struct an_softc *); 129 int an_init(struct ifnet *); 130 void an_stop(struct ifnet *, int); 131 void an_start(struct ifnet *); 132 void an_watchdog(struct ifnet *); 133 int an_ioctl(struct ifnet *, u_long, caddr_t); 134 int an_media_change(struct ifnet *); 135 void an_media_status(struct ifnet *, struct ifmediareq *); 136 137 int an_set_nwkey(struct an_softc *, struct ieee80211_nwkey *); 138 int an_set_nwkey_wep(struct an_softc *, struct ieee80211_nwkey *); 139 int an_get_nwkey(struct an_softc *, struct ieee80211_nwkey *); 140 int an_write_wepkey(struct an_softc *, int, struct an_wepkey *, 141 int); 142 143 void an_rxeof(struct an_softc *); 144 void an_txeof(struct an_softc *, u_int16_t); 145 void an_linkstat_intr(struct an_softc *); 146 147 int an_cmd(struct an_softc *, int, int); 148 int an_seek_bap(struct an_softc *, int, int); 149 int an_read_bap(struct an_softc *, int, int, void *, int, int); 150 int an_write_bap(struct an_softc *, int, int, void *, int); 151 int an_mwrite_bap(struct an_softc *, int, int, struct mbuf *, int); 152 int an_read_rid(struct an_softc *, int, void *, int *); 153 int an_write_rid(struct an_softc *, int, void *, int); 154 155 int an_alloc_nicmem(struct an_softc *, int, int *); 156 157 int an_newstate(struct ieee80211com *, enum ieee80211_state, int); 158 159 #ifdef AN_DEBUG 160 int an_debug = 0; 161 162 #define DPRINTF(X) if (an_debug) printf X 163 #define DPRINTF2(X) if (an_debug > 1) printf X 164 #else 165 #define DPRINTF(X) 166 #define DPRINTF2(X) 167 #endif 168 169 #if BYTE_ORDER == BIG_ENDIAN 170 static __inline void 171 an_swap16(u_int16_t *p, int cnt) 172 { 173 for (; cnt--; p++) 174 *p = swap16(*p); 175 } 176 #define an_switch32(val) (val >> 16 | (val & 0xFFFF) << 16) 177 #else 178 #define an_swap16(p, cnt) 179 #define an_switch32(val) val 180 #endif 181 182 int 183 an_attach(struct an_softc *sc) 184 { 185 struct ieee80211com *ic = &sc->sc_ic; 186 struct ifnet *ifp = &ic->ic_if; 187 int i; 188 struct an_rid_wepkey *akey; 189 int buflen, kid, rid; 190 int chan, chan_min, chan_max; 191 192 sc->sc_invalid = 0; 193 194 /* disable interrupts */ 195 CSR_WRITE_2(sc, AN_INT_EN, 0); 196 CSR_WRITE_2(sc, AN_EVENT_ACK, 0xffff); 197 198 // an_wait(sc); 199 if (an_reset(sc) != 0) { 200 sc->sc_invalid = 1; 201 return 1; 202 } 203 204 /* Load factory config */ 205 if (an_cmd(sc, AN_CMD_READCFG, 0) != 0) { 206 printf("%s: failed to load config data\n", 207 sc->sc_dev.dv_xname); 208 return (EIO); 209 } 210 211 /* Read the current configuration */ 212 buflen = sizeof(sc->sc_config); 213 if (an_read_rid(sc, AN_RID_GENCONFIG, &sc->sc_config, &buflen) != 0) { 214 printf("%s: read config failed\n", sc->sc_dev.dv_xname); 215 return(EIO); 216 } 217 218 an_swap16((u_int16_t *)&sc->sc_config.an_macaddr, 3); 219 220 /* Read the card capabilities */ 221 buflen = sizeof(sc->sc_caps); 222 if (an_read_rid(sc, AN_RID_CAPABILITIES, &sc->sc_caps, &buflen) != 0) { 223 printf("%s: read caps failed\n", sc->sc_dev.dv_xname); 224 return(EIO); 225 } 226 227 an_swap16((u_int16_t *)&sc->sc_caps.an_oemaddr, 3); 228 an_swap16((u_int16_t *)&sc->sc_caps.an_rates, 4); 229 230 /* Read WEP settings from persistent memory */ 231 akey = &sc->sc_buf.sc_wepkey; 232 buflen = sizeof(struct an_rid_wepkey); 233 rid = AN_RID_WEP_VOLATILE; /* first persistent key */ 234 while (an_read_rid(sc, rid, akey, &buflen) == 0) { 235 an_swap16((u_int16_t *)&akey->an_mac_addr, 3); 236 an_swap16((u_int16_t *)&akey->an_key, 8); 237 kid = akey->an_key_index; 238 DPRINTF(("an_attach: wep rid=0x%x len=%d(%d) index=0x%04x " 239 "mac[0]=%02x keylen=%d\n", 240 rid, buflen, sizeof(*akey), kid, 241 akey->an_mac_addr[0], akey->an_key_len)); 242 if (kid == 0xffff) { 243 sc->sc_tx_perskey = akey->an_mac_addr[0]; 244 sc->sc_tx_key = -1; 245 break; 246 } 247 if (kid >= IEEE80211_WEP_NKID) 248 break; 249 sc->sc_perskeylen[kid] = akey->an_key_len; 250 sc->sc_wepkeys[kid].an_wep_keylen = -1; 251 rid = AN_RID_WEP_PERSISTENT; /* for next key */ 252 buflen = sizeof(struct an_rid_wepkey); 253 } 254 255 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_caps.an_oemaddr); 256 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 257 258 printf("%s: Firmware %x.%02x.%02x, Radio: ", ifp->if_xname, 259 sc->sc_caps.an_fwrev >> 8, 260 sc->sc_caps.an_fwrev & 0xff, 261 sc->sc_caps.an_fwsubrev); 262 263 if (sc->sc_config.an_radiotype & AN_RADIOTYPE_80211_FH) 264 printf("802.11 FH"); 265 else if (sc->sc_config.an_radiotype & AN_RADIOTYPE_80211_DS) 266 printf("802.11 DS"); 267 else if (sc->sc_config.an_radiotype & AN_RADIOTYPE_LM2000_DS) 268 printf("LM2000 DS"); 269 else 270 printf("unknown (%x)", sc->sc_config.an_radiotype); 271 272 printf(", address %s\n", ether_sprintf(ic->ic_myaddr)); 273 274 ifp->if_softc = sc; 275 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 276 ifp->if_ioctl = an_ioctl; 277 ifp->if_start = an_start; 278 ifp->if_init = an_init; 279 ifp->if_watchdog = an_watchdog; 280 IFQ_SET_READY(&ifp->if_snd); 281 282 ic->ic_phytype = IEEE80211_T_DS; 283 ic->ic_opmode = IEEE80211_M_STA; 284 ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_PMGT | IEEE80211_C_MONITOR; 285 #ifndef IEEE80211_STA_ONLY 286 ic->ic_caps |= IEEE80211_C_IBSS; 287 #endif 288 ic->ic_state = IEEE80211_S_INIT; 289 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_caps.an_oemaddr); 290 291 switch (sc->sc_caps.an_regdomain) { 292 default: 293 case AN_REGDOMAIN_USA: 294 case AN_REGDOMAIN_CANADA: 295 chan_min = 1; chan_max = 11; break; 296 case AN_REGDOMAIN_EUROPE: 297 case AN_REGDOMAIN_AUSTRALIA: 298 chan_min = 1; chan_max = 13; break; 299 case AN_REGDOMAIN_JAPAN: 300 chan_min = 14; chan_max = 14; break; 301 case AN_REGDOMAIN_SPAIN: 302 chan_min = 10; chan_max = 11; break; 303 case AN_REGDOMAIN_FRANCE: 304 chan_min = 10; chan_max = 13; break; 305 case AN_REGDOMAIN_JAPANWIDE: 306 chan_min = 1; chan_max = 14; break; 307 } 308 309 for (chan = chan_min; chan <= chan_max; chan++) { 310 ic->ic_channels[chan].ic_freq = 311 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 312 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B; 313 } 314 ic->ic_ibss_chan = &ic->ic_channels[chan_min]; 315 316 /* Find supported rate */ 317 for (i = 0; i < sizeof(sc->sc_caps.an_rates); i++) { 318 if (sc->sc_caps.an_rates[i] == 0) 319 continue; 320 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ 321 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates++] = 322 sc->sc_caps.an_rates[i]; 323 } 324 325 /* 326 * Call MI attach routine. 327 */ 328 if_attach(ifp); 329 ieee80211_ifattach(ifp); 330 331 sc->sc_newstate = ic->ic_newstate; 332 ic->ic_newstate = an_newstate; 333 334 ieee80211_media_init(ifp, an_media_change, an_media_status); 335 336 #if NBPFILTER > 0 337 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu)); 338 sc->sc_rxtap.ar_ihdr.it_len = sizeof(sc->sc_rxtapu); 339 sc->sc_rxtap.ar_ihdr.it_present = AN_RX_RADIOTAP_PRESENT; 340 341 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu)); 342 sc->sc_txtap.at_ihdr.it_len = sizeof(sc->sc_txtapu); 343 sc->sc_txtap.at_ihdr.it_present = AN_TX_RADIOTAP_PRESENT; 344 345 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, 346 sizeof(struct ieee80211_frame) + 64); 347 #endif 348 349 sc->sc_attached = 1; 350 351 return(0); 352 } 353 354 void 355 an_rxeof(struct an_softc *sc) 356 { 357 struct ieee80211com *ic = &sc->sc_ic; 358 struct ifnet *ifp = &ic->ic_if; 359 struct ieee80211_frame *wh; 360 struct ieee80211_rxinfo rxi; 361 struct ieee80211_node *ni; 362 struct an_rxframe frmhdr; 363 struct mbuf *m; 364 u_int16_t status; 365 int fid, gaplen, len, off; 366 uint8_t *gap; 367 368 fid = CSR_READ_2(sc, AN_RX_FID); 369 370 /* First read in the frame header */ 371 if (an_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr), sizeof(frmhdr)) != 0) { 372 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 373 ifp->if_ierrors++; 374 DPRINTF(("an_rxeof: read fid %x failed\n", fid)); 375 return; 376 } 377 an_swap16((u_int16_t *)&frmhdr.an_whdr, sizeof(struct ieee80211_frame)/2); 378 379 status = frmhdr.an_rx_status; 380 if ((status & AN_STAT_ERRSTAT) != 0 && 381 ic->ic_opmode != IEEE80211_M_MONITOR) { 382 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 383 ifp->if_ierrors++; 384 DPRINTF(("an_rxeof: fid %x status %x\n", fid, status)); 385 return; 386 } 387 388 /* the payload length field includes a 16-bit "mystery field" */ 389 len = frmhdr.an_rx_payload_len - sizeof(uint16_t); 390 off = ALIGN(sizeof(struct ieee80211_frame)); 391 392 if (off + len > MCLBYTES) { 393 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 394 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 395 ifp->if_ierrors++; 396 DPRINTF(("an_rxeof: oversized packet %d\n", len)); 397 return; 398 } 399 len = 0; 400 } 401 402 MGETHDR(m, M_DONTWAIT, MT_DATA); 403 if (m == NULL) { 404 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 405 ifp->if_ierrors++; 406 DPRINTF(("an_rxeof: MGET failed\n")); 407 return; 408 } 409 if (off + len + AN_GAPLEN_MAX > MHLEN) { 410 MCLGET(m, M_DONTWAIT); 411 if ((m->m_flags & M_EXT) == 0) { 412 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 413 m_freem(m); 414 ifp->if_ierrors++; 415 DPRINTF(("an_rxeof: MCLGET failed\n")); 416 return; 417 } 418 } 419 m->m_data += off - sizeof(struct ieee80211_frame); 420 421 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 422 gaplen = frmhdr.an_gaplen; 423 if (gaplen > AN_GAPLEN_MAX) { 424 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 425 m_freem(m); 426 ifp->if_ierrors++; 427 DPRINTF(("%s: gap too long\n", __func__)); 428 return; 429 } 430 /* 431 * We don't need the 16-bit mystery field (payload length?), 432 * so read it into the region reserved for the 802.11 header. 433 * 434 * When Cisco Aironet 350 cards w/ firmware version 5 or 435 * greater operate with certain Cisco 350 APs, 436 * the "gap" is filled with the SNAP header. Read 437 * it in after the 802.11 header. 438 */ 439 gap = m->m_data + sizeof(struct ieee80211_frame) - 440 sizeof(uint16_t); 441 an_read_bap(sc, fid, -1, gap, gaplen + sizeof(u_int16_t), 442 gaplen + sizeof(u_int16_t)); 443 } else 444 gaplen = 0; 445 446 an_read_bap(sc, fid, -1, 447 m->m_data + sizeof(struct ieee80211_frame) + gaplen, len, len); 448 an_swap16((u_int16_t *)(m->m_data + sizeof(struct ieee80211_frame) + gaplen), (len+1)/2); 449 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + gaplen + 450 len; 451 452 memcpy(m->m_data, &frmhdr.an_whdr, sizeof(struct ieee80211_frame)); 453 m->m_pkthdr.rcvif = ifp; 454 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 455 456 #if NBPFILTER > 0 457 if (sc->sc_drvbpf) { 458 struct mbuf mb; 459 struct an_rx_radiotap_header *tap = &sc->sc_rxtap; 460 461 tap->ar_rate = frmhdr.an_rx_rate; 462 tap->ar_antsignal = frmhdr.an_rx_signal_strength; 463 tap->ar_chan_freq = ic->ic_bss->ni_chan->ic_freq; 464 tap->ar_chan_flags = ic->ic_bss->ni_chan->ic_flags; 465 466 467 mb.m_data = (caddr_t)tap; 468 mb.m_len = sizeof(sc->sc_rxtapu); 469 mb.m_next = m; 470 mb.m_nextpkt = NULL; 471 mb.m_type = 0; 472 mb.m_flags = 0; 473 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); 474 } 475 #endif /* NBPFILTER > 0 */ 476 477 wh = mtod(m, struct ieee80211_frame *); 478 rxi.rxi_flags = 0; 479 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 480 /* 481 * WEP is decrypted by hardware. Clear WEP bit 482 * header for ieee80211_input(). 483 */ 484 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 485 486 rxi.rxi_flags |= IEEE80211_RXI_HWDEC; 487 } 488 489 ni = ieee80211_find_rxnode(ic, wh); 490 rxi.rxi_rssi = frmhdr.an_rx_signal_strength; 491 rxi.rxi_tstamp = an_switch32(frmhdr.an_rx_time); 492 ieee80211_input(ifp, m, ni, &rxi); 493 ieee80211_release_node(ic, ni); 494 } 495 496 void 497 an_txeof(struct an_softc *sc, u_int16_t status) 498 { 499 struct ifnet *ifp = &sc->sc_ic.ic_if; 500 int cur, id; 501 502 sc->sc_tx_timer = 0; 503 ifp->if_flags &= ~IFF_OACTIVE; 504 505 id = CSR_READ_2(sc, AN_TX_CMP_FID); 506 CSR_WRITE_2(sc, AN_EVENT_ACK, status & (AN_EV_TX | AN_EV_TX_EXC)); 507 508 if (status & AN_EV_TX_EXC) 509 ifp->if_oerrors++; 510 else 511 ifp->if_opackets++; 512 513 cur = sc->sc_txcur; 514 if (sc->sc_txd[cur].d_fid == id) { 515 sc->sc_txd[cur].d_inuse = 0; 516 DPRINTF2(("an_txeof: sent %x/%d\n", id, cur)); 517 AN_INC(cur, AN_TX_RING_CNT); 518 sc->sc_txcur = cur; 519 } else { 520 for (cur = 0; cur < AN_TX_RING_CNT; cur++) { 521 if (id == sc->sc_txd[cur].d_fid) { 522 sc->sc_txd[cur].d_inuse = 0; 523 break; 524 } 525 } 526 if (ifp->if_flags & IFF_DEBUG) 527 printf("%s: tx mismatch: " 528 "expected %x(%d), actual %x(%d)\n", 529 sc->sc_dev.dv_xname, 530 sc->sc_txd[sc->sc_txcur].d_fid, sc->sc_txcur, 531 id, cur); 532 } 533 } 534 535 int 536 an_intr(void *arg) 537 { 538 struct an_softc *sc = arg; 539 struct ifnet *ifp = &sc->sc_ic.ic_if; 540 int i; 541 u_int16_t status; 542 543 if (!sc->sc_enabled || sc->sc_invalid || 544 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || 545 (ifp->if_flags & IFF_RUNNING) == 0) 546 return 0; 547 548 if ((ifp->if_flags & IFF_UP) == 0) { 549 CSR_WRITE_2(sc, AN_INT_EN, 0); 550 CSR_WRITE_2(sc, AN_EVENT_ACK, ~0); 551 return 1; 552 } 553 554 /* maximum 10 loops per interrupt */ 555 for (i = 0; i < 10; i++) { 556 if (!sc->sc_enabled || sc->sc_invalid) 557 return 1; 558 if (CSR_READ_2(sc, AN_SW0) != AN_MAGIC) { 559 DPRINTF(("an_intr: magic number changed: %x\n", 560 CSR_READ_2(sc, AN_SW0))); 561 sc->sc_invalid = 1; 562 return 1; 563 } 564 status = CSR_READ_2(sc, AN_EVENT_STAT); 565 CSR_WRITE_2(sc, AN_EVENT_ACK, status & ~(AN_INTRS)); 566 if ((status & AN_INTRS) == 0) 567 break; 568 569 if (status & AN_EV_RX) 570 an_rxeof(sc); 571 572 if (status & (AN_EV_TX | AN_EV_TX_EXC)) 573 an_txeof(sc, status); 574 575 if (status & AN_EV_LINKSTAT) 576 an_linkstat_intr(sc); 577 578 if ((ifp->if_flags & IFF_OACTIVE) == 0 && 579 sc->sc_ic.ic_state == IEEE80211_S_RUN && 580 !IFQ_IS_EMPTY(&ifp->if_snd)) 581 an_start(ifp); 582 } 583 584 return 1; 585 } 586 587 /* Must be called at proper protection level! */ 588 int 589 an_cmd(struct an_softc *sc, int cmd, int val) 590 { 591 int i, stat; 592 593 /* make sure previous command completed */ 594 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) { 595 if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG) 596 printf("%s: command 0x%x busy\n", sc->sc_dev.dv_xname, 597 CSR_READ_2(sc, AN_COMMAND)); 598 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 599 } 600 601 CSR_WRITE_2(sc, AN_PARAM0, val); 602 CSR_WRITE_2(sc, AN_PARAM1, 0); 603 CSR_WRITE_2(sc, AN_PARAM2, 0); 604 CSR_WRITE_2(sc, AN_COMMAND, cmd); 605 606 if (cmd == AN_CMD_FW_RESTART) { 607 /* XXX: should sleep here */ 608 DELAY(100*1000); 609 } 610 611 for (i = 0; i < AN_TIMEOUT; i++) { 612 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD) 613 break; 614 DELAY(10); 615 } 616 617 stat = CSR_READ_2(sc, AN_STATUS); 618 619 /* clear stuck command busy if necessary */ 620 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) 621 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 622 623 /* Ack the command */ 624 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD); 625 626 if (i == AN_TIMEOUT) { 627 if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG) 628 printf("%s: command 0x%x param 0x%x timeout\n", 629 sc->sc_dev.dv_xname, cmd, val); 630 return ETIMEDOUT; 631 } 632 if (stat & AN_STAT_CMD_RESULT) { 633 if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG) 634 printf("%s: command 0x%x param 0x%x status 0x%x " 635 "resp 0x%x 0x%x 0x%x\n", 636 sc->sc_dev.dv_xname, cmd, val, stat, 637 CSR_READ_2(sc, AN_RESP0), CSR_READ_2(sc, AN_RESP1), 638 CSR_READ_2(sc, AN_RESP2)); 639 return EIO; 640 } 641 642 return 0; 643 } 644 645 int 646 an_reset(struct an_softc *sc) 647 { 648 649 DPRINTF(("an_reset\n")); 650 651 if (!sc->sc_enabled) 652 return ENXIO; 653 654 an_cmd(sc, AN_CMD_ENABLE, 0); 655 an_cmd(sc, AN_CMD_FW_RESTART, 0); 656 an_cmd(sc, AN_CMD_NOOP2, 0); 657 658 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) { 659 printf("%s: reset failed\n", sc->sc_dev.dv_xname); 660 return ETIMEDOUT; 661 } 662 663 an_cmd(sc, AN_CMD_DISABLE, 0); 664 return 0; 665 } 666 667 void 668 an_linkstat_intr(struct an_softc *sc) 669 { 670 struct ieee80211com *ic = &sc->sc_ic; 671 u_int16_t status; 672 673 status = CSR_READ_2(sc, AN_LINKSTAT); 674 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT); 675 DPRINTF(("an_linkstat_intr: status 0x%x\n", status)); 676 677 if (status == AN_LINKSTAT_ASSOCIATED) { 678 if (ic->ic_state != IEEE80211_S_RUN 679 #ifndef IEEE80211_STA_ONLY 680 || ic->ic_opmode == IEEE80211_M_IBSS 681 #endif 682 ) 683 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 684 } else { 685 if (ic->ic_opmode == IEEE80211_M_STA) 686 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 687 } 688 } 689 690 /* 691 * Wait for firmware come up after power enabled. 692 */ 693 void 694 an_wait(struct an_softc *sc) 695 { 696 int i; 697 698 CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_NOOP2); 699 for (i = 0; i < 3*hz; i++) { 700 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD) 701 break; 702 (void)tsleep(sc, PWAIT, "anatch", 1); 703 } 704 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD); 705 } 706 707 int 708 an_read_bap(struct an_softc *sc, int id, int off, void *buf, int len, int blen) 709 { 710 int error, cnt, cnt2; 711 712 if (len == 0 || blen == 0) 713 return 0; 714 if (off == -1) 715 off = sc->sc_bap_off; 716 if (id != sc->sc_bap_id || off != sc->sc_bap_off) { 717 if ((error = an_seek_bap(sc, id, off)) != 0) 718 return EIO; 719 } 720 721 cnt = (blen + 1) / 2; 722 CSR_READ_MULTI_STREAM_2(sc, AN_DATA0, (u_int16_t *)buf, cnt); 723 for (cnt2 = (len + 1) / 2; cnt < cnt2; cnt++) 724 (void) CSR_READ_2(sc, AN_DATA0); 725 sc->sc_bap_off += cnt * 2; 726 727 return 0; 728 } 729 730 int 731 an_write_bap(struct an_softc *sc, int id, int off, void *buf, int buflen) 732 { 733 int error, cnt; 734 735 if (buflen == 0) 736 return 0; 737 if (off == -1) 738 off = sc->sc_bap_off; 739 if (id != sc->sc_bap_id || off != sc->sc_bap_off) { 740 if ((error = an_seek_bap(sc, id, off)) != 0) 741 return EIO; 742 } 743 744 cnt = (buflen + 1) / 2; 745 CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0, (u_int16_t *)buf, cnt); 746 sc->sc_bap_off += cnt * 2; 747 return 0; 748 } 749 750 int 751 an_seek_bap(struct an_softc *sc, int id, int off) 752 { 753 int i, status; 754 755 CSR_WRITE_2(sc, AN_SEL0, id); 756 CSR_WRITE_2(sc, AN_OFF0, off); 757 758 for (i = 0; ; i++) { 759 status = CSR_READ_2(sc, AN_OFF0); 760 if ((status & AN_OFF_BUSY) == 0) 761 break; 762 if (i == AN_TIMEOUT) { 763 printf("%s: timeout in an_seek_bap to 0x%x/0x%x\n", 764 sc->sc_dev.dv_xname, id, off); 765 sc->sc_bap_off = AN_OFF_ERR; /* invalidate */ 766 return ETIMEDOUT; 767 } 768 DELAY(10); 769 } 770 if (status & AN_OFF_ERR) { 771 printf("%s: failed in an_seek_bap to 0x%x/0x%x\n", 772 sc->sc_dev.dv_xname, id, off); 773 sc->sc_bap_off = AN_OFF_ERR; /* invalidate */ 774 return EIO; 775 } 776 sc->sc_bap_id = id; 777 sc->sc_bap_off = off; 778 return 0; 779 } 780 781 int 782 an_mwrite_bap(struct an_softc *sc, int id, int off, struct mbuf *m, int totlen) 783 { 784 int error, len, cnt; 785 786 if (off == -1) 787 off = sc->sc_bap_off; 788 if (id != sc->sc_bap_id || off != sc->sc_bap_off) { 789 if ((error = an_seek_bap(sc, id, off)) != 0) 790 return EIO; 791 } 792 793 for (len = 0; m != NULL; m = m->m_next) { 794 if (m->m_len == 0) 795 continue; 796 len = min(m->m_len, totlen); 797 798 if ((mtod(m, u_long) & 0x1) || (len & 0x1)) { 799 m_copydata(m, 0, totlen, (caddr_t)&sc->sc_buf.sc_txbuf); 800 cnt = (totlen + 1) / 2; 801 an_swap16((u_int16_t *)&sc->sc_buf.sc_txbuf, cnt); 802 CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0, 803 sc->sc_buf.sc_val, cnt); 804 off += cnt * 2; 805 break; 806 } 807 cnt = len / 2; 808 an_swap16((u_int16_t *)mtod(m, u_int16_t *), cnt); 809 CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0, mtod(m, u_int16_t *), 810 cnt); 811 off += len; 812 totlen -= len; 813 } 814 sc->sc_bap_off = off; 815 return 0; 816 } 817 818 int 819 an_alloc_nicmem(struct an_softc *sc, int len, int *idp) 820 { 821 int i; 822 823 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 824 printf("%s: failed to allocate %d bytes on NIC\n", 825 sc->sc_dev.dv_xname, len); 826 return(ENOMEM); 827 } 828 829 for (i = 0; i < AN_TIMEOUT; i++) { 830 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC) 831 break; 832 if (i == AN_TIMEOUT) { 833 printf("%s: timeout in alloc\n", sc->sc_dev.dv_xname); 834 return ETIMEDOUT; 835 } 836 DELAY(10); 837 } 838 839 *idp = CSR_READ_2(sc, AN_ALLOC_FID); 840 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 841 return 0; 842 } 843 844 int 845 an_read_rid(struct an_softc *sc, int rid, void *buf, int *buflenp) 846 { 847 int error; 848 u_int16_t len; 849 850 /* Tell the NIC to enter record read mode. */ 851 error = an_cmd(sc, AN_CMD_ACCESS | AN_ACCESS_READ, rid); 852 if (error) 853 return error; 854 855 /* length in byte, including length itself */ 856 error = an_read_bap(sc, rid, 0, &len, sizeof(len), sizeof(len)); 857 if (error) 858 return error; 859 860 len -= 2; 861 return an_read_bap(sc, rid, sizeof(len), buf, len, *buflenp); 862 } 863 864 int 865 an_write_rid(struct an_softc *sc, int rid, void *buf, int buflen) 866 { 867 int error; 868 u_int16_t len; 869 870 /* length in byte, including length itself */ 871 len = buflen + 2; 872 873 error = an_write_bap(sc, rid, 0, &len, sizeof(len)); 874 if (error) 875 return error; 876 error = an_write_bap(sc, rid, sizeof(len), buf, buflen); 877 if (error) 878 return error; 879 880 return an_cmd(sc, AN_CMD_ACCESS | AN_ACCESS_WRITE, rid); 881 } 882 883 int 884 an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 885 { 886 struct an_softc *sc = ifp->if_softc; 887 struct ifaddr *ifa = (struct ifaddr *)data; 888 int s, error = 0; 889 890 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 891 return ENXIO; 892 893 s = splnet(); 894 895 switch(command) { 896 case SIOCSIFADDR: 897 ifp->if_flags |= IFF_UP; 898 switch (ifa->ifa_addr->sa_family) { 899 #ifdef INET 900 case AF_INET: 901 error = an_init(ifp); 902 arp_ifinit(&sc->sc_ic.ic_ac, ifa); 903 break; 904 #endif 905 default: 906 error = an_init(ifp); 907 break; 908 } 909 break; 910 case SIOCSIFFLAGS: 911 if (ifp->if_flags & IFF_UP) { 912 if (sc->sc_enabled) { 913 /* 914 * To avoid rescanning another access point, 915 * do not call an_init() here. Instead, only 916 * reflect promisc mode settings. 917 */ 918 error = an_cmd(sc, AN_CMD_SET_MODE, 919 (ifp->if_flags & IFF_PROMISC) ? 0xffff : 0); 920 } else 921 error = an_init(ifp); 922 } else if (sc->sc_enabled) 923 an_stop(ifp, 1); 924 break; 925 case SIOCADDMULTI: 926 case SIOCDELMULTI: 927 /* The Aironet has no multicast filter. */ 928 error = 0; 929 break; 930 case SIOCS80211NWKEY: 931 error = an_set_nwkey(sc, (struct ieee80211_nwkey *)data); 932 break; 933 case SIOCG80211NWKEY: 934 error = an_get_nwkey(sc, (struct ieee80211_nwkey *)data); 935 break; 936 default: 937 error = ieee80211_ioctl(ifp, command, data); 938 break; 939 } 940 if (error == ENETRESET) { 941 if (sc->sc_enabled) 942 error = an_init(ifp); 943 else 944 error = 0; 945 } 946 splx(s); 947 return(error); 948 } 949 950 int 951 an_init(struct ifnet *ifp) 952 { 953 struct an_softc *sc = ifp->if_softc; 954 struct ieee80211com *ic = &sc->sc_ic; 955 int i, error, fid; 956 957 DPRINTF(("an_init: enabled %d\n", sc->sc_enabled)); 958 if (!sc->sc_enabled) { 959 if (sc->sc_enable) 960 (*sc->sc_enable)(sc); 961 an_wait(sc); 962 sc->sc_enabled = 1; 963 } else { 964 an_stop(ifp, 0); 965 if ((error = an_reset(sc)) != 0) { 966 printf("%s: failed to reset\n", ifp->if_xname); 967 an_stop(ifp, 1); 968 return error; 969 } 970 } 971 CSR_WRITE_2(sc, AN_SW0, AN_MAGIC); 972 973 /* Allocate the TX buffers */ 974 for (i = 0; i < AN_TX_RING_CNT; i++) { 975 if ((error = an_alloc_nicmem(sc, AN_TX_MAX_LEN, &fid)) != 0) { 976 printf("%s: failed to allocate nic memory\n", 977 ifp->if_xname); 978 an_stop(ifp, 1); 979 return error; 980 } 981 DPRINTF2(("an_init: txbuf %d allocated %x\n", i, fid)); 982 sc->sc_txd[i].d_fid = fid; 983 sc->sc_txd[i].d_inuse = 0; 984 } 985 sc->sc_txcur = sc->sc_txnext = 0; 986 987 IEEE80211_ADDR_COPY(sc->sc_config.an_macaddr, ic->ic_myaddr); 988 an_swap16((u_int16_t *)&sc->sc_config.an_macaddr, 3); 989 sc->sc_config.an_scanmode = AN_SCANMODE_ACTIVE; 990 sc->sc_config.an_authtype = AN_AUTHTYPE_OPEN; /*XXX*/ 991 if (ic->ic_flags & IEEE80211_F_WEPON) { 992 sc->sc_config.an_authtype |= 993 AN_AUTHTYPE_PRIVACY_IN_USE; 994 } 995 sc->sc_config.an_listen_interval = ic->ic_lintval; 996 sc->sc_config.an_beacon_period = ic->ic_lintval; 997 if (ic->ic_flags & IEEE80211_F_PMGTON) 998 sc->sc_config.an_psave_mode = AN_PSAVE_PSP; 999 else 1000 sc->sc_config.an_psave_mode = AN_PSAVE_CAM; 1001 sc->sc_config.an_ds_channel = 1002 ieee80211_chan2ieee(ic, ic->ic_ibss_chan); 1003 1004 switch (ic->ic_opmode) { 1005 case IEEE80211_M_STA: 1006 sc->sc_config.an_opmode = 1007 AN_OPMODE_INFRASTRUCTURE_STATION; 1008 sc->sc_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 1009 break; 1010 #ifndef IEEE80211_STA_ONLY 1011 case IEEE80211_M_IBSS: 1012 sc->sc_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 1013 sc->sc_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 1014 break; 1015 #endif 1016 case IEEE80211_M_MONITOR: 1017 sc->sc_config.an_opmode = 1018 AN_OPMODE_INFRASTRUCTURE_STATION; 1019 sc->sc_config.an_rxmode = 1020 AN_RXMODE_80211_MONITOR_ANYBSS; 1021 sc->sc_config.an_authtype = AN_AUTHTYPE_NONE; 1022 if (ic->ic_flags & IEEE80211_F_WEPON) 1023 sc->sc_config.an_authtype |= 1024 AN_AUTHTYPE_PRIVACY_IN_USE | 1025 AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1026 break; 1027 default: 1028 printf("%s: bad opmode %d\n", ifp->if_xname, ic->ic_opmode); 1029 an_stop(ifp, 1); 1030 return EIO; 1031 } 1032 sc->sc_config.an_rxmode |= AN_RXMODE_NO_8023_HEADER; 1033 1034 /* Set the ssid list */ 1035 memset(&sc->sc_buf, 0, sizeof(sc->sc_buf.sc_ssidlist)); 1036 sc->sc_buf.sc_ssidlist.an_entry[0].an_ssid_len = 1037 ic->ic_des_esslen; 1038 if (ic->ic_des_esslen) 1039 memcpy(sc->sc_buf.sc_ssidlist.an_entry[0].an_ssid, 1040 ic->ic_des_essid, ic->ic_des_esslen); 1041 an_swap16((u_int16_t *)&sc->sc_buf.sc_ssidlist.an_entry[0].an_ssid, 16); 1042 if (an_write_rid(sc, AN_RID_SSIDLIST, &sc->sc_buf, 1043 sizeof(sc->sc_buf.sc_ssidlist)) != 0) { 1044 printf("%s: failed to write ssid list\n", ifp->if_xname); 1045 an_stop(ifp, 1); 1046 return error; 1047 } 1048 1049 /* Set the AP list */ 1050 memset(&sc->sc_buf, 0, sizeof(sc->sc_buf.sc_aplist)); 1051 (void)an_write_rid(sc, AN_RID_APLIST, &sc->sc_buf, 1052 sizeof(sc->sc_buf.sc_aplist)); 1053 1054 /* Set the encapsulation */ 1055 for (i = 0; i < AN_ENCAP_NENTS; i++) { 1056 sc->sc_buf.sc_encap.an_entry[i].an_ethertype = 0; 1057 sc->sc_buf.sc_encap.an_entry[i].an_action = 1058 AN_RXENCAP_RFC1024 | AN_TXENCAP_RFC1024; 1059 } 1060 (void)an_write_rid(sc, AN_RID_ENCAP, &sc->sc_buf, 1061 sizeof(sc->sc_buf.sc_encap)); 1062 1063 /* Set the WEP Keys */ 1064 if (ic->ic_flags & IEEE80211_F_WEPON) 1065 an_write_wepkey(sc, AN_RID_WEP_VOLATILE, sc->sc_wepkeys, 1066 sc->sc_tx_key); 1067 1068 /* Set the configuration */ 1069 if (an_write_rid(sc, AN_RID_GENCONFIG, &sc->sc_config, 1070 sizeof(sc->sc_config)) != 0) { 1071 printf("%s: failed to write config\n", ifp->if_xname); 1072 an_stop(ifp, 1); 1073 return error; 1074 } 1075 1076 /* Enable the MAC */ 1077 if (an_cmd(sc, AN_CMD_ENABLE, 0)) { 1078 printf("%s: failed to enable MAC\n", sc->sc_dev.dv_xname); 1079 an_stop(ifp, 1); 1080 return ENXIO; 1081 } 1082 if (ifp->if_flags & IFF_PROMISC) 1083 an_cmd(sc, AN_CMD_SET_MODE, 0xffff); 1084 1085 ifp->if_flags |= IFF_RUNNING; 1086 ifp->if_flags &= ~IFF_OACTIVE; 1087 ic->ic_state = IEEE80211_S_INIT; 1088 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1089 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 1090 1091 /* enable interrupts */ 1092 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 1093 return 0; 1094 } 1095 1096 void 1097 an_start(struct ifnet *ifp) 1098 { 1099 struct an_softc *sc = (struct an_softc *)ifp->if_softc; 1100 struct ieee80211com *ic = &sc->sc_ic; 1101 struct ieee80211_node *ni; 1102 struct ieee80211_frame *wh; 1103 struct an_txframe frmhdr; 1104 struct mbuf *m; 1105 u_int16_t len; 1106 int cur, fid; 1107 1108 if (!sc->sc_enabled || sc->sc_invalid) { 1109 DPRINTF(("an_start: noop: enabled %d invalid %d\n", 1110 sc->sc_enabled, sc->sc_invalid)); 1111 return; 1112 } 1113 1114 memset(&frmhdr, 0, sizeof(frmhdr)); 1115 cur = sc->sc_txnext; 1116 for (;;) { 1117 if (ic->ic_state != IEEE80211_S_RUN) { 1118 DPRINTF(("an_start: not running %d\n", ic->ic_state)); 1119 break; 1120 } 1121 IFQ_POLL(&ifp->if_snd, m); 1122 if (m == NULL) { 1123 DPRINTF2(("an_start: no pending mbuf\n")); 1124 break; 1125 } 1126 if (sc->sc_txd[cur].d_inuse) { 1127 DPRINTF2(("an_start: %x/%d busy\n", 1128 sc->sc_txd[cur].d_fid, cur)); 1129 ifp->if_flags |= IFF_OACTIVE; 1130 break; 1131 } 1132 IFQ_DEQUEUE(&ifp->if_snd, m); 1133 ifp->if_opackets++; 1134 #if NBPFILTER > 0 1135 if (ifp->if_bpf) 1136 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 1137 #endif 1138 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL) { 1139 ifp->if_oerrors++; 1140 continue; 1141 } 1142 if (ni != NULL) 1143 ieee80211_release_node(ic, ni); 1144 #if NBPFILTER > 0 1145 if (ic->ic_rawbpf) 1146 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); 1147 #endif 1148 1149 wh = mtod(m, struct ieee80211_frame *); 1150 if (ic->ic_flags & IEEE80211_F_WEPON) 1151 wh->i_fc[1] |= IEEE80211_FC1_WEP; 1152 m_copydata(m, 0, sizeof(struct ieee80211_frame), 1153 (caddr_t)&frmhdr.an_whdr); 1154 an_swap16((u_int16_t *)&frmhdr.an_whdr, sizeof(struct ieee80211_frame)/2); 1155 1156 /* insert payload length in front of llc/snap */ 1157 len = htons(m->m_pkthdr.len - sizeof(struct ieee80211_frame)); 1158 m_adj(m, sizeof(struct ieee80211_frame) - sizeof(len)); 1159 if (mtod(m, u_long) & 0x01) 1160 memcpy(mtod(m, caddr_t), &len, sizeof(len)); 1161 else 1162 *mtod(m, u_int16_t *) = len; 1163 1164 /* 1165 * XXX Aironet firmware apparently convert the packet 1166 * with longer than 1500 bytes in length into LLC/SNAP. 1167 * If we have 1500 bytes in ethernet payload, it is 1168 * 1508 bytes including LLC/SNAP and will be inserted 1169 * additional LLC/SNAP header with 1501-1508 in its 1170 * ethertype !! 1171 * So we skip LLC/SNAP header and force firmware to 1172 * convert it to LLC/SNAP again. 1173 */ 1174 m_adj(m, sizeof(struct llc)); 1175 1176 frmhdr.an_tx_ctl = AN_TXCTL_80211; 1177 frmhdr.an_tx_payload_len = m->m_pkthdr.len; 1178 frmhdr.an_gaplen = AN_TXGAP_802_11; 1179 1180 if (ic->ic_fixed_rate != -1) 1181 frmhdr.an_tx_rate = 1182 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ 1183 ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 1184 else 1185 frmhdr.an_tx_rate = 0; 1186 1187 if (sizeof(frmhdr) + AN_TXGAP_802_11 + sizeof(len) + 1188 m->m_pkthdr.len > AN_TX_MAX_LEN) { 1189 ifp->if_oerrors++; 1190 m_freem(m); 1191 continue; 1192 } 1193 1194 #if NBPFILTER > 0 1195 if (sc->sc_drvbpf) { 1196 struct mbuf mb; 1197 struct an_tx_radiotap_header *tap = &sc->sc_txtap; 1198 1199 tap->at_rate = 1200 ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate]; 1201 tap->at_chan_freq = 1202 ic->ic_bss->ni_chan->ic_freq; 1203 tap->at_chan_flags = 1204 ic->ic_bss->ni_chan->ic_flags; 1205 1206 mb.m_data = (caddr_t)tap; 1207 mb.m_len = sizeof(sc->sc_txtapu); 1208 mb.m_next = m; 1209 mb.m_nextpkt = NULL; 1210 mb.m_type = 0; 1211 mb.m_flags = 0; 1212 bpf_mtap(sc->sc_drvbpf, m, BPF_DIRECTION_OUT); 1213 } 1214 #endif 1215 1216 fid = sc->sc_txd[cur].d_fid; 1217 if (an_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) { 1218 ifp->if_oerrors++; 1219 m_freem(m); 1220 continue; 1221 } 1222 /* dummy write to avoid seek. */ 1223 an_write_bap(sc, fid, -1, &frmhdr, AN_TXGAP_802_11); 1224 an_mwrite_bap(sc, fid, -1, m, m->m_pkthdr.len); 1225 m_freem(m); 1226 1227 DPRINTF2(("an_start: send %d byte via %x/%d\n", 1228 ntohs(len) + sizeof(struct ieee80211_frame), 1229 fid, cur)); 1230 sc->sc_txd[cur].d_inuse = 1; 1231 if (an_cmd(sc, AN_CMD_TX, fid)) { 1232 printf("%s: xmit failed\n", ifp->if_xname); 1233 sc->sc_txd[cur].d_inuse = 0; 1234 continue; 1235 } 1236 sc->sc_tx_timer = 5; 1237 ifp->if_timer = 1; 1238 AN_INC(cur, AN_TX_RING_CNT); 1239 sc->sc_txnext = cur; 1240 } 1241 } 1242 1243 void 1244 an_stop(struct ifnet *ifp, int disable) 1245 { 1246 struct an_softc *sc = ifp->if_softc; 1247 int i, s; 1248 1249 if (!sc->sc_enabled) 1250 return; 1251 1252 DPRINTF(("an_stop: disable %d\n", disable)); 1253 1254 s = splnet(); 1255 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 1256 if (!sc->sc_invalid) { 1257 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 1258 CSR_WRITE_2(sc, AN_INT_EN, 0); 1259 an_cmd(sc, AN_CMD_DISABLE, 0); 1260 1261 for (i = 0; i < AN_TX_RING_CNT; i++) 1262 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->sc_txd[i].d_fid); 1263 } 1264 1265 sc->sc_tx_timer = 0; 1266 ifp->if_timer = 0; 1267 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1268 1269 if (disable) { 1270 if (sc->sc_disable) 1271 (*sc->sc_disable)(sc); 1272 sc->sc_enabled = 0; 1273 } 1274 splx(s); 1275 } 1276 1277 void 1278 an_watchdog(struct ifnet *ifp) 1279 { 1280 struct an_softc *sc = ifp->if_softc; 1281 1282 if (!sc->sc_enabled) 1283 return; 1284 1285 if (sc->sc_tx_timer) { 1286 if (--sc->sc_tx_timer == 0) { 1287 printf("%s: device timeout\n", ifp->if_xname); 1288 ifp->if_oerrors++; 1289 an_init(ifp); 1290 return; 1291 } 1292 ifp->if_timer = 1; 1293 } 1294 ieee80211_watchdog(ifp); 1295 } 1296 1297 /* TBD factor with ieee80211_media_change */ 1298 int 1299 an_media_change(struct ifnet *ifp) 1300 { 1301 struct an_softc *sc = ifp->if_softc; 1302 struct ieee80211com *ic = &sc->sc_ic; 1303 struct ifmedia_entry *ime; 1304 enum ieee80211_opmode newmode; 1305 int i, rate, error = 0; 1306 1307 ime = ic->ic_media.ifm_cur; 1308 if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) { 1309 i = -1; 1310 } else { 1311 struct ieee80211_rateset *rs = 1312 &ic->ic_sup_rates[IEEE80211_MODE_11B]; 1313 rate = ieee80211_media2rate(ime->ifm_media); 1314 if (rate == 0) 1315 return EINVAL; 1316 for (i = 0; i < rs->rs_nrates; i++) { 1317 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 1318 break; 1319 } 1320 if (i == rs->rs_nrates) 1321 return EINVAL; 1322 } 1323 if (ic->ic_fixed_rate != i) { 1324 ic->ic_fixed_rate = i; 1325 error = ENETRESET; 1326 } 1327 1328 #ifndef IEEE80211_STA_ONLY 1329 if (ime->ifm_media & IFM_IEEE80211_ADHOC) 1330 newmode = IEEE80211_M_IBSS; 1331 else if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 1332 newmode = IEEE80211_M_HOSTAP; 1333 else 1334 #endif 1335 if (ime->ifm_media & IFM_IEEE80211_MONITOR) 1336 newmode = IEEE80211_M_MONITOR; 1337 else 1338 newmode = IEEE80211_M_STA; 1339 if (ic->ic_opmode != newmode) { 1340 ic->ic_opmode = newmode; 1341 error = ENETRESET; 1342 } 1343 if (error == ENETRESET) { 1344 if (sc->sc_enabled) 1345 error = an_init(ifp); 1346 else 1347 error = 0; 1348 } 1349 ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media); 1350 1351 return error; 1352 } 1353 1354 void 1355 an_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1356 { 1357 struct an_softc *sc = ifp->if_softc; 1358 struct ieee80211com *ic = &sc->sc_ic; 1359 int rate, buflen; 1360 1361 if (sc->sc_enabled == 0) { 1362 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 1363 imr->ifm_status = 0; 1364 return; 1365 } 1366 1367 imr->ifm_status = IFM_AVALID; 1368 imr->ifm_active = IFM_IEEE80211; 1369 if (ic->ic_state == IEEE80211_S_RUN) 1370 imr->ifm_status |= IFM_ACTIVE; 1371 buflen = sizeof(sc->sc_buf); 1372 if (ic->ic_fixed_rate != -1) 1373 rate = ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ 1374 ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 1375 else if (an_read_rid(sc, AN_RID_STATUS, &sc->sc_buf, &buflen) != 0) 1376 rate = 0; 1377 else 1378 rate = sc->sc_buf.sc_status.an_current_tx_rate; 1379 imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); 1380 switch (ic->ic_opmode) { 1381 case IEEE80211_M_STA: 1382 break; 1383 #ifndef IEEE80211_STA_ONLY 1384 case IEEE80211_M_IBSS: 1385 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1386 break; 1387 case IEEE80211_M_HOSTAP: 1388 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1389 break; 1390 #endif 1391 case IEEE80211_M_MONITOR: 1392 imr->ifm_active |= IFM_IEEE80211_MONITOR; 1393 break; 1394 default: 1395 break; 1396 } 1397 } 1398 1399 int 1400 an_set_nwkey(struct an_softc *sc, struct ieee80211_nwkey *nwkey) 1401 { 1402 int error; 1403 struct ieee80211com *ic = &sc->sc_ic; 1404 u_int16_t prevauth; 1405 1406 error = 0; 1407 prevauth = sc->sc_config.an_authtype; 1408 1409 switch (nwkey->i_wepon) { 1410 case IEEE80211_NWKEY_OPEN: 1411 sc->sc_config.an_authtype = AN_AUTHTYPE_OPEN; 1412 ic->ic_flags &= ~IEEE80211_F_WEPON; 1413 break; 1414 1415 case IEEE80211_NWKEY_WEP: 1416 case IEEE80211_NWKEY_WEP | IEEE80211_NWKEY_PERSIST: 1417 error = an_set_nwkey_wep(sc, nwkey); 1418 if (error == 0 || error == ENETRESET) { 1419 sc->sc_config.an_authtype = 1420 AN_AUTHTYPE_OPEN | AN_AUTHTYPE_PRIVACY_IN_USE; 1421 ic->ic_flags |= IEEE80211_F_WEPON; 1422 } 1423 break; 1424 1425 default: 1426 error = EINVAL; 1427 break; 1428 } 1429 if (error == 0 && prevauth != sc->sc_config.an_authtype) 1430 error = ENETRESET; 1431 return error; 1432 } 1433 1434 int 1435 an_set_nwkey_wep(struct an_softc *sc, struct ieee80211_nwkey *nwkey) 1436 { 1437 int i, txkey, anysetkey, needreset, error; 1438 struct an_wepkey keys[IEEE80211_WEP_NKID]; 1439 1440 error = 0; 1441 memset(keys, 0, sizeof(keys)); 1442 anysetkey = needreset = 0; 1443 1444 /* load argument and sanity check */ 1445 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1446 keys[i].an_wep_keylen = nwkey->i_key[i].i_keylen; 1447 if (keys[i].an_wep_keylen < 0) 1448 continue; 1449 if (keys[i].an_wep_keylen != 0 && 1450 keys[i].an_wep_keylen < IEEE80211_WEP_KEYLEN) 1451 return EINVAL; 1452 if (keys[i].an_wep_keylen > sizeof(keys[i].an_wep_key)) 1453 return EINVAL; 1454 if ((error = copyin(nwkey->i_key[i].i_keydat, 1455 keys[i].an_wep_key, keys[i].an_wep_keylen)) != 0) 1456 return error; 1457 anysetkey++; 1458 } 1459 txkey = nwkey->i_defkid - 1; 1460 if (txkey >= 0) { 1461 if (txkey >= IEEE80211_WEP_NKID) 1462 return EINVAL; 1463 /* default key must have a valid value */ 1464 if (keys[txkey].an_wep_keylen == 0 || 1465 (keys[txkey].an_wep_keylen < 0 && 1466 sc->sc_perskeylen[txkey] == 0)) 1467 return EINVAL; 1468 anysetkey++; 1469 } 1470 DPRINTF(("an_set_nwkey_wep: %s: %sold(%d:%d,%d,%d,%d) " 1471 "pers(%d:%d,%d,%d,%d) new(%d:%d,%d,%d,%d)\n", 1472 sc->sc_dev.dv_xname, 1473 ((nwkey->i_wepon & IEEE80211_NWKEY_PERSIST) ? "persist: " : ""), 1474 sc->sc_tx_key, 1475 sc->sc_wepkeys[0].an_wep_keylen, sc->sc_wepkeys[1].an_wep_keylen, 1476 sc->sc_wepkeys[2].an_wep_keylen, sc->sc_wepkeys[3].an_wep_keylen, 1477 sc->sc_tx_perskey, 1478 sc->sc_perskeylen[0], sc->sc_perskeylen[1], 1479 sc->sc_perskeylen[2], sc->sc_perskeylen[3], 1480 txkey, 1481 keys[0].an_wep_keylen, keys[1].an_wep_keylen, 1482 keys[2].an_wep_keylen, keys[3].an_wep_keylen)); 1483 if (!(nwkey->i_wepon & IEEE80211_NWKEY_PERSIST)) { 1484 /* set temporary keys */ 1485 sc->sc_tx_key = txkey; 1486 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1487 if (keys[i].an_wep_keylen < 0) 1488 continue; 1489 memcpy(&sc->sc_wepkeys[i], &keys[i], sizeof(keys[i])); 1490 } 1491 } else { 1492 /* set persist keys */ 1493 if (anysetkey) { 1494 /* prepare to write nvram */ 1495 if (!sc->sc_enabled) { 1496 if (sc->sc_enable) 1497 (*sc->sc_enable)(sc); 1498 an_wait(sc); 1499 sc->sc_enabled = 1; 1500 error = an_write_wepkey(sc, 1501 AN_RID_WEP_PERSISTENT, keys, txkey); 1502 if (sc->sc_disable) 1503 (*sc->sc_disable)(sc); 1504 sc->sc_enabled = 0; 1505 } else { 1506 an_cmd(sc, AN_CMD_DISABLE, 0); 1507 error = an_write_wepkey(sc, 1508 AN_RID_WEP_PERSISTENT, keys, txkey); 1509 an_cmd(sc, AN_CMD_ENABLE, 0); 1510 } 1511 if (error) 1512 return error; 1513 } 1514 if (txkey >= 0) 1515 sc->sc_tx_perskey = txkey; 1516 if (sc->sc_tx_key >= 0) { 1517 sc->sc_tx_key = -1; 1518 needreset++; 1519 } 1520 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1521 if (sc->sc_wepkeys[i].an_wep_keylen >= 0) { 1522 memset(&sc->sc_wepkeys[i].an_wep_key, 0, 1523 sizeof(sc->sc_wepkeys[i].an_wep_key)); 1524 sc->sc_wepkeys[i].an_wep_keylen = -1; 1525 needreset++; 1526 } 1527 if (keys[i].an_wep_keylen >= 0) 1528 sc->sc_perskeylen[i] = keys[i].an_wep_keylen; 1529 } 1530 } 1531 if (needreset) { 1532 /* firmware restart to reload persistent key */ 1533 an_reset(sc); 1534 } 1535 if (anysetkey || needreset) 1536 error = ENETRESET; 1537 return error; 1538 } 1539 1540 int 1541 an_get_nwkey(struct an_softc *sc, struct ieee80211_nwkey *nwkey) 1542 { 1543 int i, error; 1544 1545 error = 0; 1546 if (sc->sc_config.an_authtype & AN_AUTHTYPE_LEAP) 1547 nwkey->i_wepon = IEEE80211_NWKEY_EAP; 1548 else if (sc->sc_config.an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) 1549 nwkey->i_wepon = IEEE80211_NWKEY_WEP; 1550 else 1551 nwkey->i_wepon = IEEE80211_NWKEY_OPEN; 1552 if (sc->sc_tx_key == -1) 1553 nwkey->i_defkid = sc->sc_tx_perskey + 1; 1554 else 1555 nwkey->i_defkid = sc->sc_tx_key + 1; 1556 if (nwkey->i_key[0].i_keydat == NULL) 1557 return 0; 1558 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1559 if (nwkey->i_key[i].i_keydat == NULL) 1560 continue; 1561 /* do not show any keys to non-root user */ 1562 if ((error = suser(curproc, 0)) != 0) 1563 break; 1564 nwkey->i_key[i].i_keylen = sc->sc_wepkeys[i].an_wep_keylen; 1565 if (nwkey->i_key[i].i_keylen < 0) { 1566 if (sc->sc_perskeylen[i] == 0) 1567 nwkey->i_key[i].i_keylen = 0; 1568 continue; 1569 } 1570 if ((error = copyout(sc->sc_wepkeys[i].an_wep_key, 1571 nwkey->i_key[i].i_keydat, 1572 sc->sc_wepkeys[i].an_wep_keylen)) != 0) 1573 break; 1574 } 1575 return error; 1576 } 1577 1578 int 1579 an_write_wepkey(struct an_softc *sc, int type, struct an_wepkey *keys, int kid) 1580 { 1581 int i, error; 1582 struct an_rid_wepkey *akey; 1583 1584 error = 0; 1585 akey = &sc->sc_buf.sc_wepkey; 1586 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1587 memset(akey, 0, sizeof(struct an_rid_wepkey)); 1588 if (keys[i].an_wep_keylen < 0 || 1589 keys[i].an_wep_keylen > sizeof(akey->an_key)) 1590 continue; 1591 akey->an_key_len = keys[i].an_wep_keylen; 1592 akey->an_key_index = i; 1593 akey->an_mac_addr[0] = 1; /* default mac */ 1594 an_swap16((u_int16_t *)&akey->an_mac_addr, 3); 1595 memcpy(akey->an_key, keys[i].an_wep_key, keys[i].an_wep_keylen); 1596 an_swap16((u_int16_t *)&akey->an_key, 8); 1597 if ((error = an_write_rid(sc, type, akey, sizeof(*akey))) != 0) 1598 return error; 1599 } 1600 if (kid >= 0) { 1601 memset(akey, 0, sizeof(struct an_rid_wepkey)); 1602 akey->an_key_index = 0xffff; 1603 akey->an_mac_addr[0] = kid; 1604 an_swap16((u_int16_t *)&akey->an_mac_addr, 3); 1605 akey->an_key_len = 0; 1606 memset(akey->an_key, 0, sizeof(akey->an_key)); 1607 error = an_write_rid(sc, type, akey, sizeof(*akey)); 1608 } 1609 return error; 1610 } 1611 1612 int 1613 an_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1614 { 1615 struct an_softc *sc = ic->ic_softc; 1616 struct ieee80211_node *ni = ic->ic_bss; 1617 enum ieee80211_state ostate; 1618 int buflen; 1619 1620 ostate = ic->ic_state; 1621 DPRINTF(("an_newstate: %s -> %s\n", ieee80211_state_name[ostate], 1622 ieee80211_state_name[nstate])); 1623 1624 switch (nstate) { 1625 case IEEE80211_S_INIT: 1626 ic->ic_flags &= ~IEEE80211_F_IBSSON; 1627 return (*sc->sc_newstate)(ic, nstate, arg); 1628 1629 case IEEE80211_S_RUN: 1630 buflen = sizeof(sc->sc_buf); 1631 an_read_rid(sc, AN_RID_STATUS, &sc->sc_buf, &buflen); 1632 an_swap16((u_int16_t *)&sc->sc_buf.sc_status.an_cur_bssid, 3); 1633 an_swap16((u_int16_t *)&sc->sc_buf.sc_status.an_ssid, 16); 1634 IEEE80211_ADDR_COPY(ni->ni_bssid, 1635 sc->sc_buf.sc_status.an_cur_bssid); 1636 IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid); 1637 ni->ni_chan = &ic->ic_channels[ 1638 sc->sc_buf.sc_status.an_cur_channel]; 1639 ni->ni_esslen = sc->sc_buf.sc_status.an_ssidlen; 1640 if (ni->ni_esslen > IEEE80211_NWID_LEN) 1641 ni->ni_esslen = IEEE80211_NWID_LEN; /*XXX*/ 1642 memcpy(ni->ni_essid, sc->sc_buf.sc_status.an_ssid, 1643 ni->ni_esslen); 1644 ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; /*XXX*/ 1645 if (ic->ic_if.if_flags & IFF_DEBUG) { 1646 printf("%s: ", sc->sc_dev.dv_xname); 1647 if (ic->ic_opmode == IEEE80211_M_STA) 1648 printf("associated "); 1649 else 1650 printf("synchronized "); 1651 printf("with %s ssid ", ether_sprintf(ni->ni_bssid)); 1652 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen); 1653 printf(" channel %u start %uMb\n", 1654 sc->sc_buf.sc_status.an_cur_channel, 1655 sc->sc_buf.sc_status.an_current_tx_rate/2); 1656 } 1657 break; 1658 1659 default: 1660 break; 1661 } 1662 ic->ic_state = nstate; 1663 /* skip standard ieee80211 handling */ 1664 return 0; 1665 } 1666 1667 int 1668 an_detach(struct an_softc *sc) 1669 { 1670 struct ifnet *ifp = &sc->sc_ic.ic_if; 1671 int s; 1672 1673 if (!sc->sc_attached) 1674 return 0; 1675 1676 s = splnet(); 1677 sc->sc_invalid = 1; 1678 an_stop(ifp, 1); 1679 ifmedia_delete_instance(&sc->sc_ic.ic_media, IFM_INST_ANY); 1680 ieee80211_ifdetach(ifp); 1681 if_detach(ifp); 1682 splx(s); 1683 return 0; 1684 } 1685 1686