if_ipw.c revision 1.8
1/* $Id: if_ipw.c,v 1.8 2004/10/27 21:17:18 damien Exp $ */ 2 3/*- 4 * Copyright (c) 2004 5 * Damien Bergamini <damien.bergamini@free.fr>. 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 unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30/*- 31 * Intel(R) PRO/Wireless 2100 MiniPCI driver 32 * www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm 33 */ 34 35#include "bpfilter.h" 36 37#include <sys/param.h> 38#include <sys/sockio.h> 39#include <sys/sysctl.h> 40#include <sys/mbuf.h> 41#include <sys/kernel.h> 42#include <sys/socket.h> 43#include <sys/systm.h> 44#include <sys/malloc.h> 45#include <sys/conf.h> 46 47#include <machine/bus.h> 48#include <machine/endian.h> 49#include <machine/intr.h> 50 51#include <dev/pci/pcireg.h> 52#include <dev/pci/pcivar.h> 53#include <dev/pci/pcidevs.h> 54 55#if NBPFILTER > 0 56#include <net/bpf.h> 57#endif 58#include <net/if.h> 59#include <net/if_arp.h> 60#include <net/if_dl.h> 61#include <net/if_media.h> 62#include <net/if_types.h> 63 64#include <netinet/in.h> 65#include <netinet/in_systm.h> 66#include <netinet/in_var.h> 67#include <netinet/if_ether.h> 68#include <netinet/ip.h> 69 70#include <net80211/ieee80211_var.h> 71#include <net80211/ieee80211_radiotap.h> 72 73#include <dev/pci/if_ipwreg.h> 74#include <dev/pci/if_ipwvar.h> 75 76static const struct ieee80211_rateset ipw_rateset_11b = 77 { 4, { 2, 4, 11, 22 } }; 78 79int ipw_match(struct device *, void *, void *); 80void ipw_attach(struct device *, struct device *, void *); 81int ipw_detach(struct device *, int); 82int ipw_media_change(struct ifnet *); 83int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int); 84void ipw_command_intr(struct ipw_softc *, struct ipw_soft_buf *); 85void ipw_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); 86void ipw_data_intr(struct ipw_softc *, struct ipw_status *, 87 struct ipw_soft_bd *, struct ipw_soft_buf *); 88void ipw_notification_intr(struct ipw_softc *, struct ipw_soft_buf *); 89void ipw_rx_intr(struct ipw_softc *); 90void ipw_release_sbd(struct ipw_softc *, struct ipw_soft_bd *); 91void ipw_tx_intr(struct ipw_softc *); 92int ipw_intr(void *); 93int ipw_cmd(struct ipw_softc *, u_int32_t, void *, u_int32_t); 94int ipw_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *); 95void ipw_start(struct ifnet *); 96void ipw_watchdog(struct ifnet *); 97int ipw_get_table1(struct ipw_softc *, u_int32_t *); 98int ipw_get_radio(struct ipw_softc *, int *); 99int ipw_ioctl(struct ifnet *, u_long, caddr_t); 100u_int32_t ipw_read_table1(struct ipw_softc *, u_int32_t); 101void ipw_write_table1(struct ipw_softc *, u_int32_t, u_int32_t); 102int ipw_read_table2(struct ipw_softc *, u_int32_t, void *, u_int32_t *); 103int ipw_tx_init(struct ipw_softc *); 104void ipw_tx_stop(struct ipw_softc *); 105int ipw_rx_init(struct ipw_softc *); 106void ipw_rx_stop(struct ipw_softc *); 107void ipw_reset(struct ipw_softc *); 108int ipw_clock_sync(struct ipw_softc *); 109int ipw_load_ucode(struct ipw_softc *, u_char *, int); 110int ipw_load_firmware(struct ipw_softc *, u_char *, int); 111int ipw_firmware_init(struct ipw_softc *, u_char *); 112int ipw_config(struct ipw_softc *); 113int ipw_init(struct ifnet *); 114void ipw_stop(struct ifnet *, int); 115void ipw_read_mem_1(struct ipw_softc *, bus_size_t, u_int8_t *, bus_size_t); 116void ipw_write_mem_1(struct ipw_softc *, bus_size_t, u_int8_t *, bus_size_t); 117void ipw_zero_mem_4(struct ipw_softc *, bus_size_t, bus_size_t); 118 119static __inline u_int8_t MEM_READ_1(struct ipw_softc *sc, u_int32_t addr) 120{ 121 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, addr); 122 return CSR_READ_1(sc, IPW_CSR_INDIRECT_DATA); 123} 124 125static __inline u_int32_t MEM_READ_4(struct ipw_softc *sc, u_int32_t addr) 126{ 127 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, addr); 128 return CSR_READ_4(sc, IPW_CSR_INDIRECT_DATA); 129} 130 131#ifdef IPW_DEBUG 132#define DPRINTF(x) if (ipw_debug > 0) printf x 133#define DPRINTFN(n, x) if (ipw_debug >= (n)) printf x 134int ipw_debug = 0; 135#else 136#define DPRINTF(x) 137#define DPRINTFN(n, x) 138#endif 139 140struct cfattach ipw_ca = { 141 sizeof (struct ipw_softc), ipw_match, ipw_attach, ipw_detach 142}; 143 144int 145ipw_match(struct device *parent, void *match, void *aux) 146{ 147 struct pci_attach_args *pa = aux; 148 149 if (PCI_VENDOR (pa->pa_id) == PCI_VENDOR_INTEL && 150 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_2100_3B) 151 return 1; 152 153 return 0; 154} 155 156/* Base Address Register */ 157#define IPW_PCI_BAR0 0x10 158 159void 160ipw_attach(struct device *parent, struct device *self, void *aux) 161{ 162 struct ipw_softc *sc = (struct ipw_softc *)self; 163 struct ieee80211com *ic = &sc->sc_ic; 164 struct ifnet *ifp = &ic->ic_if; 165 struct pci_attach_args *pa = aux; 166 const char *intrstr; 167 bus_space_tag_t memt; 168 bus_space_handle_t memh; 169 bus_addr_t base; 170 pci_intr_handle_t ih; 171 u_int32_t data; 172 int error, i; 173 174 sc->sc_pct = pa->pa_pc; 175 176 /* enable bus-mastering */ 177 data = pci_conf_read(sc->sc_pct, pa->pa_tag, PCI_COMMAND_STATUS_REG); 178 data |= PCI_COMMAND_MASTER_ENABLE; 179 pci_conf_write(sc->sc_pct, pa->pa_tag, PCI_COMMAND_STATUS_REG, data); 180 181 /* map the register window */ 182 error = pci_mapreg_map(pa, IPW_PCI_BAR0, PCI_MAPREG_TYPE_MEM | 183 PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &base, &sc->sc_sz, 0); 184 if (error != 0) { 185 printf(": could not map memory space\n"); 186 return; 187 } 188 189 sc->sc_st = memt; 190 sc->sc_sh = memh; 191 sc->sc_dmat = pa->pa_dmat; 192 193 /* disable interrupts */ 194 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0); 195 196 if (pci_intr_map(pa, &ih) != 0) { 197 printf(": could not map interrupt\n"); 198 return; 199 } 200 201 intrstr = pci_intr_string(sc->sc_pct, ih); 202 sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, ipw_intr, sc, 203 sc->sc_dev.dv_xname); 204 if (sc->sc_ih == NULL) { 205 printf(": could not establish interrupt"); 206 if (intrstr != NULL) 207 printf(" at %s", intrstr); 208 printf("\n"); 209 return; 210 } 211 printf(": %s\n", intrstr); 212 213 ic->ic_phytype = IEEE80211_T_DS; 214 ic->ic_opmode = IEEE80211_M_STA; 215 ic->ic_state = IEEE80211_S_INIT; 216 217 /* set device capabilities */ 218 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_MONITOR | 219 IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | IEEE80211_C_WEP; 220 221 /* set supported .11b rates */ 222 ic->ic_sup_rates[IEEE80211_MODE_11B] = ipw_rateset_11b; 223 224 /* set supported .11b channels (1 through 14) */ 225 for (i = 1; i <= 14; i++) { 226 ic->ic_channels[i].ic_freq = 227 ieee80211_ieee2mhz(i, IEEE80211_CHAN_B); 228 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B; 229 } 230 231 /* default to authmode OPEN */ 232 sc->authmode = IEEE80211_AUTH_OPEN; 233 234 /* IBSS channel undefined for now */ 235 ic->ic_ibss_chan = &ic->ic_channels[0]; 236 237 ifp->if_softc = sc; 238 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 239 ifp->if_init = ipw_init; 240 ifp->if_ioctl = ipw_ioctl; 241 ifp->if_start = ipw_start; 242 ifp->if_watchdog = ipw_watchdog; 243 IFQ_SET_READY(&ifp->if_snd); 244 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 245 246 if_attach(ifp); 247 ieee80211_ifattach(ifp); 248 /* override state transition machine */ 249 sc->sc_newstate = ic->ic_newstate; 250 ic->ic_newstate = ipw_newstate; 251 ieee80211_media_init(ifp, ipw_media_change, ieee80211_media_status); 252 253#if NBPFILTER > 0 254 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, 255 sizeof (struct ieee80211_frame) + 64); 256 257 sc->sc_rxtap_len = sizeof sc->sc_rxtapu; 258 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 259 sc->sc_rxtap.wr_ihdr.it_present = htole32(IPW_RX_RADIOTAP_PRESENT); 260 261 sc->sc_txtap_len = sizeof sc->sc_txtapu; 262 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 263 sc->sc_txtap.wt_ihdr.it_present = htole32(IPW_TX_RADIOTAP_PRESENT); 264#endif 265} 266 267int 268ipw_detach(struct device* self, int flags) 269{ 270 struct ipw_softc *sc = (struct ipw_softc *)self; 271 struct ifnet *ifp = &sc->sc_ic.ic_if; 272 273 ipw_reset(sc); 274 275#if NBPFILTER > 0 276 bpfdetach(ifp); 277#endif 278 ieee80211_ifdetach(ifp); 279 if_detach(ifp); 280 281 if (sc->sc_ih != NULL) { 282 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 283 sc->sc_ih = NULL; 284 } 285 286 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz); 287 288 return 0; 289} 290 291int 292ipw_media_change(struct ifnet *ifp) 293{ 294 int error; 295 296 error = ieee80211_media_change(ifp); 297 if (error != ENETRESET) 298 return error; 299 300 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 301 ipw_init(ifp); 302 303 return 0; 304} 305 306int 307ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 308{ 309 struct ipw_softc *sc = ic->ic_softc; 310 struct ieee80211_node *ni = ic->ic_bss; 311 u_int32_t val, len; 312 313 switch (nstate) { 314 case IEEE80211_S_RUN: 315 len = IEEE80211_NWID_LEN; 316 ipw_read_table2(sc, IPW_INFO_CURRENT_SSID, ni->ni_essid, &len); 317 ni->ni_esslen = len; 318 319 val = ipw_read_table1(sc, IPW_INFO_CURRENT_CHANNEL); 320 ni->ni_chan = &ic->ic_channels[val]; 321 322 DELAY(100); /* firmware needs a short delay here */ 323 324 len = IEEE80211_ADDR_LEN; 325 ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, ni->ni_bssid, &len); 326 break; 327 328 case IEEE80211_S_INIT: 329 case IEEE80211_S_SCAN: 330 case IEEE80211_S_AUTH: 331 case IEEE80211_S_ASSOC: 332 break; 333 } 334 335 ic->ic_state = nstate; 336 return 0; 337} 338 339void 340ipw_command_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) 341{ 342 struct ipw_cmd *cmd; 343 344 bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, sizeof (struct ipw_cmd), 345 BUS_DMASYNC_POSTREAD); 346 347 cmd = mtod(sbuf->m, struct ipw_cmd *); 348 349 DPRINTFN(2, ("RX!CMD!%u!%u!%u!%u!%u\n", 350 letoh32(cmd->type), letoh32(cmd->subtype), letoh32(cmd->seq), 351 letoh32(cmd->len), letoh32(cmd->status))); 352 353 /* 354 * Wake up processes waiting for command ack. In the case of the 355 * IPW_CMD_DISABLE command, wake up the process only when the adapter 356 * enters the IPW_STATE_DISABLED state. This is notified in 357 * ipw_newstate_intr(). 358 */ 359 if (letoh32(cmd->type) != IPW_CMD_DISABLE) 360 wakeup(sc->cmd); 361} 362 363void 364ipw_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) 365{ 366 struct ieee80211com *ic = &sc->sc_ic; 367 u_int32_t state; 368 369 bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, sizeof state, 370 BUS_DMASYNC_POSTREAD); 371 372 state = letoh32(*mtod(sbuf->m, u_int32_t *)); 373 374 DPRINTFN(2, ("RX!NEWSTATE!%u\n", state)); 375 376 switch (state) { 377 case IPW_STATE_ASSOCIATED: 378 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 379 break; 380 381 case IPW_STATE_SCANNING: 382 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 383 break; 384 385 case IPW_STATE_ASSOCIATION_LOST: 386 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 387 break; 388 389 case IPW_STATE_DISABLED: 390 wakeup(sc->cmd); 391 break; 392 393 case IPW_STATE_RADIO_DISABLED: 394 /* XXX should turn the interface down */ 395 break; 396 } 397} 398 399void 400ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status, 401 struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf) 402{ 403 struct ieee80211com *ic = &sc->sc_ic; 404 struct ifnet *ifp = &ic->ic_if; 405 struct mbuf *m; 406 struct ieee80211_frame *wh; 407 struct ieee80211_node *ni; 408 int error; 409 410 DPRINTFN(5, ("RX!DATA!%u!%u\n", letoh32(status->len), status->rssi)); 411 412 bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, letoh32(status->len), 413 BUS_DMASYNC_POSTREAD); 414 415 bus_dmamap_unload(sc->sc_dmat, sbuf->map); 416 417 /* Finalize mbuf */ 418 m = sbuf->m; 419 m->m_pkthdr.rcvif = ifp; 420 m->m_pkthdr.len = m->m_len = letoh32(status->len); 421 422#if NBPFILTER > 0 423 if (sc->sc_drvbpf != NULL) { 424 struct mbuf mb; 425 struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap; 426 427 tap->wr_flags = 0; 428 tap->wr_antsignal = status->rssi; 429 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 430 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 431 432 M_DUP_PKTHDR(&mb, m); 433 mb.m_data = (caddr_t)tap; 434 mb.m_len = sc->sc_rxtap_len; 435 mb.m_next = m; 436 mb.m_pkthdr.len += mb.m_len; 437 bpf_mtap(sc->sc_drvbpf, &mb); 438 } 439#endif 440 441 wh = mtod(m, struct ieee80211_frame *); 442 443 ni = ieee80211_find_rxnode(ic, wh); 444 445 /* Send it up to the upper layer */ 446 ieee80211_input(ifp, m, ni, status->rssi, 0); 447 448 if (ni == ic->ic_bss) 449 ieee80211_unref_node(&ni); 450 else 451 ieee80211_free_node(ic, ni); 452 453 MGETHDR(m, M_DONTWAIT, MT_DATA); 454 if (m == NULL) { 455 printf("%s: could not allocate rx mbuf\n", 456 sc->sc_dev.dv_xname); 457 return; 458 } 459 MCLGET(m, M_DONTWAIT); 460 if (!(m->m_flags & M_EXT)) { 461 m_freem(m); 462 printf("%s: could not allocate rx mbuf cluster\n", 463 sc->sc_dev.dv_xname); 464 return; 465 } 466 467 error = bus_dmamap_load(sc->sc_dmat, sbuf->map, mtod(m, void *), 468 MCLBYTES, NULL, BUS_DMA_NOWAIT); 469 if (error != 0) { 470 printf("%s: could not map rxbuf dma memory\n", 471 sc->sc_dev.dv_xname); 472 m_freem(m); 473 return; 474 } 475 476 sbuf->m = m; 477 sbd->bd->physaddr = htole32(sbuf->map->dm_segs[0].ds_addr); 478} 479 480void 481ipw_notification_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) 482{ 483 DPRINTFN(2, ("RX!NOTIFICATION\n")); 484} 485 486void 487ipw_rx_intr(struct ipw_softc *sc) 488{ 489 struct ipw_status *status; 490 struct ipw_soft_bd *sbd; 491 struct ipw_soft_buf *sbuf; 492 u_int32_t r, i; 493 494 r = CSR_READ_4(sc, IPW_CSR_RX_READ_INDEX); 495 496 for (i = (sc->rxcur + 1) % IPW_NRBD; i != r; i = (i + 1) % IPW_NRBD) { 497 498 bus_dmamap_sync(sc->sc_dmat, sc->rbd_map, 499 i * sizeof (struct ipw_bd), sizeof (struct ipw_bd), 500 BUS_DMASYNC_POSTREAD); 501 502 bus_dmamap_sync(sc->sc_dmat, sc->status_map, 503 i * sizeof (struct ipw_status), sizeof (struct ipw_status), 504 BUS_DMASYNC_POSTREAD); 505 506 status = &sc->status_list[i]; 507 sbd = &sc->srbd_list[i]; 508 sbuf = sbd->priv; 509 510 switch (letoh16(status->code) & 0xf) { 511 case IPW_STATUS_CODE_COMMAND: 512 ipw_command_intr(sc, sbuf); 513 break; 514 515 case IPW_STATUS_CODE_NEWSTATE: 516 ipw_newstate_intr(sc, sbuf); 517 break; 518 519 case IPW_STATUS_CODE_DATA_802_3: 520 case IPW_STATUS_CODE_DATA_802_11: 521 ipw_data_intr(sc, status, sbd, sbuf); 522 break; 523 524 case IPW_STATUS_CODE_NOTIFICATION: 525 ipw_notification_intr(sc, sbuf); 526 break; 527 528 default: 529 printf("%s: unknown status code %u\n", 530 sc->sc_dev.dv_xname, letoh16(status->code)); 531 } 532 sbd->bd->flags = 0; 533 534 bus_dmamap_sync(sc->sc_dmat, sc->rbd_map, 535 i * sizeof (struct ipw_bd), sizeof (struct ipw_bd), 536 BUS_DMASYNC_PREWRITE); 537 } 538 539 /* Tell the firmware what we have processed */ 540 sc->rxcur = (r == 0) ? IPW_NRBD - 1 : r - 1; 541 CSR_WRITE_4(sc, IPW_CSR_RX_WRITE_INDEX, sc->rxcur); 542} 543 544void 545ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd) 546{ 547 struct ieee80211com *ic; 548 struct ipw_soft_hdr *shdr; 549 struct ipw_soft_buf *sbuf; 550 551 switch (sbd->type) { 552 case IPW_SBD_TYPE_COMMAND: 553 bus_dmamap_unload(sc->sc_dmat, sc->cmd_map); 554 break; 555 556 case IPW_SBD_TYPE_HEADER: 557 shdr = sbd->priv; 558 bus_dmamap_unload(sc->sc_dmat, shdr->map); 559 TAILQ_INSERT_TAIL(&sc->sc_free_shdr, shdr, next); 560 break; 561 562 case IPW_SBD_TYPE_DATA: 563 ic = &sc->sc_ic; 564 sbuf = sbd->priv; 565 bus_dmamap_unload(sc->sc_dmat, sbuf->map); 566 m_freem(sbuf->m); 567 if (sbuf->ni != NULL && sbuf->ni != ic->ic_bss) 568 ieee80211_free_node(ic, sbuf->ni); 569 /* kill watchdog timer */ 570 sc->sc_tx_timer = 0; 571 TAILQ_INSERT_TAIL(&sc->sc_free_sbuf, sbuf, next); 572 break; 573 } 574 sbd->type = IPW_SBD_TYPE_NOASSOC; 575} 576 577void 578ipw_tx_intr(struct ipw_softc *sc) 579{ 580 struct ifnet *ifp = &sc->sc_ic.ic_if; 581 u_int32_t r, i; 582 583 r = CSR_READ_4(sc, IPW_CSR_TX_READ_INDEX); 584 585 for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) 586 ipw_release_sbd(sc, &sc->stbd_list[i]); 587 588 /* Remember what the firmware has processed */ 589 sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; 590 591 /* Call start() since some buffer descriptors have been released */ 592 ifp->if_flags &= ~IFF_OACTIVE; 593 (*ifp->if_start)(ifp); 594} 595 596int 597ipw_intr(void *arg) 598{ 599 struct ipw_softc *sc = arg; 600 u_int32_t r; 601 602 if ((r = CSR_READ_4(sc, IPW_CSR_INTR)) == 0) 603 return 0; 604 605 /* Disable interrupts */ 606 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0); 607 608 DPRINTFN(8, ("INTR!0x%08x\n", r)); 609 610 if (r & IPW_INTR_RX_TRANSFER) 611 ipw_rx_intr(sc); 612 613 if (r & IPW_INTR_TX_TRANSFER) 614 ipw_tx_intr(sc); 615 616 if (r & IPW_INTR_FW_INIT_DONE) { 617 if (!(r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR))) 618 wakeup(sc); 619 } 620 621 /* Acknowledge interrupts */ 622 CSR_WRITE_4(sc, IPW_CSR_INTR, r); 623 624 /* Re-enable interrupts */ 625 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK); 626 627 return 0; 628} 629 630int 631ipw_cmd(struct ipw_softc *sc, u_int32_t type, void *data, u_int32_t len) 632{ 633 struct ipw_soft_bd *sbd; 634 int error; 635 636 sbd = &sc->stbd_list[sc->txcur]; 637 638 error = bus_dmamap_load(sc->sc_dmat, sc->cmd_map, sc->cmd, 639 sizeof (struct ipw_cmd), NULL, BUS_DMA_NOWAIT); 640 if (error != 0) { 641 printf("%s: could not map cmd dma memory\n", 642 sc->sc_dev.dv_xname); 643 return error; 644 } 645 646 sc->cmd->type = htole32(type); 647 sc->cmd->subtype = htole32(0); 648 sc->cmd->len = htole32(len); 649 sc->cmd->seq = htole32(0); 650 if (data != NULL) 651 bcopy(data, sc->cmd->data, len); 652 653 sbd->type = IPW_SBD_TYPE_COMMAND; 654 sbd->bd->physaddr = htole32(sc->cmd_map->dm_segs[0].ds_addr); 655 sbd->bd->len = htole32(sizeof (struct ipw_cmd)); 656 sbd->bd->nfrag = 1; 657 sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_COMMAND | 658 IPW_BD_FLAG_TX_LAST_FRAGMENT; 659 660 bus_dmamap_sync(sc->sc_dmat, sc->cmd_map, 0, sizeof (struct ipw_cmd), 661 BUS_DMASYNC_PREWRITE); 662 663 bus_dmamap_sync(sc->sc_dmat, sc->tbd_map, 664 sc->txcur * sizeof (struct ipw_bd), sizeof (struct ipw_bd), 665 BUS_DMASYNC_PREWRITE); 666 667 sc->txcur = (sc->txcur + 1) % IPW_NTBD; 668 CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, sc->txcur); 669 670 DPRINTFN(2, ("TX!CMD!%u!%u!%u!%u\n", type, 0, 0, len)); 671 672 /* Wait at most one second for command to complete */ 673 return tsleep(sc->cmd, 0, "ipwcmd", hz); 674} 675 676int 677ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni) 678{ 679 struct ipw_softc *sc = ifp->if_softc; 680 struct ieee80211com *ic = &sc->sc_ic; 681 struct ieee80211_frame *wh; 682 struct ipw_soft_bd *sbd; 683 struct ipw_soft_hdr *shdr; 684 struct ipw_soft_buf *sbuf; 685 int error, i; 686 687 if (ic->ic_flags & IEEE80211_F_WEPON) { 688 m = ieee80211_wep_crypt(ifp, m, 1); 689 if (m == NULL) 690 return ENOBUFS; 691 } 692 693#if NBPFILTER > 0 694 if (sc->sc_drvbpf != NULL) { 695 struct mbuf mb; 696 struct ipw_tx_radiotap_header *tap = &sc->sc_txtap; 697 698 tap->wt_flags = 0; 699 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 700 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 701 702 M_DUP_PKTHDR(&mb, m); 703 mb.m_data = (caddr_t)tap; 704 mb.m_len = sc->sc_txtap_len; 705 mb.m_next = m; 706 mb.m_pkthdr.len += mb.m_len; 707 bpf_mtap(sc->sc_drvbpf, &mb); 708 } 709#endif 710 711 wh = mtod(m, struct ieee80211_frame *); 712 713 shdr = TAILQ_FIRST(&sc->sc_free_shdr); 714 sbuf = TAILQ_FIRST(&sc->sc_free_sbuf); 715 716 shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND); 717 shdr->hdr.subtype = htole32(0); 718 shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0; 719 shdr->hdr.encrypt = 0; 720 shdr->hdr.keyidx = 0; 721 shdr->hdr.keysz = 0; 722 shdr->hdr.fragmentsz = htole16(0); 723 IEEE80211_ADDR_COPY(shdr->hdr.src_addr, wh->i_addr2); 724 if (ic->ic_opmode == IEEE80211_M_STA) 725 IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr3); 726 else 727 IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr1); 728 729 /* trim IEEE802.11 header */ 730 m_adj(m, sizeof (struct ieee80211_frame)); 731 732 /* 733 * We need to map the mbuf first to know how many buffer descriptors 734 * are needed for this transfer. 735 */ 736 error = bus_dmamap_load_mbuf(sc->sc_dmat, sbuf->map, m, BUS_DMA_NOWAIT); 737 if (error != 0) { 738 printf("%s: could not map mbuf (error %d)\n", 739 sc->sc_dev.dv_xname, error); 740 m_freem(m); 741 return error; 742 } 743 744 error = bus_dmamap_load(sc->sc_dmat, shdr->map, &shdr->hdr, 745 sizeof (struct ipw_hdr), NULL, BUS_DMA_NOWAIT); 746 if (error != 0) { 747 printf("%s: could not map header (error %d)\n", 748 sc->sc_dev.dv_xname, error); 749 bus_dmamap_unload(sc->sc_dmat, sbuf->map); 750 m_freem(m); 751 return error; 752 } 753 754 TAILQ_REMOVE(&sc->sc_free_sbuf, sbuf, next); 755 TAILQ_REMOVE(&sc->sc_free_shdr, shdr, next); 756 757 sbd = &sc->stbd_list[sc->txcur]; 758 sbd->type = IPW_SBD_TYPE_HEADER; 759 sbd->priv = shdr; 760 sbd->bd->physaddr = htole32(shdr->map->dm_segs[0].ds_addr); 761 sbd->bd->len = htole32(sizeof (struct ipw_hdr)); 762 sbd->bd->nfrag = 1 + sbuf->map->dm_nsegs; 763 sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3 | 764 IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT; 765 766 DPRINTFN(5, ("TX!HDR!%u!%u!%u!%u", shdr->hdr.type, shdr->hdr.subtype, 767 shdr->hdr.encrypted, shdr->hdr.encrypt)); 768 DPRINTFN(5, ("!%s", ether_sprintf(shdr->hdr.src_addr))); 769 DPRINTFN(5, ("!%s\n", ether_sprintf(shdr->hdr.dst_addr))); 770 771 bus_dmamap_sync(sc->sc_dmat, sc->tbd_map, 772 sc->txcur * sizeof (struct ipw_bd), 773 sizeof (struct ipw_bd), BUS_DMASYNC_PREWRITE); 774 775 sc->txcur = (sc->txcur + 1) % IPW_NTBD; 776 777 sbuf->m = m; 778 sbuf->ni = ni; 779 780 for (i = 0; i < sbuf->map->dm_nsegs; i++) { 781 sbd = &sc->stbd_list[sc->txcur]; 782 sbd->bd->physaddr = htole32(sbuf->map->dm_segs[i].ds_addr); 783 sbd->bd->len = htole32(sbuf->map->dm_segs[i].ds_len); 784 sbd->bd->nfrag = 0; /* used only in first bd */ 785 sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3; 786 if (i == sbuf->map->dm_nsegs - 1) { 787 sbd->type = IPW_SBD_TYPE_DATA; 788 sbd->priv = sbuf; 789 sbd->bd->flags |= IPW_BD_FLAG_TX_LAST_FRAGMENT; 790 } else { 791 sbd->type = IPW_SBD_TYPE_NOASSOC; 792 sbd->bd->flags |= IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT; 793 } 794 795 DPRINTFN(5, ("TX!FRAG!%d!%d\n", i, 796 sbuf->map->dm_segs[i].ds_len)); 797 798 bus_dmamap_sync(sc->sc_dmat, sc->tbd_map, 799 sc->txcur * sizeof (struct ipw_bd), 800 sizeof (struct ipw_bd), BUS_DMASYNC_PREWRITE); 801 802 sc->txcur = (sc->txcur + 1) % IPW_NTBD; 803 } 804 805 bus_dmamap_sync(sc->sc_dmat, shdr->map, 0, sizeof (struct ipw_hdr), 806 BUS_DMASYNC_PREWRITE); 807 808 bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, MCLBYTES, 809 BUS_DMASYNC_PREWRITE); 810 811 /* Inform firmware about this new packet */ 812 CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, sc->txcur); 813 814 return 0; 815} 816 817void 818ipw_start(struct ifnet *ifp) 819{ 820 struct ipw_softc *sc = ifp->if_softc; 821 struct ieee80211com *ic = &sc->sc_ic; 822 struct mbuf *m; 823 struct ieee80211_node *ni; 824 825 for (;;) { 826 IF_DEQUEUE(&ifp->if_snd, m); 827 if (m == NULL) 828 break; 829 830#if NBPFILTER > 0 831 if (ifp->if_bpf != NULL) 832 bpf_mtap(ifp->if_bpf, m); 833#endif 834 835 m = ieee80211_encap(ifp, m, &ni); 836 if (m == NULL) 837 continue; 838 839#if NBPFILTER > 0 840 if (ic->ic_rawbpf != NULL) 841 bpf_mtap(ic->ic_rawbpf, m); 842#endif 843 844 if (ipw_tx_start(ifp, m, ni) != 0) { 845 if (ni != NULL && ni != ic->ic_bss) 846 ieee80211_free_node(ic, ni); 847 break; 848 } 849 850 /* start watchdog timer */ 851 sc->sc_tx_timer = 5; 852 ifp->if_timer = 1; 853 } 854} 855 856void 857ipw_watchdog(struct ifnet *ifp) 858{ 859 struct ipw_softc *sc = ifp->if_softc; 860 861 ifp->if_timer = 0; 862 863 if (sc->sc_tx_timer > 0) { 864 if (--sc->sc_tx_timer == 0) { 865 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 866#ifdef notyet 867 ipw_init(ifp); 868#endif 869 return; 870 } 871 ifp->if_timer = 1; 872 } 873 874 ieee80211_watchdog(ifp); 875} 876 877int 878ipw_get_table1(struct ipw_softc *sc, u_int32_t *tbl) 879{ 880 u_int32_t i, size, buf[256]; 881 882 if (!(sc->flags & IPW_FLAG_FW_INITED)) 883 return ENOTTY; 884 885 CSR_WRITE_4(sc, IPW_CSR_AUTOINC_ADDR, sc->table1_base); 886 887 size = CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA); 888 for (i = 1; i < size; i++) 889 buf[i] = MEM_READ_4(sc, CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA)); 890 891 return copyout(buf, tbl, size * sizeof (u_int32_t)); 892} 893 894int 895ipw_get_radio(struct ipw_softc *sc, int *ret) 896{ 897 int val; 898 899 if (!(sc->flags & IPW_FLAG_FW_INITED)) 900 return ENOTTY; 901 902 val = (CSR_READ_4(sc, IPW_CSR_IO) & IPW_IO_RADIO_DISABLED) ? 0 : 1; 903 return copyout(&val, ret, sizeof val); 904} 905 906int 907ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 908{ 909 struct ipw_softc *sc = ifp->if_softc; 910 struct ifreq *ifr; 911 struct ifaddr *ifa; 912 int s, error = 0; 913 914 s = splnet(); 915 916 switch (cmd) { 917 case SIOCSIFADDR: 918 ifa = (struct ifaddr *) data; 919 ifp->if_flags |= IFF_UP; 920 switch (ifa->ifa_addr->sa_family) { 921#ifdef INET 922 case AF_INET: 923 arp_ifinit(&sc->sc_ic.ic_ac, ifa); 924 ipw_init(ifp); 925 break; 926#endif 927 default: 928 ipw_init(ifp); 929 } 930 break; 931 932 case SIOCSIFFLAGS: 933 if (ifp->if_flags & IFF_UP) { 934 if (!(ifp->if_flags & IFF_RUNNING)) 935 ipw_init(ifp); 936 } else { 937 if (ifp->if_flags & IFF_RUNNING) 938 ipw_stop(ifp, 1); 939 } 940 break; 941 942 case SIOCGTABLE1: 943 ifr = (struct ifreq *)data; 944 error = ipw_get_table1(sc, (u_int32_t *)ifr->ifr_data); 945 break; 946 947 case SIOCGRADIO: 948 ifr = (struct ifreq *)data; 949 error = ipw_get_radio(sc, (int *)ifr->ifr_data); 950 break; 951 952 case SIOCSLOADFW: 953 /* only super-user can do that! */ 954 if ((error = suser(curproc, 0)) != 0) 955 break; 956 957 ifr = (struct ifreq *)data; 958 error = ipw_firmware_init(sc, (u_char *)ifr->ifr_data); 959 break; 960 961 case SIOCSKILLFW: 962 /* only super-user can do that! */ 963 if ((error = suser(curproc, 0)) != 0) 964 break; 965 966 ipw_reset(sc); 967 break; 968 969 case SIOCG80211AUTH: 970 ((struct ieee80211_auth *)data)->i_authtype = sc->authmode; 971 break; 972 973 case SIOCS80211AUTH: 974 /* only super-user can do that! */ 975 if ((error = suser(curproc, 0)) != 0) 976 break; 977 978 sc->authmode = ((struct ieee80211_auth *)data)->i_authtype; 979 break; 980 981 default: 982 error = ieee80211_ioctl(ifp, cmd, data); 983 } 984 985 if (error == ENETRESET && cmd != SIOCADDMULTI) { 986 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 987 (IFF_UP | IFF_RUNNING)) 988 ipw_init(ifp); 989 error = 0; 990 } 991 992 splx(s); 993 return error; 994} 995 996u_int32_t 997ipw_read_table1(struct ipw_softc *sc, u_int32_t off) 998{ 999 return MEM_READ_4(sc, MEM_READ_4(sc, sc->table1_base + off)); 1000} 1001 1002void 1003ipw_write_table1(struct ipw_softc *sc, u_int32_t off, u_int32_t info) 1004{ 1005 MEM_WRITE_4(sc, MEM_READ_4(sc, sc->table1_base + off), info); 1006} 1007 1008int 1009ipw_read_table2(struct ipw_softc *sc, u_int32_t off, void *buf, u_int32_t *len) 1010{ 1011 u_int32_t addr, info; 1012 u_int16_t count, size; 1013 u_int32_t total; 1014 1015 /* addr[4] + count[2] + size[2] */ 1016 addr = MEM_READ_4(sc, sc->table2_base + off); 1017 info = MEM_READ_4(sc, sc->table2_base + off + 4); 1018 1019 count = info >> 16; 1020 size = info & 0xffff; 1021 total = count * size; 1022 1023 if (total > *len) { 1024 *len = total; 1025 return EINVAL; 1026 } 1027 1028 *len = total; 1029 ipw_read_mem_1(sc, addr, buf, total); 1030 1031 return 0; 1032} 1033 1034int 1035ipw_tx_init(struct ipw_softc *sc) 1036{ 1037 char *errmsg; 1038 struct ipw_bd *bd; 1039 struct ipw_soft_bd *sbd; 1040 struct ipw_soft_hdr *shdr; 1041 struct ipw_soft_buf *sbuf; 1042 int error, i, nsegs; 1043 1044 /* Allocate transmission buffer descriptors */ 1045 error = bus_dmamap_create(sc->sc_dmat, IPW_TBD_SZ, 1, IPW_TBD_SZ, 0, 1046 BUS_DMA_NOWAIT, &sc->tbd_map); 1047 if (error != 0) { 1048 errmsg = "could not create tbd dma map"; 1049 goto fail; 1050 } 1051 1052 error = bus_dmamem_alloc(sc->sc_dmat, IPW_TBD_SZ, PAGE_SIZE, 0, 1053 &sc->tbd_seg, 1, &nsegs, BUS_DMA_NOWAIT); 1054 if (error != 0) { 1055 errmsg = "could not allocate tbd dma memory"; 1056 goto fail; 1057 } 1058 1059 error = bus_dmamem_map(sc->sc_dmat, &sc->tbd_seg, nsegs, IPW_TBD_SZ, 1060 (caddr_t *)&sc->tbd_list, BUS_DMA_NOWAIT); 1061 if (error != 0) { 1062 errmsg = "could not map tbd dma memory"; 1063 goto fail; 1064 } 1065 1066 error = bus_dmamap_load(sc->sc_dmat, sc->tbd_map, sc->tbd_list, 1067 IPW_TBD_SZ, NULL, BUS_DMA_NOWAIT); 1068 if (error != 0) { 1069 errmsg = "could not load tbd dma memory"; 1070 goto fail; 1071 } 1072 1073 sc->stbd_list = malloc(IPW_NTBD * sizeof (struct ipw_soft_bd), 1074 M_DEVBUF, M_NOWAIT); 1075 if (sc->stbd_list == NULL) { 1076 errmsg = "could not allocate soft tbd"; 1077 error = ENOMEM; 1078 goto fail; 1079 } 1080 sbd = sc->stbd_list; 1081 bd = sc->tbd_list; 1082 for (i = 0; i < IPW_NTBD; i++, sbd++, bd++) { 1083 sbd->type = IPW_SBD_TYPE_NOASSOC; 1084 sbd->bd = bd; 1085 } 1086 1087 CSR_WRITE_4(sc, IPW_CSR_TX_BD_BASE, sc->tbd_map->dm_segs[0].ds_addr); 1088 CSR_WRITE_4(sc, IPW_CSR_TX_BD_SIZE, IPW_NTBD); 1089 CSR_WRITE_4(sc, IPW_CSR_TX_READ_INDEX, 0); 1090 CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, 0); 1091 sc->txold = IPW_NTBD - 1; /* latest bd index ack'ed by firmware */ 1092 sc->txcur = 0; /* bd index to write to */ 1093 1094 /* Allocate a DMA-able command */ 1095 error = bus_dmamap_create(sc->sc_dmat, sizeof (struct ipw_cmd), 1, 1096 sizeof (struct ipw_cmd), 0, BUS_DMA_NOWAIT, &sc->cmd_map); 1097 if (error != 0) { 1098 errmsg = "could not create cmd dma map"; 1099 goto fail; 1100 } 1101 1102 error = bus_dmamem_alloc(sc->sc_dmat, sizeof (struct ipw_cmd), 1103 PAGE_SIZE, 0, &sc->cmd_seg, 1, &nsegs, BUS_DMA_NOWAIT); 1104 if (error != 0) { 1105 errmsg = "could not allocate cmd dma memory"; 1106 goto fail; 1107 } 1108 1109 error = bus_dmamem_map(sc->sc_dmat, &sc->cmd_seg, nsegs, 1110 sizeof (struct ipw_cmd), (caddr_t *)&sc->cmd, BUS_DMA_NOWAIT); 1111 if (error != 0) { 1112 errmsg = "could not map cmd dma memory"; 1113 goto fail; 1114 } 1115 1116 /* Allocate a pool of DMA-able headers */ 1117 sc->shdr_list = malloc(IPW_NDATA * sizeof (struct ipw_soft_hdr), 1118 M_DEVBUF, M_NOWAIT); 1119 if (sc->shdr_list == NULL) { 1120 errmsg = "could not allocate soft hdr"; 1121 error = ENOMEM; 1122 goto fail; 1123 } 1124 TAILQ_INIT(&sc->sc_free_shdr); 1125 for (i = 0, shdr = sc->shdr_list; i < IPW_NDATA; i++, shdr++) { 1126 error = bus_dmamap_create(sc->sc_dmat, 1127 sizeof (struct ipw_soft_hdr), 1, 1128 sizeof (struct ipw_soft_hdr), 0, BUS_DMA_NOWAIT, 1129 &shdr->map); 1130 if (error != 0) { 1131 errmsg = "could not create hdr dma map"; 1132 goto fail; 1133 } 1134 TAILQ_INSERT_TAIL(&sc->sc_free_shdr, shdr, next); 1135 } 1136 1137 /* Allocate a pool of DMA-able buffers */ 1138 sc->tx_sbuf_list = malloc(IPW_NDATA * sizeof (struct ipw_soft_buf), 1139 M_DEVBUF, M_NOWAIT); 1140 if (sc->tx_sbuf_list == NULL) { 1141 errmsg = "could not allocate soft txbuf"; 1142 error = ENOMEM; 1143 goto fail; 1144 } 1145 TAILQ_INIT(&sc->sc_free_sbuf); 1146 for (i = 0, sbuf = sc->tx_sbuf_list; i < IPW_NDATA; i++, sbuf++) { 1147 error = bus_dmamap_create(sc->sc_dmat, IPW_NDATA * MCLBYTES, 1148 IPW_NDATA, MCLBYTES, 0, BUS_DMA_NOWAIT, &sbuf->map); 1149 if (error != 0) { 1150 errmsg = "could not create txbuf dma map"; 1151 goto fail; 1152 } 1153 TAILQ_INSERT_TAIL(&sc->sc_free_sbuf, sbuf, next); 1154 } 1155 1156 return 0; 1157 1158fail: printf("%s: %s\n", sc->sc_dev.dv_xname, errmsg); 1159 ipw_tx_stop(sc); 1160 1161 return error; 1162} 1163 1164void 1165ipw_tx_stop(struct ipw_softc *sc) 1166{ 1167 struct ipw_soft_hdr *shdr; 1168 struct ipw_soft_buf *sbuf; 1169 int i; 1170 1171 if (sc->tbd_map != NULL) { 1172 if (sc->tbd_list != NULL) { 1173 bus_dmamap_unload(sc->sc_dmat, sc->tbd_map); 1174 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->tbd_list, 1175 IPW_TBD_SZ); 1176 bus_dmamem_free(sc->sc_dmat, &sc->tbd_seg, 1); 1177 sc->tbd_list = NULL; 1178 } 1179 bus_dmamap_destroy(sc->sc_dmat, sc->tbd_map); 1180 sc->tbd_map = NULL; 1181 } 1182 1183 if (sc->stbd_list != NULL) { 1184 for (i = 0; i < IPW_NTBD; i++) 1185 ipw_release_sbd(sc, &sc->stbd_list[i]); 1186 free(sc->stbd_list, M_DEVBUF); 1187 sc->stbd_list = NULL; 1188 } 1189 1190 if (sc->cmd_map != NULL) { 1191 if (sc->cmd != NULL) { 1192 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->cmd, 1193 sizeof (struct ipw_cmd)); 1194 bus_dmamem_free(sc->sc_dmat, &sc->cmd_seg, 1); 1195 sc->cmd = NULL; 1196 } 1197 bus_dmamap_destroy(sc->sc_dmat, sc->cmd_map); 1198 sc->cmd_map = NULL; 1199 } 1200 1201 if (sc->shdr_list != NULL) { 1202 TAILQ_FOREACH(shdr, &sc->sc_free_shdr, next) 1203 bus_dmamap_destroy(sc->sc_dmat, shdr->map); 1204 free(sc->shdr_list, M_DEVBUF); 1205 sc->shdr_list = NULL; 1206 } 1207 1208 1209 if (sc->tx_sbuf_list != NULL) { 1210 TAILQ_FOREACH(sbuf, &sc->sc_free_sbuf, next) 1211 bus_dmamap_destroy(sc->sc_dmat, sbuf->map); 1212 free(sc->tx_sbuf_list, M_DEVBUF); 1213 sc->tx_sbuf_list = NULL; 1214 } 1215} 1216 1217int 1218ipw_rx_init(struct ipw_softc *sc) 1219{ 1220 char *errmsg; 1221 struct ipw_bd *bd; 1222 struct ipw_soft_bd *sbd; 1223 struct ipw_soft_buf *sbuf; 1224 int error, i, nsegs; 1225 1226 /* Allocate reception buffer descriptors */ 1227 error = bus_dmamap_create(sc->sc_dmat, IPW_RBD_SZ, 1, IPW_RBD_SZ, 0, 1228 BUS_DMA_NOWAIT, &sc->rbd_map); 1229 if (error != 0) { 1230 errmsg = "could not create rbd dma map"; 1231 goto fail; 1232 } 1233 1234 error = bus_dmamem_alloc(sc->sc_dmat, IPW_RBD_SZ, PAGE_SIZE, 0, 1235 &sc->rbd_seg, 1, &nsegs, BUS_DMA_NOWAIT); 1236 if (error != 0) { 1237 errmsg = "could not allocate rbd dma memory"; 1238 goto fail; 1239 } 1240 1241 error = bus_dmamem_map(sc->sc_dmat, &sc->rbd_seg, nsegs, IPW_RBD_SZ, 1242 (caddr_t *)&sc->rbd_list, BUS_DMA_NOWAIT); 1243 if (error != 0) { 1244 errmsg = "could not map rbd dma memory"; 1245 goto fail; 1246 } 1247 1248 error = bus_dmamap_load(sc->sc_dmat, sc->rbd_map, sc->rbd_list, 1249 IPW_RBD_SZ, NULL, BUS_DMA_NOWAIT); 1250 if (error != 0) { 1251 errmsg = "could not load rbd dma memory"; 1252 goto fail; 1253 } 1254 1255 sc->srbd_list = malloc(IPW_NRBD * sizeof (struct ipw_soft_bd), 1256 M_DEVBUF, M_NOWAIT); 1257 if (sc->srbd_list == NULL) { 1258 errmsg = "could not allocate soft rbd"; 1259 error = ENOMEM; 1260 goto fail; 1261 } 1262 sbd = sc->srbd_list; 1263 bd = sc->rbd_list; 1264 for (i = 0; i < IPW_NRBD; i++, sbd++, bd++) { 1265 sbd->type = IPW_SBD_TYPE_NOASSOC; 1266 sbd->bd = bd; 1267 } 1268 1269 CSR_WRITE_4(sc, IPW_CSR_RX_BD_BASE, sc->rbd_map->dm_segs[0].ds_addr); 1270 CSR_WRITE_4(sc, IPW_CSR_RX_BD_SIZE, IPW_NRBD); 1271 CSR_WRITE_4(sc, IPW_CSR_RX_READ_INDEX, 0); 1272 CSR_WRITE_4(sc, IPW_CSR_RX_WRITE_INDEX, IPW_NRBD - 1); 1273 sc->rxcur = IPW_NRBD - 1; /* latest bd index I've read */ 1274 1275 /* Allocate status descriptors */ 1276 error = bus_dmamap_create(sc->sc_dmat, IPW_STATUS_SZ, 1, IPW_STATUS_SZ, 1277 0, BUS_DMA_NOWAIT, &sc->status_map); 1278 if (error != 0) { 1279 errmsg = "could not create status dma map"; 1280 goto fail; 1281 } 1282 1283 error = bus_dmamem_alloc(sc->sc_dmat, IPW_STATUS_SZ, PAGE_SIZE, 0, 1284 &sc->status_seg, 1, &nsegs, BUS_DMA_NOWAIT); 1285 if (error != 0) { 1286 errmsg = "could not allocate status dma memory"; 1287 goto fail; 1288 } 1289 1290 error = bus_dmamem_map(sc->sc_dmat, &sc->status_seg, nsegs, 1291 IPW_STATUS_SZ, (caddr_t *)&sc->status_list, BUS_DMA_NOWAIT); 1292 if (error != 0) { 1293 errmsg = "could not map status dma memory"; 1294 goto fail; 1295 } 1296 1297 error = bus_dmamap_load(sc->sc_dmat, sc->status_map, sc->status_list, 1298 IPW_STATUS_SZ, NULL, BUS_DMA_NOWAIT); 1299 if (error != 0) { 1300 errmsg = "could not load status dma memory"; 1301 goto fail; 1302 } 1303 1304 CSR_WRITE_4(sc, IPW_CSR_RX_STATUS_BASE, 1305 sc->status_map->dm_segs[0].ds_addr); 1306 1307 sc->rx_sbuf_list = malloc(IPW_NRBD * sizeof (struct ipw_soft_buf), 1308 M_DEVBUF, M_NOWAIT); 1309 if (sc->rx_sbuf_list == NULL) { 1310 errmsg = "could not allocate soft rxbuf"; 1311 error = ENOMEM; 1312 goto fail; 1313 } 1314 1315 sbuf = sc->rx_sbuf_list; 1316 sbd = sc->srbd_list; 1317 for (i = 0; i < IPW_NRBD; i++, sbuf++, sbd++) { 1318 1319 MGETHDR(sbuf->m, M_DONTWAIT, MT_DATA); 1320 if (sbuf->m == NULL) { 1321 errmsg = "could not allocate rx mbuf"; 1322 error = ENOMEM; 1323 goto fail; 1324 } 1325 MCLGET(sbuf->m, M_DONTWAIT); 1326 if (!(sbuf->m->m_flags & M_EXT)) { 1327 m_freem(sbuf->m); 1328 errmsg = "could not allocate rx mbuf cluster"; 1329 error = ENOMEM; 1330 goto fail; 1331 } 1332 1333 error = bus_dmamap_create(sc->sc_dmat, IPW_NRBD * MCLBYTES, 1334 IPW_NRBD, MCLBYTES, 0, BUS_DMA_NOWAIT, &sbuf->map); 1335 if (error != 0) { 1336 m_freem(sbuf->m); 1337 errmsg = "could not create rxbuf dma map"; 1338 goto fail; 1339 } 1340 error = bus_dmamap_load(sc->sc_dmat, sbuf->map, 1341 mtod(sbuf->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT); 1342 if (error != 0) { 1343 bus_dmamap_destroy(sc->sc_dmat, sbuf->map); 1344 m_freem(sbuf->m); 1345 errmsg = "could not map rxbuf dma memory"; 1346 goto fail; 1347 } 1348 sbd->type = IPW_SBD_TYPE_DATA; 1349 sbd->priv = sbuf; 1350 sbd->bd->physaddr = htole32(sbuf->map->dm_segs[0].ds_addr); 1351 sbd->bd->len = htole32(MCLBYTES); 1352 } 1353 1354 return 0; 1355 1356fail: printf("%s: %s\n", sc->sc_dev.dv_xname, errmsg); 1357 ipw_rx_stop(sc); 1358 1359 return error; 1360} 1361 1362void 1363ipw_rx_stop(struct ipw_softc *sc) 1364{ 1365 struct ipw_soft_bd *sbd; 1366 struct ipw_soft_buf *sbuf; 1367 int i; 1368 1369 if (sc->rbd_map != NULL) { 1370 if (sc->rbd_list != NULL) { 1371 bus_dmamap_unload(sc->sc_dmat, sc->rbd_map); 1372 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->rbd_list, 1373 IPW_RBD_SZ); 1374 bus_dmamem_free(sc->sc_dmat, &sc->rbd_seg, 1); 1375 sc->rbd_list = NULL; 1376 } 1377 bus_dmamap_destroy(sc->sc_dmat, sc->rbd_map); 1378 sc->rbd_map = NULL; 1379 } 1380 1381 if (sc->status_map != NULL) { 1382 if (sc->status_list != NULL) { 1383 bus_dmamap_unload(sc->sc_dmat, sc->status_map); 1384 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->status_list, 1385 IPW_STATUS_SZ); 1386 bus_dmamem_free(sc->sc_dmat, &sc->status_seg, 1); 1387 sc->status_list = NULL; 1388 } 1389 bus_dmamap_destroy(sc->sc_dmat, sc->status_map); 1390 sc->status_map = NULL; 1391 } 1392 1393 if (sc->srbd_list != NULL) { 1394 for (i = 0, sbd = sc->srbd_list; i < IPW_NRBD; i++, sbd++) { 1395 if (sbd->type == IPW_SBD_TYPE_NOASSOC) 1396 continue; 1397 1398 sbuf = sbd->priv; 1399 bus_dmamap_unload(sc->sc_dmat, sbuf->map); 1400 bus_dmamap_destroy(sc->sc_dmat, sbuf->map); 1401 m_freem(sbuf->m); 1402 } 1403 free(sc->srbd_list, M_DEVBUF); 1404 sc->srbd_list = NULL; 1405 } 1406 1407 if (sc->rx_sbuf_list != NULL) { 1408 free(sc->rx_sbuf_list, M_DEVBUF); 1409 sc->rx_sbuf_list = NULL; 1410 } 1411} 1412 1413void 1414ipw_reset(struct ipw_softc *sc) 1415{ 1416 struct ifnet *ifp = &sc->sc_ic.ic_if; 1417 int ntries; 1418 1419 ipw_stop(ifp, 1); 1420 1421 if (sc->flags & IPW_FLAG_FW_INITED) { 1422 ipw_cmd(sc, IPW_CMD_DISABLE_PHY, NULL, 0); 1423 ipw_cmd(sc, IPW_CMD_PREPARE_POWER_DOWN, NULL, 0); 1424 1425 sc->flags &= ~IPW_FLAG_FW_INITED; 1426 } 1427 1428 /* Disable interrupts */ 1429 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0); 1430 1431 CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_STOP_MASTER); 1432 for (ntries = 0; ntries < 5; ntries++) { 1433 if (CSR_READ_4(sc, IPW_CSR_RST) & IPW_RST_MASTER_DISABLED) 1434 break; 1435 DELAY(10); 1436 } 1437 1438 CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_SW_RESET); 1439 1440 ipw_rx_stop(sc); 1441 ipw_tx_stop(sc); 1442 1443 ifp->if_flags &= ~IFF_UP; 1444} 1445 1446int 1447ipw_clock_sync(struct ipw_softc *sc) 1448{ 1449 int ntries; 1450 u_int32_t r; 1451 1452 CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_SW_RESET); 1453 for (ntries = 0; ntries < 1000; ntries++) { 1454 if (CSR_READ_4(sc, IPW_CSR_RST) & IPW_RST_PRINCETON_RESET) 1455 break; 1456 DELAY(10); 1457 } 1458 if (ntries == 1000) 1459 return EIO; 1460 1461 CSR_WRITE_4(sc, IPW_CSR_CTL, IPW_CTL_INIT); 1462 for (ntries = 0; ntries < 1000; ntries++) { 1463 if ((r = CSR_READ_4(sc, IPW_CSR_CTL)) & IPW_CTL_CLOCK_READY) 1464 break; 1465 DELAY(200); 1466 } 1467 if (ntries == 1000) 1468 return EIO; 1469 1470 CSR_WRITE_4(sc, IPW_CSR_CTL, r | IPW_CTL_ALLOW_STANDBY); 1471 1472 return 0; 1473} 1474 1475int 1476ipw_load_ucode(struct ipw_softc *sc, u_char *uc, int size) 1477{ 1478 int ntries; 1479 1480 MEM_WRITE_2(sc, 0x220000, 0x0703); 1481 MEM_WRITE_2(sc, 0x220000, 0x0707); 1482 1483 MEM_WRITE_1(sc, 0x210014, 0x72); 1484 MEM_WRITE_1(sc, 0x210014, 0x72); 1485 1486 MEM_WRITE_1(sc, 0x210000, 0x40); 1487 MEM_WRITE_1(sc, 0x210000, 0x00); 1488 MEM_WRITE_1(sc, 0x210000, 0x40); 1489 1490 MEM_WRITE_MULTI_1(sc, 0x210010, uc, size); 1491 1492 MEM_WRITE_1(sc, 0x210000, 0x00); 1493 MEM_WRITE_1(sc, 0x210000, 0x00); 1494 MEM_WRITE_1(sc, 0x210000, 0x80); 1495 1496 MEM_WRITE_2(sc, 0x220000, 0x0703); 1497 MEM_WRITE_2(sc, 0x220000, 0x0707); 1498 1499 MEM_WRITE_1(sc, 0x210014, 0x72); 1500 MEM_WRITE_1(sc, 0x210014, 0x72); 1501 1502 MEM_WRITE_1(sc, 0x210000, 0x00); 1503 MEM_WRITE_1(sc, 0x210000, 0x80); 1504 1505 for (ntries = 0; ntries < 10; ntries++) { 1506 if (MEM_READ_1(sc, 0x210000) & 1) 1507 break; 1508 DELAY(10); 1509 } 1510 if (ntries == 10) 1511 return EIO; 1512 1513 return 0; 1514} 1515 1516/* set of macros to handle unaligned little endian data in firmware image */ 1517#define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24) 1518#define GETLE16(p) ((p)[0] | (p)[1] << 8) 1519int 1520ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size) 1521{ 1522 u_char *p, *end; 1523 u_int32_t dst; 1524 u_int16_t len; 1525 1526 p = fw; 1527 end = fw + size; 1528 while (p < end) { 1529 if (p + 6 > end) 1530 return EINVAL; 1531 1532 dst = GETLE32(p); p += 4; 1533 len = GETLE16(p); p += 2; 1534 1535 if (p + len > end) 1536 return EINVAL; 1537 1538 ipw_write_mem_1(sc, dst, p, len); 1539 p += len; 1540 } 1541 return 0; 1542} 1543 1544int 1545ipw_firmware_init(struct ipw_softc *sc, u_char *data) 1546{ 1547 struct ieee80211com *ic = &sc->sc_ic; 1548 struct ifnet *ifp = &ic->ic_if; 1549 struct ipw_fw_hdr hdr; 1550 u_int32_t r, len, fw_size, uc_size; 1551 u_char *fw, *uc; 1552 int error; 1553 1554 ipw_reset(sc); 1555 1556 if ((error = copyin(data, &hdr, sizeof hdr)) != 0) 1557 goto fail1; 1558 1559 fw_size = letoh32(hdr.fw_size); 1560 uc_size = letoh32(hdr.uc_size); 1561 data += sizeof hdr; 1562 1563 if ((fw = malloc(fw_size, M_DEVBUF, M_NOWAIT)) == NULL) { 1564 error = ENOMEM; 1565 goto fail1; 1566 } 1567 1568 if ((error = copyin(data, fw, fw_size)) != 0) 1569 goto fail2; 1570 1571 data += fw_size; 1572 1573 if ((uc = malloc(uc_size, M_DEVBUF, M_NOWAIT)) == NULL) { 1574 error = ENOMEM; 1575 goto fail2; 1576 } 1577 1578 if ((error = copyin(data, uc, uc_size)) != 0) 1579 goto fail3; 1580 1581 if ((error = ipw_clock_sync(sc)) != 0) { 1582 printf("%s: clock synchronization failed\n", 1583 sc->sc_dev.dv_xname); 1584 goto fail3; 1585 } 1586 1587 MEM_WRITE_4(sc, 0x003000e0, 0x80000000); 1588 1589 CSR_WRITE_4(sc, IPW_CSR_RST, 0); 1590 1591 if ((error = ipw_load_ucode(sc, uc, uc_size)) != 0) { 1592 printf("%s: could not load microcode\n", sc->sc_dev.dv_xname); 1593 goto fail3; 1594 } 1595 1596 MEM_WRITE_4(sc, 0x003000e0, 0); 1597 1598 if ((error = ipw_clock_sync(sc)) != 0) { 1599 printf("%s: clock synchronization failed\n", 1600 sc->sc_dev.dv_xname); 1601 goto fail3; 1602 } 1603 1604 if ((error = ipw_load_firmware(sc, fw, fw_size))) { 1605 printf("%s: could not load firmware\n", sc->sc_dev.dv_xname); 1606 goto fail3; 1607 } 1608 1609 ipw_zero_mem_4(sc, 0x0002f200, 196); 1610 ipw_zero_mem_4(sc, 0x0002f610, 8); 1611 ipw_zero_mem_4(sc, 0x0002fa00, 8); 1612 ipw_zero_mem_4(sc, 0x0002fc00, 4); 1613 ipw_zero_mem_4(sc, 0x0002ff80, 32); 1614 1615 if ((error = ipw_rx_init(sc)) != 0) { 1616 printf("%s: could not initialize rx queue\n", 1617 sc->sc_dev.dv_xname); 1618 goto fail3; 1619 } 1620 1621 if ((error = ipw_tx_init(sc)) != 0) { 1622 printf("%s: could not initialize tx queue\n", 1623 sc->sc_dev.dv_xname); 1624 goto fail3; 1625 } 1626 1627 CSR_WRITE_4(sc, IPW_CSR_IO, IPW_IO_GPIO1_ENABLE | IPW_IO_GPIO3_MASK | 1628 IPW_IO_LED_OFF); 1629 1630 /* Allow interrupts so we know when the firmware is inited */ 1631 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK); 1632 1633 /* Tell the adapter to initialize the firmware */ 1634 CSR_WRITE_4(sc, IPW_CSR_RST, 0); 1635 1636 /* Wait at most one second for firmware initialization to complete */ 1637 if ((error = tsleep(sc, 0, "ipwinit", hz)) != 0) { 1638 printf("%s: timeout waiting for firmware initialization to " 1639 "complete\n", sc->sc_dev.dv_xname); 1640 goto fail3; 1641 } 1642 1643 /* Firmware initialization completed */ 1644 sc->flags |= IPW_FLAG_FW_INITED; 1645 1646 free(uc, M_DEVBUF); 1647 free(fw, M_DEVBUF); 1648 1649 r = CSR_READ_4(sc, IPW_CSR_IO); 1650 CSR_WRITE_4(sc, IPW_CSR_IO, r | IPW_IO_GPIO1_MASK | IPW_IO_GPIO3_MASK); 1651 1652 /* Retrieve information tables base addresses */ 1653 sc->table1_base = CSR_READ_4(sc, IPW_CSR_TABLE1_BASE); 1654 sc->table2_base = CSR_READ_4(sc, IPW_CSR_TABLE2_BASE); 1655 1656 ipw_write_table1(sc, IPW_INFO_LOCK, 0); 1657 1658 /* Retrieve adapter MAC address */ 1659 len = IEEE80211_ADDR_LEN; 1660 ipw_read_table2(sc, IPW_INFO_ADAPTER_MAC, ic->ic_myaddr, &len); 1661 1662 IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), ic->ic_myaddr); 1663 1664 return 0; 1665 1666fail3: free(uc, M_DEVBUF); 1667fail2: free(fw, M_DEVBUF); 1668fail1: ipw_reset(sc); 1669 1670 return error; 1671} 1672 1673int 1674ipw_config(struct ipw_softc *sc) 1675{ 1676 struct ieee80211com *ic = &sc->sc_ic; 1677 struct ifnet *ifp = &ic->ic_if; 1678 struct ipw_security security; 1679 struct ieee80211_wepkey *k; 1680 struct ipw_wep_key wepkey; 1681 struct ipw_scan_options options; 1682 struct ipw_configuration config; 1683 u_int32_t data; 1684 int error, i; 1685 1686 switch (ic->ic_opmode) { 1687 case IEEE80211_M_STA: 1688 case IEEE80211_M_HOSTAP: 1689 data = htole32(IPW_MODE_BSS); 1690 break; 1691 1692 case IEEE80211_M_IBSS: 1693 case IEEE80211_M_AHDEMO: 1694 data = htole32(IPW_MODE_IBSS); 1695 break; 1696 1697 case IEEE80211_M_MONITOR: 1698 data = htole32(IPW_MODE_MONITOR); 1699 break; 1700 } 1701 DPRINTF(("Setting adapter mode to %u\n", data)); 1702 error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data); 1703 if (error != 0) 1704 return error; 1705 1706 if (ic->ic_opmode == IEEE80211_M_IBSS || 1707 ic->ic_opmode == IEEE80211_M_MONITOR) { 1708 data = htole32(ieee80211_chan2ieee(ic, ic->ic_ibss_chan)); 1709 DPRINTF(("Setting adapter channel to %u\n", data)); 1710 error = ipw_cmd(sc, IPW_CMD_SET_CHANNEL, &data, sizeof data); 1711 if (error != 0) 1712 return error; 1713 } 1714 1715 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 1716 DPRINTF(("Enabling adapter\n")); 1717 return ipw_cmd(sc, IPW_CMD_ENABLE, NULL, 0); 1718 } 1719 1720 DPRINTF(("Setting adapter MAC to %s\n", ether_sprintf(ic->ic_myaddr))); 1721 IEEE80211_ADDR_COPY(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr); 1722 IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), ic->ic_myaddr); 1723 error = ipw_cmd(sc, IPW_CMD_SET_MAC_ADDRESS, ic->ic_myaddr, 1724 IEEE80211_ADDR_LEN); 1725 if (error != 0) 1726 return error; 1727 1728 config.flags = htole32(IPW_CFG_BSS_MASK | IPW_CFG_IBSS_MASK | 1729 IPW_CFG_PREAMBLE_LEN | IPW_CFG_802_1x_ENABLE); 1730 if (ic->ic_opmode == IEEE80211_M_IBSS) 1731 config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); 1732 if (ifp->if_flags & IFF_PROMISC) 1733 config.flags |= htole32(IPW_CFG_PROMISCUOUS); 1734 config.channels = htole32(0x3fff); /* channels 1-14 */ 1735 config.ibss_chan = htole32(0x7ff); 1736 DPRINTF(("Setting adapter configuration 0x%08x\n", config.flags)); 1737 error = ipw_cmd(sc, IPW_CMD_SET_CONFIGURATION, &config, sizeof config); 1738 if (error != 0) 1739 return error; 1740 1741 data = htole32(0x3); /* 1, 2 */ 1742 DPRINTF(("Setting adapter basic tx rates to 0x%x\n", data)); 1743 error = ipw_cmd(sc, IPW_CMD_SET_BASIC_TX_RATES, &data, sizeof data); 1744 if (error != 0) 1745 return error; 1746 1747 data = htole32(0xf); /* 1, 2, 5.5, 11 */ 1748 DPRINTF(("Setting adapter tx rates to 0x%x\n", data)); 1749 error = ipw_cmd(sc, IPW_CMD_SET_TX_RATES, &data, sizeof data); 1750 if (error != 0) 1751 return error; 1752 1753 data = htole32(IPW_POWER_MODE_CAM); 1754 DPRINTF(("Setting adapter power mode to %u\n", data)); 1755 error = ipw_cmd(sc, IPW_CMD_SET_POWER_MODE, &data, sizeof data); 1756 if (error != 0) 1757 return error; 1758 1759 if (ic->ic_opmode == IEEE80211_M_IBSS) { 1760 data = htole32(ic->ic_txpower); 1761 DPRINTF(("Setting adapter tx power index to %u\n", data)); 1762 error = ipw_cmd(sc, IPW_CMD_SET_TX_POWER_INDEX, &data, 1763 sizeof data); 1764 if (error != 0) 1765 return error; 1766 } 1767 1768 data = htole32(ic->ic_rtsthreshold); 1769 DPRINTF(("Setting adapter RTS threshold to %u\n", data)); 1770 error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data); 1771 if (error != 0) 1772 return error; 1773 1774 data = htole32(ic->ic_fragthreshold); 1775 DPRINTF(("Setting adapter frag threshold to %u\n", data)); 1776 error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); 1777 if (error != 0) 1778 return error; 1779 1780#ifdef IPW_DEBUG 1781 if (ipw_debug > 0) { 1782 printf("Setting adapter ESSID to "); 1783 ieee80211_print_essid(ic->ic_des_essid, ic->ic_des_esslen); 1784 printf("\n"); 1785 } 1786#endif 1787 error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_essid, 1788 ic->ic_des_esslen); 1789 if (error != 0) 1790 return error; 1791 1792 /* no mandatory BSSID */ 1793 error = ipw_cmd(sc, IPW_CMD_SET_MANDATORY_BSSID, NULL, 0); 1794 if (error != 0) 1795 return error; 1796 1797 if (ic->ic_flags & IEEE80211_F_DESBSSID) { 1798 DPRINTF(("Setting adapter desired BSSID to %s\n", 1799 ether_sprintf(ic->ic_des_bssid))); 1800 error = ipw_cmd(sc, IPW_CMD_SET_DESIRED_BSSID, 1801 ic->ic_des_bssid, IEEE80211_ADDR_LEN); 1802 if (error != 0) 1803 return error; 1804 } 1805 1806 security.authmode = (sc->authmode == IEEE80211_AUTH_SHARED) ? 1807 IPW_AUTH_SHARED : IPW_AUTH_OPEN; 1808 security.ciphers = htole32(IPW_CIPHER_NONE); 1809 security.version = htole16(0); 1810 security.replay_counters_number = 0; 1811 security.unicast_using_group = 0; 1812 DPRINTF(("Setting adapter authmode to %u\n", security.authmode)); 1813 error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFORMATION, &security, 1814 sizeof security); 1815 if (error != 0) 1816 return error; 1817 1818 if (ic->ic_flags & IEEE80211_F_WEPON) { 1819 k = ic->ic_nw_keys; 1820 for (i = 0; i < IEEE80211_WEP_NKID; i++, k++) { 1821 if (k->wk_len == 0) 1822 continue; 1823 1824 wepkey.idx = i; 1825 wepkey.len = k->wk_len; 1826 bzero(wepkey.key, sizeof wepkey.key); 1827 bcopy(k->wk_key, wepkey.key, k->wk_len); 1828 DPRINTF(("Setting wep key index %d len %d\n", 1829 wepkey.idx, wepkey.len)); 1830 error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY, &wepkey, 1831 sizeof wepkey); 1832 if (error != 0) 1833 return error; 1834 } 1835 1836 data = htole32(ic->ic_wep_txkey); 1837 DPRINTF(("Setting adapter tx key index to %u\n", data)); 1838 error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data, 1839 sizeof data); 1840 if (error != 0) 1841 return error; 1842 } 1843 1844 data = htole32((sc->sc_ic.ic_flags & IEEE80211_F_WEPON) ? 0x8 : 0); 1845 DPRINTF(("Setting adapter wep flags to 0x%x\n", data)); 1846 error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data); 1847 if (error != 0) 1848 return error; 1849 1850 if (ic->ic_opmode == IEEE80211_M_IBSS || 1851 ic->ic_opmode == IEEE80211_M_HOSTAP) { 1852 data = htole32(ic->ic_lintval); 1853 DPRINTF(("Setting adapter beacon interval to %u\n", data)); 1854 error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data, 1855 sizeof data); 1856 if (error != 0) 1857 return error; 1858 } 1859 1860 options.flags = htole32(0); 1861 options.channels = htole32(0x3fff); /* scan channels 1-14 */ 1862 error = ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &options, sizeof options); 1863 if (error != 0) 1864 return error; 1865 1866 /* finally, enable adapter (start scanning for an access point) */ 1867 DPRINTF(("Enabling adapter\n")); 1868 return ipw_cmd(sc, IPW_CMD_ENABLE, NULL, 0); 1869} 1870 1871int 1872ipw_init(struct ifnet *ifp) 1873{ 1874 struct ipw_softc *sc = ifp->if_softc; 1875 1876 /* exit immediately if firmware has not been ioctl'd */ 1877 if (!(sc->flags & IPW_FLAG_FW_INITED)) { 1878 ifp->if_flags &= ~IFF_UP; 1879 return EIO; 1880 } 1881 1882 ipw_stop(ifp, 0); 1883 1884 if (ipw_config(sc) != 0) { 1885 printf("%s: device configuration failed\n", 1886 sc->sc_dev.dv_xname); 1887 goto fail; 1888 } 1889 1890 ifp->if_flags &= ~IFF_OACTIVE; 1891 ifp->if_flags |= IFF_RUNNING; 1892 1893 return 0; 1894 1895fail: ipw_stop(ifp, 0); 1896 1897 return EIO; 1898} 1899 1900void 1901ipw_stop(struct ifnet *ifp, int disable) 1902{ 1903 struct ipw_softc *sc = ifp->if_softc; 1904 struct ieee80211com *ic = &sc->sc_ic; 1905 1906 if (ifp->if_flags & IFF_RUNNING) { 1907 DPRINTF(("Disabling adapter\n")); 1908 ipw_cmd(sc, IPW_CMD_DISABLE, NULL, 0); 1909 } 1910 1911 ifp->if_timer = 0; 1912 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1913 1914 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1915} 1916 1917void 1918ipw_read_mem_1(struct ipw_softc *sc, bus_size_t offset, u_int8_t *datap, 1919 bus_size_t count) 1920{ 1921 for (; count > 0; offset++, datap++, count--) { 1922 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3); 1923 *datap = CSR_READ_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3)); 1924 } 1925} 1926 1927void 1928ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, u_int8_t *datap, 1929 bus_size_t count) 1930{ 1931 for (; count > 0; offset++, datap++, count--) { 1932 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3); 1933 CSR_WRITE_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3), *datap); 1934 } 1935} 1936 1937void 1938ipw_zero_mem_4(struct ipw_softc *sc, bus_size_t offset, bus_size_t count) 1939{ 1940 CSR_WRITE_4(sc, IPW_CSR_AUTOINC_ADDR, offset); 1941 while (count-- > 0) 1942 CSR_WRITE_4(sc, IPW_CSR_AUTOINC_DATA, 0); 1943} 1944 1945struct cfdriver ipw_cd = { 1946 0, "ipw", DV_IFNET 1947}; 1948