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