[BACK]Return to if_iwi.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/if_iwi.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_iwi.c,v 1.83 2007/07/18 18:10:31 damien Exp $      */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2004-2006
                      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:  * Driver for Intel PRO/Wireless 2200BG/2915ABG 802.11 network adapters.
                     32:  */
                     33:
                     34: #include "bpfilter.h"
                     35:
                     36: #include <sys/param.h>
                     37: #include <sys/sockio.h>
                     38: #include <sys/sysctl.h>
                     39: #include <sys/mbuf.h>
                     40: #include <sys/kernel.h>
                     41: #include <sys/socket.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/malloc.h>
                     44: #include <sys/conf.h>
                     45: #include <sys/device.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/rndvar.h>
                     74: #include <crypto/arc4.h>
                     75:
                     76: #include <dev/pci/if_iwireg.h>
                     77: #include <dev/pci/if_iwivar.h>
                     78:
                     79: const struct pci_matchid iwi_devices[] = {
                     80:        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2200BG },
                     81:        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2225BG },
                     82:        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 },
                     83:        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2 }
                     84: };
                     85:
                     86: int            iwi_match(struct device *, void *, void *);
                     87: void           iwi_attach(struct device *, struct device *, void *);
                     88: void           iwi_power(int, void *);
                     89: int            iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
                     90: void           iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
                     91: void           iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
                     92: int            iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
                     93:                    bus_size_t, bus_size_t);
                     94: void           iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
                     95: void           iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
                     96: int            iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
                     97: void           iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
                     98: void           iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
                     99: int            iwi_media_change(struct ifnet *);
                    100: void           iwi_media_status(struct ifnet *, struct ifmediareq *);
                    101: uint16_t       iwi_read_prom_word(struct iwi_softc *, uint8_t);
                    102: int            iwi_find_txnode(struct iwi_softc *, const uint8_t *);
                    103: int            iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    104: uint8_t                iwi_rate(int);
                    105: void           iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *,
                    106:                    struct iwi_frame *);
                    107: void           iwi_notification_intr(struct iwi_softc *, struct iwi_rx_data *,
                    108:                    struct iwi_notif *);
                    109: void           iwi_rx_intr(struct iwi_softc *);
                    110: void           iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
                    111: int            iwi_intr(void *);
                    112: int            iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
                    113: int            iwi_tx_start(struct ifnet *, struct mbuf *,
                    114:                    struct ieee80211_node *);
                    115: void           iwi_start(struct ifnet *);
                    116: void           iwi_watchdog(struct ifnet *);
                    117: int            iwi_ioctl(struct ifnet *, u_long, caddr_t);
                    118: void           iwi_stop_master(struct iwi_softc *);
                    119: int            iwi_reset(struct iwi_softc *);
                    120: int            iwi_load_ucode(struct iwi_softc *, const char *, int);
                    121: int            iwi_load_firmware(struct iwi_softc *, const char *, int);
                    122: int            iwi_config(struct iwi_softc *);
                    123: int            iwi_set_chan(struct iwi_softc *, struct ieee80211_channel *);
                    124: int            iwi_scan(struct iwi_softc *);
                    125: int            iwi_auth_and_assoc(struct iwi_softc *);
                    126: int            iwi_init(struct ifnet *);
                    127: void           iwi_stop(struct ifnet *, int);
                    128:
                    129: static __inline uint8_t
                    130: MEM_READ_1(struct iwi_softc *sc, uint32_t addr)
                    131: {
                    132:        CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
                    133:        return CSR_READ_1(sc, IWI_CSR_INDIRECT_DATA);
                    134: }
                    135:
                    136: static __inline uint32_t
                    137: MEM_READ_4(struct iwi_softc *sc, uint32_t addr)
                    138: {
                    139:        CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
                    140:        return CSR_READ_4(sc, IWI_CSR_INDIRECT_DATA);
                    141: }
                    142:
                    143: #ifdef IWI_DEBUG
                    144: #define DPRINTF(x)     do { if (iwi_debug > 0) printf x; } while (0)
                    145: #define DPRINTFN(n, x) do { if (iwi_debug >= (n)) printf x; } while (0)
                    146: int iwi_debug = 0;
                    147: #else
                    148: #define DPRINTF(x)
                    149: #define DPRINTFN(n, x)
                    150: #endif
                    151:
                    152: struct cfattach iwi_ca = {
                    153:        sizeof (struct iwi_softc), iwi_match, iwi_attach
                    154: };
                    155:
                    156: int
                    157: iwi_match(struct device *parent, void *match, void *aux)
                    158: {
                    159:        return pci_matchbyid((struct pci_attach_args *)aux, iwi_devices,
                    160:            sizeof (iwi_devices) / sizeof (iwi_devices[0]));
                    161: }
                    162:
                    163: /* Base Address Register */
                    164: #define IWI_PCI_BAR0   0x10
                    165:
                    166: void
                    167: iwi_attach(struct device *parent, struct device *self, void *aux)
                    168: {
                    169:        struct iwi_softc *sc = (struct iwi_softc *)self;
                    170:        struct ieee80211com *ic = &sc->sc_ic;
                    171:        struct ifnet *ifp = &ic->ic_if;
                    172:        struct pci_attach_args *pa = aux;
                    173:        const char *intrstr;
                    174:        bus_space_tag_t memt;
                    175:        bus_space_handle_t memh;
                    176:        pci_intr_handle_t ih;
                    177:        pcireg_t data;
                    178:        uint16_t val;
                    179:        int error, i;
                    180:
                    181:        sc->sc_pct = pa->pa_pc;
                    182:        sc->sc_pcitag = pa->pa_tag;
                    183:
                    184:        /* clear device specific PCI configuration register 0x41 */
                    185:        data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
                    186:        data &= ~0x0000ff00;
                    187:        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
                    188:
                    189:        /* map the register window */
                    190:        error = pci_mapreg_map(pa, IWI_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
                    191:            PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, &sc->sc_sz, 0);
                    192:        if (error != 0) {
                    193:                printf(": could not map memory space\n");
                    194:                return;
                    195:        }
                    196:
                    197:        sc->sc_st = memt;
                    198:        sc->sc_sh = memh;
                    199:        sc->sc_dmat = pa->pa_dmat;
                    200:
                    201:        if (pci_intr_map(pa, &ih) != 0) {
                    202:                printf(": could not map interrupt\n");
                    203:                return;
                    204:        }
                    205:
                    206:        intrstr = pci_intr_string(sc->sc_pct, ih);
                    207:        sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwi_intr, sc,
                    208:            sc->sc_dev.dv_xname);
                    209:        if (sc->sc_ih == NULL) {
                    210:                printf(": could not establish interrupt");
                    211:                if (intrstr != NULL)
                    212:                        printf(" at %s", intrstr);
                    213:                printf("\n");
                    214:                return;
                    215:        }
                    216:        printf(": %s", intrstr);
                    217:
                    218:        if (iwi_reset(sc) != 0) {
                    219:                printf(": could not reset adapter\n");
                    220:                return;
                    221:        }
                    222:
                    223:        /*
                    224:         * Allocate rings.
                    225:         */
                    226:        error = iwi_alloc_cmd_ring(sc, &sc->cmdq);
                    227:        if (error != 0) {
                    228:                printf(": could not allocate Cmd ring\n");
                    229:                return;
                    230:        }
                    231:
                    232:        error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_CSR_TX1_RIDX,
                    233:            IWI_CSR_TX1_WIDX);
                    234:        if (error != 0) {
                    235:                printf(": could not allocate Tx ring 1\n");
                    236:                goto fail1;
                    237:        }
                    238:
                    239:        error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_CSR_TX2_RIDX,
                    240:            IWI_CSR_TX2_WIDX);
                    241:        if (error != 0) {
                    242:                printf(": could not allocate Tx ring 2\n");
                    243:                goto fail2;
                    244:        }
                    245:
                    246:        error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_CSR_TX3_RIDX,
                    247:            IWI_CSR_TX3_WIDX);
                    248:        if (error != 0) {
                    249:                printf(": could not allocate Tx ring 3\n");
                    250:                goto fail3;
                    251:        }
                    252:
                    253:        error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_CSR_TX4_RIDX,
                    254:            IWI_CSR_TX4_WIDX);
                    255:        if (error != 0) {
                    256:                printf(": could not allocate Tx ring 4\n");
                    257:                goto fail4;
                    258:        }
                    259:
                    260:        error = iwi_alloc_rx_ring(sc, &sc->rxq);
                    261:        if (error != 0) {
                    262:                printf(": could not allocate Rx ring\n");
                    263:                goto fail5;
                    264:        }
                    265:
                    266:        ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
                    267:        ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
                    268:        ic->ic_state = IEEE80211_S_INIT;
                    269:
                    270:        /* set device capabilities */
                    271:        ic->ic_caps =
                    272:            IEEE80211_C_IBSS |          /* IBSS mode supported */
                    273:            IEEE80211_C_MONITOR |       /* monitor mode supported */
                    274:            IEEE80211_C_TXPMGT |        /* tx power management */
                    275:            IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
                    276:            IEEE80211_C_SHSLOT |        /* short slot time supported */
                    277:            IEEE80211_C_WEP |           /* h/w WEP supported */
                    278:            IEEE80211_C_SCANALL;        /* h/w scanning */
                    279:
                    280:        /* read MAC address from EEPROM */
                    281:        val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
                    282:        ic->ic_myaddr[0] = val & 0xff;
                    283:        ic->ic_myaddr[1] = val >> 8;
                    284:        val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
                    285:        ic->ic_myaddr[2] = val & 0xff;
                    286:        ic->ic_myaddr[3] = val >> 8;
                    287:        val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
                    288:        ic->ic_myaddr[4] = val & 0xff;
                    289:        ic->ic_myaddr[5] = val >> 8;
                    290:
                    291:        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
                    292:
                    293:        if (PCI_PRODUCT(pa->pa_id) >= PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1) {
                    294:                /* set supported .11a rates */
                    295:                ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
                    296:
                    297:                /* set supported .11a channels */
                    298:                for (i = 36; i <= 64; i += 4) {
                    299:                        ic->ic_channels[i].ic_freq =
                    300:                            ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
                    301:                        ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
                    302:                }
                    303:                for (i = 149; i <= 165; i += 4) {
                    304:                        ic->ic_channels[i].ic_freq =
                    305:                            ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
                    306:                        ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
                    307:                }
                    308:        }
                    309:
                    310:        /* set supported .11b and .11g rates */
                    311:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    312:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
                    313:
                    314:        /* set supported .11b and .11g channels (1 through 14) */
                    315:        for (i = 1; i <= 14; i++) {
                    316:                ic->ic_channels[i].ic_freq =
                    317:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
                    318:                ic->ic_channels[i].ic_flags =
                    319:                    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
                    320:                    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
                    321:        }
                    322:
                    323:        /* IBSS channel undefined for now */
                    324:        ic->ic_ibss_chan = &ic->ic_channels[0];
                    325:
                    326:        ifp->if_softc = sc;
                    327:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    328:        ifp->if_init = iwi_init;
                    329:        ifp->if_ioctl = iwi_ioctl;
                    330:        ifp->if_start = iwi_start;
                    331:        ifp->if_watchdog = iwi_watchdog;
                    332:        IFQ_SET_READY(&ifp->if_snd);
                    333:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                    334:
                    335:        if_attach(ifp);
                    336:        ieee80211_ifattach(ifp);
                    337:        /* override state transition machine */
                    338:        sc->sc_newstate = ic->ic_newstate;
                    339:        ic->ic_newstate = iwi_newstate;
                    340:        ieee80211_media_init(ifp, iwi_media_change, iwi_media_status);
                    341:
                    342:        sc->powerhook = powerhook_establish(iwi_power, sc);
                    343:
                    344: #if NBPFILTER > 0
                    345:        bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
                    346:            sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
                    347:
                    348:        sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
                    349:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    350:        sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
                    351:
                    352:        sc->sc_txtap_len = sizeof sc->sc_txtapu;
                    353:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    354:        sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
                    355: #endif
                    356:
                    357:        return;
                    358:
                    359: fail5: iwi_free_tx_ring(sc, &sc->txq[3]);
                    360: fail4: iwi_free_tx_ring(sc, &sc->txq[2]);
                    361: fail3: iwi_free_tx_ring(sc, &sc->txq[1]);
                    362: fail2: iwi_free_tx_ring(sc, &sc->txq[0]);
                    363: fail1: iwi_free_cmd_ring(sc, &sc->cmdq);
                    364: }
                    365:
                    366: void
                    367: iwi_power(int why, void *arg)
                    368: {
                    369:        struct iwi_softc *sc = arg;
                    370:        struct ifnet *ifp;
                    371:        pcireg_t data;
                    372:
                    373:        if (why != PWR_RESUME)
                    374:                return;
                    375:
                    376:        /* clear device specific PCI configuration register 0x41 */
                    377:        data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
                    378:        data &= ~0x0000ff00;
                    379:        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
                    380:
                    381:        ifp = &sc->sc_ic.ic_if;
                    382:        if (ifp->if_flags & IFF_UP) {
                    383:                ifp->if_init(ifp);
                    384:                if (ifp->if_flags & IFF_RUNNING)
                    385:                        ifp->if_start(ifp);
                    386:        }
                    387: }
                    388:
                    389: int
                    390: iwi_alloc_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
                    391: {
                    392:        int nsegs, error;
                    393:
                    394:        ring->queued = 0;
                    395:        ring->cur = ring->next = 0;
                    396:
                    397:        error = bus_dmamap_create(sc->sc_dmat,
                    398:            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, 1,
                    399:            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, 0,
                    400:            BUS_DMA_NOWAIT, &ring->map);
                    401:        if (error != 0) {
                    402:                printf("%s: could not create cmd ring DMA map\n",
                    403:                    sc->sc_dev.dv_xname);
                    404:                goto fail;
                    405:        }
                    406:
                    407:        error = bus_dmamem_alloc(sc->sc_dmat,
                    408:            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, PAGE_SIZE, 0,
                    409:            &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
                    410:        if (error != 0) {
                    411:                printf("%s: could not allocate cmd ring DMA memory\n",
                    412:                    sc->sc_dev.dv_xname);
                    413:                goto fail;
                    414:        }
                    415:
                    416:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
                    417:            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT,
                    418:            (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
                    419:        if (error != 0) {
                    420:                printf("%s: could not map cmd ring DMA memory\n",
                    421:                    sc->sc_dev.dv_xname);
                    422:                goto fail;
                    423:        }
                    424:
                    425:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
                    426:            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, NULL,
                    427:            BUS_DMA_NOWAIT);
                    428:        if (error != 0) {
                    429:                printf("%s: could not load cmd ring DMA map\n",
                    430:                    sc->sc_dev.dv_xname);
                    431:                goto fail;
                    432:        }
                    433:
                    434:        bzero(ring->desc, sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT);
                    435:        return 0;
                    436:
                    437: fail:  iwi_free_cmd_ring(sc, ring);
                    438:        return error;
                    439: }
                    440:
                    441: void
                    442: iwi_reset_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
                    443: {
                    444:        ring->queued = 0;
                    445:        ring->cur = ring->next = 0;
                    446: }
                    447:
                    448: void
                    449: iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
                    450: {
                    451:        if (ring->map != NULL) {
                    452:                if (ring->desc != NULL) {
                    453:                        bus_dmamap_unload(sc->sc_dmat, ring->map);
                    454:                        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
                    455:                            sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT);
                    456:                        bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
                    457:                }
                    458:                bus_dmamap_destroy(sc->sc_dmat, ring->map);
                    459:        }
                    460: }
                    461:
                    462: int
                    463: iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring,
                    464:     bus_size_t csr_ridx, bus_size_t csr_widx)
                    465: {
                    466:        struct iwi_tx_data *data;
                    467:        int i, nsegs, error;
                    468:
                    469:        ring->queued = 0;
                    470:        ring->cur = ring->next = 0;
                    471:        ring->csr_ridx = csr_ridx;
                    472:        ring->csr_widx = csr_widx;
                    473:
                    474:        error = bus_dmamap_create(sc->sc_dmat,
                    475:            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, 1,
                    476:            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, 0, BUS_DMA_NOWAIT,
                    477:            &ring->map);
                    478:        if (error != 0) {
                    479:                printf("%s: could not create tx ring DMA map\n",
                    480:                    sc->sc_dev.dv_xname);
                    481:                goto fail;
                    482:        }
                    483:
                    484:        error = bus_dmamem_alloc(sc->sc_dmat,
                    485:            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, PAGE_SIZE, 0,
                    486:            &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
                    487:        if (error != 0) {
                    488:                printf("%s: could not allocate tx ring DMA memory\n",
                    489:                    sc->sc_dev.dv_xname);
                    490:                goto fail;
                    491:        }
                    492:
                    493:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
                    494:            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT,
                    495:            (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
                    496:        if (error != 0) {
                    497:                printf("%s: could not map tx ring DMA memory\n",
                    498:                    sc->sc_dev.dv_xname);
                    499:                goto fail;
                    500:        }
                    501:
                    502:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
                    503:            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, NULL,
                    504:            BUS_DMA_NOWAIT);
                    505:        if (error != 0) {
                    506:                printf("%s: could not load tx ring DMA map\n",
                    507:                    sc->sc_dev.dv_xname);
                    508:                goto fail;
                    509:        }
                    510:
                    511:        bzero(ring->desc, sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT);
                    512:
                    513:        for (i = 0; i < IWI_TX_RING_COUNT; i++) {
                    514:                data = &ring->data[i];
                    515:
                    516:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                    517:                    IWI_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT, &data->map);
                    518:                if (error != 0) {
                    519:                        printf("%s: could not create tx buf DMA map\n",
                    520:                            sc->sc_dev.dv_xname);
                    521:                        goto fail;
                    522:                }
                    523:        }
                    524:
                    525:        return 0;
                    526:
                    527: fail:  iwi_free_tx_ring(sc, ring);
                    528:        return error;
                    529: }
                    530:
                    531: void
                    532: iwi_reset_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
                    533: {
                    534:        struct iwi_tx_data *data;
                    535:        int i;
                    536:
                    537:        for (i = 0; i < IWI_TX_RING_COUNT; i++) {
                    538:                data = &ring->data[i];
                    539:
                    540:                if (data->m != NULL) {
                    541:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                    542:                        m_freem(data->m);
                    543:                        data->m = NULL;
                    544:                }
                    545:        }
                    546:
                    547:        ring->queued = 0;
                    548:        ring->cur = ring->next = 0;
                    549: }
                    550:
                    551: void
                    552: iwi_free_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
                    553: {
                    554:        struct iwi_tx_data *data;
                    555:        int i;
                    556:
                    557:        if (ring->map != NULL) {
                    558:                if (ring->desc != NULL) {
                    559:                        bus_dmamap_unload(sc->sc_dmat, ring->map);
                    560:                        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
                    561:                            sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT);
                    562:                        bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
                    563:                }
                    564:                bus_dmamap_destroy(sc->sc_dmat, ring->map);
                    565:        }
                    566:
                    567:        for (i = 0; i < IWI_TX_RING_COUNT; i++) {
                    568:                data = &ring->data[i];
                    569:
                    570:                if (data->m != NULL) {
                    571:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                    572:                        m_freem(data->m);
                    573:                }
                    574:                bus_dmamap_destroy(sc->sc_dmat, data->map);
                    575:        }
                    576: }
                    577:
                    578: int
                    579: iwi_alloc_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
                    580: {
                    581:        struct iwi_rx_data *data;
                    582:        int i, error;
                    583:
                    584:        ring->cur = 0;
                    585:
                    586:        for (i = 0; i < IWI_RX_RING_COUNT; i++) {
                    587:                data = &sc->rxq.data[i];
                    588:
                    589:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
                    590:                    0, BUS_DMA_NOWAIT, &data->map);
                    591:                if (error != 0) {
                    592:                        printf("%s: could not create rx buf DMA map\n",
                    593:                            sc->sc_dev.dv_xname);
                    594:                        goto fail;
                    595:                }
                    596:
                    597:                MGETHDR(data->m, M_DONTWAIT, MT_DATA);
                    598:                if (data->m == NULL) {
                    599:                        printf("%s: could not allocate rx mbuf\n",
                    600:                            sc->sc_dev.dv_xname);
                    601:                        error = ENOMEM;
                    602:                        goto fail;
                    603:                }
                    604:
                    605:                MCLGET(data->m, M_DONTWAIT);
                    606:                if (!(data->m->m_flags & M_EXT)) {
                    607:                        m_freem(data->m);
                    608:                        data->m = NULL;
                    609:                        printf("%s: could not allocate rx mbuf cluster\n",
                    610:                            sc->sc_dev.dv_xname);
                    611:                        error = ENOMEM;
                    612:                        goto fail;
                    613:                }
                    614:
                    615:                error = bus_dmamap_load(sc->sc_dmat, data->map,
                    616:                    mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
                    617:                if (error != 0) {
                    618:                        printf("%s: could not load rx buf DMA map\n",
                    619:                            sc->sc_dev.dv_xname);
                    620:                        goto fail;
                    621:                }
                    622:
                    623:                data->reg = IWI_CSR_RX_BASE + i * 4;
                    624:        }
                    625:
                    626:        return 0;
                    627:
                    628: fail:  iwi_free_rx_ring(sc, ring);
                    629:        return error;
                    630: }
                    631:
                    632: void
                    633: iwi_reset_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
                    634: {
                    635:        ring->cur = 0;
                    636: }
                    637:
                    638: void
                    639: iwi_free_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
                    640: {
                    641:        struct iwi_rx_data *data;
                    642:        int i;
                    643:
                    644:        for (i = 0; i < IWI_RX_RING_COUNT; i++) {
                    645:                data = &sc->rxq.data[i];
                    646:
                    647:                if (data->m != NULL) {
                    648:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                    649:                        m_freem(data->m);
                    650:                }
                    651:                bus_dmamap_destroy(sc->sc_dmat, data->map);
                    652:        }
                    653: }
                    654:
                    655: int
                    656: iwi_media_change(struct ifnet *ifp)
                    657: {
                    658:        int error;
                    659:
                    660:        error = ieee80211_media_change(ifp);
                    661:        if (error != ENETRESET)
                    662:                return error;
                    663:
                    664:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
                    665:                iwi_init(ifp);
                    666:
                    667:        return 0;
                    668: }
                    669:
                    670: void
                    671: iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
                    672: {
                    673:        struct iwi_softc *sc = ifp->if_softc;
                    674:        struct ieee80211com *ic = &sc->sc_ic;
                    675:        uint32_t val;
                    676:        int rate;
                    677:
                    678:        imr->ifm_status = IFM_AVALID;
                    679:        imr->ifm_active = IFM_IEEE80211;
                    680:        if (ic->ic_state == IEEE80211_S_RUN)
                    681:                imr->ifm_status |= IFM_ACTIVE;
                    682:
                    683:        /* read current transmission rate from adapter */
                    684:        val = CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE);
                    685:        /* convert PLCP signal to 802.11 rate */
                    686:        rate = iwi_rate(val);
                    687:
                    688:        imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
                    689:        switch (ic->ic_opmode) {
                    690:        case IEEE80211_M_STA:
                    691:                break;
                    692:        case IEEE80211_M_IBSS:
                    693:                imr->ifm_active |= IFM_IEEE80211_ADHOC;
                    694:                break;
                    695:        case IEEE80211_M_MONITOR:
                    696:                imr->ifm_active |= IFM_IEEE80211_MONITOR;
                    697:                break;
                    698:        case IEEE80211_M_AHDEMO:
                    699:        case IEEE80211_M_HOSTAP:
                    700:                /* should not get there */
                    701:                break;
                    702:        }
                    703: }
                    704:
                    705: /*
                    706:  * This is only used for IBSS mode where the firmware expect an index to an
                    707:  * internal node table instead of a destination address.
                    708:  */
                    709: int
                    710: iwi_find_txnode(struct iwi_softc *sc, const uint8_t *macaddr)
                    711: {
                    712:        struct iwi_node node;
                    713:        int i;
                    714:
                    715:        for (i = 0; i < sc->nsta; i++)
                    716:                if (IEEE80211_ADDR_EQ(sc->sta[i], macaddr))
                    717:                        return i;       /* already existing node */
                    718:
                    719:        if (i == IWI_MAX_NODE)
                    720:                return -1;      /* no place left in neighbor table */
                    721:
                    722:        /* save this new node in our softc table */
                    723:        IEEE80211_ADDR_COPY(sc->sta[i], macaddr);
                    724:        sc->nsta = i;
                    725:
                    726:        /* write node information into NIC memory */
                    727:        bzero(&node, sizeof node);
                    728:        IEEE80211_ADDR_COPY(node.bssid, macaddr);
                    729:
                    730:        CSR_WRITE_REGION_1(sc, IWI_CSR_NODE_BASE + i * sizeof node,
                    731:            (uint8_t *)&node, sizeof node);
                    732:
                    733:        return i;
                    734: }
                    735:
                    736: int
                    737: iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                    738: {
                    739:        struct iwi_softc *sc = ic->ic_softc;
                    740:        enum ieee80211_state ostate;
                    741:        uint32_t tmp;
                    742:
                    743:        ostate = ic->ic_state;
                    744:
                    745:        switch (nstate) {
                    746:        case IEEE80211_S_SCAN:
                    747:                iwi_scan(sc);
                    748:                break;
                    749:
                    750:        case IEEE80211_S_AUTH:
                    751:                iwi_auth_and_assoc(sc);
                    752:                break;
                    753:
                    754:        case IEEE80211_S_RUN:
                    755:                if (ic->ic_opmode == IEEE80211_M_IBSS) {
                    756:                        sc->nsta = 0;   /* flush IBSS nodes */
                    757:                        ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
                    758:                } else if (ic->ic_opmode == IEEE80211_M_MONITOR)
                    759:                        iwi_set_chan(sc, ic->ic_ibss_chan);
                    760:
                    761:                /* assoc led on */
                    762:                tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
                    763:                MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp | IWI_LED_ASSOC);
                    764:                break;
                    765:
                    766:        case IEEE80211_S_INIT:
                    767:                if (ostate != IEEE80211_S_RUN)
                    768:                        break;
                    769:
                    770:                /* assoc led off */
                    771:                tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
                    772:                MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp & ~IWI_LED_ASSOC);
                    773:                break;
                    774:
                    775:        case IEEE80211_S_ASSOC:
                    776:                break;
                    777:        }
                    778:
                    779:        ic->ic_state = nstate;
                    780:        return 0;
                    781: }
                    782:
                    783: /*
                    784:  * Read 16 bits at address 'addr' from the serial EEPROM.
                    785:  * DON'T PLAY WITH THIS CODE UNLESS YOU KNOW *EXACTLY* WHAT YOU'RE DOING!
                    786:  */
                    787: uint16_t
                    788: iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr)
                    789: {
                    790:        uint32_t tmp;
                    791:        uint16_t val;
                    792:        int n;
                    793:
                    794:        /* clock C once before the first command */
                    795:        IWI_EEPROM_CTL(sc, 0);
                    796:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    797:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
                    798:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    799:
                    800:        /* write start bit (1) */
                    801:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
                    802:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
                    803:
                    804:        /* write READ opcode (10) */
                    805:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
                    806:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
                    807:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    808:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
                    809:
                    810:        /* write address A7-A0 */
                    811:        for (n = 7; n >= 0; n--) {
                    812:                IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
                    813:                    (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D));
                    814:                IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
                    815:                    (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D) | IWI_EEPROM_C);
                    816:        }
                    817:
                    818:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    819:
                    820:        /* read data Q15-Q0 */
                    821:        val = 0;
                    822:        for (n = 15; n >= 0; n--) {
                    823:                IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
                    824:                IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    825:                tmp = MEM_READ_4(sc, IWI_MEM_EEPROM_CTL);
                    826:                val |= ((tmp & IWI_EEPROM_Q) >> IWI_EEPROM_SHIFT_Q) << n;
                    827:        }
                    828:
                    829:        IWI_EEPROM_CTL(sc, 0);
                    830:
                    831:        /* clear Chip Select and clock C */
                    832:        IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
                    833:        IWI_EEPROM_CTL(sc, 0);
                    834:        IWI_EEPROM_CTL(sc, IWI_EEPROM_C);
                    835:
                    836:        return val;
                    837: }
                    838:
                    839: uint8_t
                    840: iwi_rate(int plcp)
                    841: {
                    842:        switch (plcp) {
                    843:        /* CCK rates (values are device-dependent) */
                    844:        case  10:       return 2;
                    845:        case  20:       return 4;
                    846:        case  55:       return 11;
                    847:        case 110:       return 22;
                    848:
                    849:        /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
                    850:        case 0xd:       return 12;
                    851:        case 0xf:       return 18;
                    852:        case 0x5:       return 24;
                    853:        case 0x7:       return 36;
                    854:        case 0x9:       return 48;
                    855:        case 0xb:       return 72;
                    856:        case 0x1:       return 96;
                    857:        case 0x3:       return 108;
                    858:
                    859:        /* unknown rate: should not happen */
                    860:        default:        return 0;
                    861:        }
                    862: }
                    863:
                    864: void
                    865: iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
                    866:     struct iwi_frame *frame)
                    867: {
                    868:        struct ieee80211com *ic = &sc->sc_ic;
                    869:        struct ifnet *ifp = &ic->ic_if;
                    870:        struct mbuf *mnew, *m;
                    871:        struct ieee80211_frame *wh;
                    872:        struct ieee80211_node *ni;
                    873:        int error;
                    874:
                    875:        DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u\n",
                    876:            letoh16(frame->len), frame->chan, frame->rssi_dbm));
                    877:
                    878:        if (letoh16(frame->len) < sizeof (struct ieee80211_frame_min) ||
                    879:            letoh16(frame->len) > MCLBYTES) {
                    880:                DPRINTF(("%s: bad frame length\n", sc->sc_dev.dv_xname));
                    881:                ifp->if_ierrors++;
                    882:                return;
                    883:        }
                    884:
                    885:        /*
                    886:         * Try to allocate a new mbuf for this ring element and load it before
                    887:         * processing the current mbuf.  If the ring element cannot be loaded,
                    888:         * drop the received packet and reuse the old mbuf.  In the unlikely
                    889:         * case that the old mbuf can't be reloaded either, explicitly panic.
                    890:         */
                    891:        MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                    892:        if (mnew == NULL) {
                    893:                ifp->if_ierrors++;
                    894:                return;
                    895:        }
                    896:
                    897:        MCLGET(mnew, M_DONTWAIT);
                    898:        if (!(mnew->m_flags & M_EXT)) {
                    899:                m_freem(mnew);
                    900:                ifp->if_ierrors++;
                    901:                return;
                    902:        }
                    903:
                    904:        bus_dmamap_unload(sc->sc_dmat, data->map);
                    905:
                    906:        error = bus_dmamap_load(sc->sc_dmat, data->map, mtod(mnew, void *),
                    907:            MCLBYTES, NULL, BUS_DMA_NOWAIT);
                    908:        if (error != 0) {
                    909:                m_freem(mnew);
                    910:
                    911:                /* try to reload the old mbuf */
                    912:                error = bus_dmamap_load(sc->sc_dmat, data->map,
                    913:                    mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
                    914:                if (error != 0) {
                    915:                        /* very unlikely that it will fail... */
                    916:                        panic("%s: could not load old rx mbuf",
                    917:                            sc->sc_dev.dv_xname);
                    918:                }
                    919:                ifp->if_ierrors++;
                    920:                return;
                    921:        }
                    922:
                    923:        m = data->m;
                    924:        data->m = mnew;
                    925:        CSR_WRITE_4(sc, data->reg, data->map->dm_segs[0].ds_addr);
                    926:
                    927:        /* finalize mbuf */
                    928:        m->m_pkthdr.rcvif = ifp;
                    929:        m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) +
                    930:            sizeof (struct iwi_frame) + letoh16(frame->len);
                    931:        m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
                    932:
                    933:        wh = mtod(m, struct ieee80211_frame *);
                    934:
                    935:        if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
                    936:            ic->ic_opmode != IEEE80211_M_MONITOR) {
                    937:                /*
                    938:                 * Hardware decrypts the frame itself but leaves the WEP bit
                    939:                 * set in the 802.11 header and doesn't remove the IV and CRC
                    940:                 * fields.
                    941:                 */
                    942:                wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
                    943:                ovbcopy(wh, (char *)wh + IEEE80211_WEP_IVLEN +
                    944:                    IEEE80211_WEP_KIDLEN, sizeof (struct ieee80211_frame));
                    945:                m_adj(m, IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN);
                    946:                m_adj(m, -IEEE80211_WEP_CRCLEN);
                    947:                wh = mtod(m, struct ieee80211_frame *);
                    948:        }
                    949:
                    950: #if NBPFILTER > 0
                    951:        if (sc->sc_drvbpf != NULL) {
                    952:                struct mbuf mb;
                    953:                struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
                    954:
                    955:                tap->wr_flags = 0;
                    956:                tap->wr_rate = iwi_rate(frame->rate);
                    957:                tap->wr_chan_freq =
                    958:                    htole16(ic->ic_channels[frame->chan].ic_freq);
                    959:                tap->wr_chan_flags =
                    960:                    htole16(ic->ic_channels[frame->chan].ic_flags);
                    961:                tap->wr_antsignal = frame->signal;
                    962:                tap->wr_antenna = frame->antenna & 0x3;
                    963:                if (frame->antenna & 0x40)
                    964:                        tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
                    965:
                    966:                mb.m_data = (caddr_t)tap;
                    967:                mb.m_len = sc->sc_rxtap_len;
                    968:                mb.m_next = m;
                    969:                mb.m_nextpkt = NULL;
                    970:                mb.m_type = 0;
                    971:                mb.m_flags = 0;
                    972:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
                    973:        }
                    974: #endif
                    975:
                    976:        ni = ieee80211_find_rxnode(ic, wh);
                    977:
                    978:        /* send the frame to the upper layer */
                    979:        ieee80211_input(ifp, m, ni, frame->rssi_dbm, 0);
                    980:
                    981:        /* node is no longer needed */
                    982:        ieee80211_release_node(ic, ni);
                    983: }
                    984:
                    985: void
                    986: iwi_notification_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
                    987:     struct iwi_notif *notif)
                    988: {
                    989:        struct ieee80211com *ic = &sc->sc_ic;
                    990:        struct ifnet *ifp = &ic->ic_if;
                    991:
                    992:        switch (notif->type) {
                    993:        case IWI_NOTIF_TYPE_SCAN_CHANNEL:
                    994:        {
                    995: #ifdef IWI_DEBUG
                    996:                struct iwi_notif_scan_channel *chan =
                    997:                    (struct iwi_notif_scan_channel *)(notif + 1);
                    998: #endif
                    999:                DPRINTFN(2, ("Scanning channel (%u)\n", chan->nchan));
                   1000:                break;
                   1001:        }
                   1002:        case IWI_NOTIF_TYPE_SCAN_COMPLETE:
                   1003:        {
                   1004: #ifdef IWI_DEBUG
                   1005:                struct iwi_notif_scan_complete *scan =
                   1006:                    (struct iwi_notif_scan_complete *)(notif + 1);
                   1007: #endif
                   1008:                DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
                   1009:                    scan->status));
                   1010:
                   1011:                /* monitor mode uses scan to set the channel ... */
                   1012:                if (ic->ic_opmode != IEEE80211_M_MONITOR)
                   1013:                        ieee80211_end_scan(ifp);
                   1014:                else
                   1015:                        iwi_set_chan(sc, ic->ic_ibss_chan);
                   1016:                break;
                   1017:        }
                   1018:        case IWI_NOTIF_TYPE_AUTHENTICATION:
                   1019:        {
                   1020:                struct iwi_notif_authentication *auth =
                   1021:                    (struct iwi_notif_authentication *)(notif + 1);
                   1022:
                   1023:                DPRINTFN(2, ("Authentication (%u)\n", auth->state));
                   1024:
                   1025:                switch (auth->state) {
                   1026:                case IWI_AUTHENTICATED:
                   1027:                        ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
                   1028:                        break;
                   1029:
                   1030:                case IWI_DEAUTHENTICATED:
                   1031:                        break;
                   1032:
                   1033:                default:
                   1034:                        printf("%s: unknown authentication state %u\n",
                   1035:                            sc->sc_dev.dv_xname, auth->state);
                   1036:                }
                   1037:                break;
                   1038:        }
                   1039:        case IWI_NOTIF_TYPE_ASSOCIATION:
                   1040:        {
                   1041:                struct iwi_notif_association *assoc =
                   1042:                    (struct iwi_notif_association *)(notif + 1);
                   1043:
                   1044:                DPRINTFN(2, ("Association (%u, %u)\n", assoc->state,
                   1045:                    assoc->status));
                   1046:
                   1047:                switch (assoc->state) {
                   1048:                case IWI_AUTHENTICATED:
                   1049:                        /* re-association, do nothing */
                   1050:                        break;
                   1051:
                   1052:                case IWI_ASSOCIATED:
                   1053:                        ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   1054:                        break;
                   1055:
                   1056:                case IWI_DEASSOCIATED:
                   1057:                        ieee80211_begin_scan(ifp);
                   1058:                        break;
                   1059:
                   1060:                default:
                   1061:                        printf("%s: unknown association state %u\n",
                   1062:                            sc->sc_dev.dv_xname, assoc->state);
                   1063:                }
                   1064:                break;
                   1065:        }
                   1066:        case IWI_NOTIF_TYPE_BEACON:
                   1067:        {
                   1068:                struct iwi_notif_beacon *beacon =
                   1069:                    (struct iwi_notif_beacon *)(notif + 1);
                   1070:
                   1071:                if (letoh32(beacon->status) == IWI_BEACON_MISSED) {
                   1072:                        /* XXX should roam when too many beacons missed */
                   1073:                        DPRINTFN(2, ("%s: %u beacon(s) missed\n",
                   1074:                            sc->sc_dev.dv_xname, letoh32(beacon->count)));
                   1075:                }
                   1076:                break;
                   1077:        }
                   1078:        case IWI_NOTIF_TYPE_BAD_LINK:
                   1079:                DPRINTFN(2, ("link deterioration detected\n"));
                   1080:                break;
                   1081:
                   1082:        case IWI_NOTIF_TYPE_NOISE:
                   1083:                DPRINTFN(5, ("Measured noise %u\n",
                   1084:                    letoh32(*(uint32_t *)(notif + 1)) & 0xff));
                   1085:                break;
                   1086:
                   1087:        default:
                   1088:                DPRINTFN(5, ("Notification (%u)\n", notif->type));
                   1089:        }
                   1090: }
                   1091:
                   1092: void
                   1093: iwi_rx_intr(struct iwi_softc *sc)
                   1094: {
                   1095:        struct iwi_rx_data *data;
                   1096:        struct iwi_hdr *hdr;
                   1097:        uint32_t hw;
                   1098:
                   1099:        hw = CSR_READ_4(sc, IWI_CSR_RX_RIDX);
                   1100:
                   1101:        for (; sc->rxq.cur != hw;) {
                   1102:                data = &sc->rxq.data[sc->rxq.cur];
                   1103:
                   1104:                bus_dmamap_sync(sc->sc_dmat, data->map, 0, MCLBYTES,
                   1105:                    BUS_DMASYNC_POSTREAD);
                   1106:
                   1107:                hdr = mtod(data->m, struct iwi_hdr *);
                   1108:
                   1109:                switch (hdr->type) {
                   1110:                case IWI_HDR_TYPE_FRAME:
                   1111:                        iwi_frame_intr(sc, data,
                   1112:                            (struct iwi_frame *)(hdr + 1));
                   1113:                        break;
                   1114:
                   1115:                case IWI_HDR_TYPE_NOTIF:
                   1116:                        iwi_notification_intr(sc, data,
                   1117:                            (struct iwi_notif *)(hdr + 1));
                   1118:                        break;
                   1119:
                   1120:                default:
                   1121:                        printf("%s: unknown hdr type %u\n",
                   1122:                            sc->sc_dev.dv_xname, hdr->type);
                   1123:                }
                   1124:
                   1125:                sc->rxq.cur = (sc->rxq.cur + 1) % IWI_RX_RING_COUNT;
                   1126:        }
                   1127:
                   1128:        /* tell the firmware what we have processed */
                   1129:        hw = (hw == 0) ? IWI_RX_RING_COUNT - 1 : hw - 1;
                   1130:        CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, hw);
                   1131: }
                   1132:
                   1133: void
                   1134: iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
                   1135: {
                   1136:        struct ieee80211com *ic = &sc->sc_ic;
                   1137:        struct ifnet *ifp = &ic->ic_if;
                   1138:        struct iwi_tx_data *data;
                   1139:        uint32_t hw;
                   1140:
                   1141:        hw = CSR_READ_4(sc, txq->csr_ridx);
                   1142:
                   1143:        for (; txq->next != hw;) {
                   1144:                data = &txq->data[txq->next];
                   1145:
                   1146:                bus_dmamap_unload(sc->sc_dmat, data->map);
                   1147:                m_freem(data->m);
                   1148:                data->m = NULL;
                   1149:                ieee80211_release_node(ic, data->ni);
                   1150:                data->ni = NULL;
                   1151:
                   1152:                ifp->if_opackets++;
                   1153:
                   1154:                txq->queued--;
                   1155:                txq->next = (txq->next + 1) % IWI_TX_RING_COUNT;
                   1156:        }
                   1157:
                   1158:        sc->sc_tx_timer = 0;
                   1159:        ifp->if_flags &= ~IFF_OACTIVE;
                   1160:        (*ifp->if_start)(ifp);
                   1161: }
                   1162:
                   1163: int
                   1164: iwi_intr(void *arg)
                   1165: {
                   1166:        struct iwi_softc *sc = arg;
                   1167:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   1168:        uint32_t r;
                   1169:
                   1170:        if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff)
                   1171:                return 0;
                   1172:
                   1173:        /* disable interrupts */
                   1174:        CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
                   1175:
                   1176:        /* acknowledge interrupts */
                   1177:        CSR_WRITE_4(sc, IWI_CSR_INTR, r);
                   1178:
                   1179:        if (r & IWI_INTR_FATAL_ERROR) {
                   1180:                printf("%s: fatal firmware error\n", sc->sc_dev.dv_xname);
                   1181:                ifp->if_flags &= ~IFF_UP;
                   1182:                iwi_stop(ifp, 1);
                   1183:                return 1;
                   1184:        }
                   1185:
                   1186:        if (r & IWI_INTR_FW_INITED)
                   1187:                wakeup(sc);
                   1188:
                   1189:        if (r & IWI_INTR_RADIO_OFF) {
                   1190:                DPRINTF(("radio transmitter off\n"));
                   1191:                ifp->if_flags &= ~IFF_UP;
                   1192:                iwi_stop(ifp, 1);
                   1193:                return 1;
                   1194:        }
                   1195:
                   1196:        if (r & IWI_INTR_CMD_DONE) {
                   1197:                /* kick next pending command if any */
                   1198:                sc->cmdq.next = (sc->cmdq.next + 1) % IWI_CMD_RING_COUNT;
                   1199:                if (--sc->cmdq.queued > 0)
                   1200:                        CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.next);
                   1201:
                   1202:                wakeup(sc);
                   1203:        }
                   1204:
                   1205:        if (r & IWI_INTR_TX1_DONE)
                   1206:                iwi_tx_intr(sc, &sc->txq[0]);
                   1207:
                   1208:        if (r & IWI_INTR_TX2_DONE)
                   1209:                iwi_tx_intr(sc, &sc->txq[1]);
                   1210:
                   1211:        if (r & IWI_INTR_TX3_DONE)
                   1212:                iwi_tx_intr(sc, &sc->txq[2]);
                   1213:
                   1214:        if (r & IWI_INTR_TX4_DONE)
                   1215:                iwi_tx_intr(sc, &sc->txq[3]);
                   1216:
                   1217:        if (r & IWI_INTR_RX_DONE)
                   1218:                iwi_rx_intr(sc);
                   1219:
                   1220:        /* re-enable interrupts */
                   1221:        CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
                   1222:
                   1223:        return 1;
                   1224: }
                   1225:
                   1226: int
                   1227: iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len, int async)
                   1228: {
                   1229:        struct iwi_cmd_desc *desc;
                   1230:
                   1231:        desc = &sc->cmdq.desc[sc->cmdq.cur];
                   1232:        desc->hdr.type = IWI_HDR_TYPE_COMMAND;
                   1233:        desc->hdr.flags = IWI_HDR_FLAG_IRQ;
                   1234:        desc->type = type;
                   1235:        desc->len = len;
                   1236:        bcopy(data, desc->data, len);
                   1237:
                   1238:        bus_dmamap_sync(sc->sc_dmat, sc->cmdq.map,
                   1239:            sc->cmdq.cur * sizeof (struct iwi_cmd_desc),
                   1240:            sizeof (struct iwi_cmd_desc), BUS_DMASYNC_PREWRITE);
                   1241:
                   1242:        DPRINTFN(2, ("sending command idx=%u type=%u len=%u\n", sc->cmdq.cur,
                   1243:            type, len));
                   1244:
                   1245:        sc->cmdq.cur = (sc->cmdq.cur + 1) % IWI_CMD_RING_COUNT;
                   1246:
                   1247:        /* don't kick cmd immediately if another async command is pending */
                   1248:        if (++sc->cmdq.queued == 1) {
                   1249:                sc->cmdq.next = sc->cmdq.cur;
                   1250:                CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.next);
                   1251:        }
                   1252:
                   1253:        return async ? 0 : tsleep(sc, 0, "iwicmd", hz);
                   1254: }
                   1255:
                   1256: int
                   1257: iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
                   1258: {
                   1259:        struct iwi_softc *sc = ifp->if_softc;
                   1260:        struct ieee80211com *ic = &sc->sc_ic;
                   1261:        struct iwi_tx_data *data;
                   1262:        struct iwi_tx_desc *desc;
                   1263:        struct iwi_tx_ring *txq = &sc->txq[0];
                   1264:        struct mbuf *mnew;
                   1265:        int error, i, station = 0;
                   1266:
                   1267: #if NBPFILTER > 0
                   1268:        if (sc->sc_drvbpf != NULL) {
                   1269:                struct mbuf mb;
                   1270:                struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
                   1271:
                   1272:                tap->wt_flags = 0;
                   1273:                tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   1274:                tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1275:
                   1276:                mb.m_data = (caddr_t)tap;
                   1277:                mb.m_len = sc->sc_txtap_len;
                   1278:                mb.m_next = m0;
                   1279:                mb.m_nextpkt = NULL;
                   1280:                mb.m_type = 0;
                   1281:                mb.m_flags = 0;
                   1282:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
                   1283:        }
                   1284: #endif
                   1285:
                   1286:        data = &txq->data[txq->cur];
                   1287:        desc = &txq->desc[txq->cur];
                   1288:
                   1289:        /* save and trim IEEE802.11 header */
                   1290:        m_copydata(m0, 0, sizeof (struct ieee80211_frame), (caddr_t)&desc->wh);
                   1291:        m_adj(m0, sizeof (struct ieee80211_frame));
                   1292:
                   1293:        if (ic->ic_opmode == IEEE80211_M_IBSS) {
                   1294:                station = iwi_find_txnode(sc, desc->wh.i_addr1);
                   1295:                if (station == -1) {
                   1296:                        m_freem(m0);
                   1297:                        ieee80211_release_node(ic, ni);
                   1298:                        ifp->if_oerrors++;
                   1299:                        return 0;
                   1300:                }
                   1301:        }
                   1302:
                   1303:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
                   1304:            BUS_DMA_NOWAIT);
                   1305:        if (error != 0 && error != EFBIG) {
                   1306:                printf("%s: could not map mbuf (error %d)\n",
                   1307:                    sc->sc_dev.dv_xname, error);
                   1308:                m_freem(m0);
                   1309:                return error;
                   1310:        }
                   1311:        if (error != 0) {
                   1312:                /* too many fragments, linearize */
                   1313:
                   1314:                MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                   1315:                if (mnew == NULL) {
                   1316:                        m_freem(m0);
                   1317:                        return ENOMEM;
                   1318:                }
                   1319:
                   1320:                M_DUP_PKTHDR(mnew, m0);
                   1321:                if (m0->m_pkthdr.len > MHLEN) {
                   1322:                        MCLGET(mnew, M_DONTWAIT);
                   1323:                        if (!(mnew->m_flags & M_EXT)) {
                   1324:                                m_freem(m0);
                   1325:                                m_freem(mnew);
                   1326:                                return ENOMEM;
                   1327:                        }
                   1328:                }
                   1329:
                   1330:                m_copydata(m0, 0, m0->m_pkthdr.len, mtod(mnew, caddr_t));
                   1331:                m_freem(m0);
                   1332:                mnew->m_len = mnew->m_pkthdr.len;
                   1333:                m0 = mnew;
                   1334:
                   1335:                error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
                   1336:                    BUS_DMA_NOWAIT);
                   1337:                if (error != 0) {
                   1338:                        printf("%s: could not map mbuf (error %d)\n",
                   1339:                            sc->sc_dev.dv_xname, error);
                   1340:                        m_freem(m0);
                   1341:                        return error;
                   1342:                }
                   1343:        }
                   1344:
                   1345:        data->m = m0;
                   1346:        data->ni = ni;
                   1347:
                   1348:        desc->hdr.type = IWI_HDR_TYPE_DATA;
                   1349:        desc->hdr.flags = IWI_HDR_FLAG_IRQ;
                   1350:        desc->cmd = IWI_DATA_CMD_TX;
                   1351:        desc->len = htole16(m0->m_pkthdr.len);
                   1352:        desc->station = station;
                   1353:        desc->flags = 0;
                   1354:        desc->xflags = 0;
                   1355:
                   1356:        if (!IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
                   1357:                desc->flags |= IWI_DATA_FLAG_NEED_ACK;
                   1358:
                   1359:        if (desc->wh.i_fc[1] & IEEE80211_FC1_WEP) {
                   1360:                desc->wep_txkey = ic->ic_wep_txkey |
                   1361:                    ((ic->ic_nw_keys[ic->ic_wep_txkey].k_cipher ==
                   1362:                        IEEE80211_CIPHER_WEP40) ? IWI_DATA_KEY_WEP40 :
                   1363:                    IWI_DATA_KEY_WEP104);
                   1364:        } else {
                   1365:                desc->flags |= IWI_DATA_FLAG_NO_WEP;
                   1366:                desc->wep_txkey = 0;
                   1367:        }
                   1368:        if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
                   1369:                desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
                   1370:
                   1371:        if (ic->ic_curmode == IEEE80211_MODE_11B)
                   1372:                desc->xflags |= IWI_DATA_XFLAG_CCK;
                   1373:
                   1374:        desc->nseg = htole32(data->map->dm_nsegs);
                   1375:        for (i = 0; i < data->map->dm_nsegs; i++) {
                   1376:                desc->seg_addr[i] = htole32(data->map->dm_segs[i].ds_addr);
                   1377:                desc->seg_len[i]  = htole16(data->map->dm_segs[i].ds_len);
                   1378:        }
                   1379:
                   1380:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                   1381:            BUS_DMASYNC_PREWRITE);
                   1382:        bus_dmamap_sync(sc->sc_dmat, txq->map,
                   1383:            txq->cur * sizeof (struct iwi_tx_desc),
                   1384:            sizeof (struct iwi_tx_desc), BUS_DMASYNC_PREWRITE);
                   1385:
                   1386:        DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", txq->cur,
                   1387:            letoh16(desc->len), data->map->dm_nsegs));
                   1388:
                   1389:        txq->queued++;
                   1390:        txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT;
                   1391:        CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
                   1392:
                   1393:        return 0;
                   1394: }
                   1395:
                   1396: void
                   1397: iwi_start(struct ifnet *ifp)
                   1398: {
                   1399:        struct iwi_softc *sc = ifp->if_softc;
                   1400:        struct ieee80211com *ic = &sc->sc_ic;
                   1401:        struct mbuf *m0;
                   1402:        struct ieee80211_node *ni;
                   1403:
                   1404:        if (ic->ic_state != IEEE80211_S_RUN)
                   1405:                return;
                   1406:
                   1407:        for (;;) {
                   1408:                IFQ_POLL(&ifp->if_snd, m0);
                   1409:                if (m0 == NULL)
                   1410:                        break;
                   1411:
                   1412:                if (sc->txq[0].queued >= IWI_TX_RING_COUNT - 8) {
                   1413:                        ifp->if_flags |= IFF_OACTIVE;
                   1414:                        break;
                   1415:                }
                   1416:                IFQ_DEQUEUE(&ifp->if_snd, m0);
                   1417: #if NBPFILTER > 0
                   1418:                if (ifp->if_bpf != NULL)
                   1419:                        bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   1420: #endif
                   1421:
                   1422:                m0 = ieee80211_encap(ifp, m0, &ni);
                   1423:                if (m0 == NULL)
                   1424:                        continue;
                   1425:
                   1426: #if NBPFILTER > 0
                   1427:                if (ic->ic_rawbpf != NULL)
                   1428:                        bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   1429: #endif
                   1430:
                   1431:                if (iwi_tx_start(ifp, m0, ni) != 0) {
                   1432:                        if (ni != NULL)
                   1433:                                ieee80211_release_node(ic, ni);
                   1434:                        ifp->if_oerrors++;
                   1435:                        break;
                   1436:                }
                   1437:
                   1438:                /* start watchdog timer */
                   1439:                sc->sc_tx_timer = 5;
                   1440:                ifp->if_timer = 1;
                   1441:        }
                   1442: }
                   1443:
                   1444: void
                   1445: iwi_watchdog(struct ifnet *ifp)
                   1446: {
                   1447:        struct iwi_softc *sc = ifp->if_softc;
                   1448:
                   1449:        ifp->if_timer = 0;
                   1450:
                   1451:        if (sc->sc_tx_timer > 0) {
                   1452:                if (--sc->sc_tx_timer == 0) {
                   1453:                        printf("%s: device timeout\n", sc->sc_dev.dv_xname);
                   1454:                        ifp->if_flags &= ~IFF_UP;
                   1455:                        iwi_stop(ifp, 1);
                   1456:                        ifp->if_oerrors++;
                   1457:                        return;
                   1458:                }
                   1459:                ifp->if_timer = 1;
                   1460:        }
                   1461:
                   1462:        ieee80211_watchdog(ifp);
                   1463: }
                   1464:
                   1465: int
                   1466: iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                   1467: {
                   1468:        struct iwi_softc *sc = ifp->if_softc;
                   1469:        struct ieee80211com *ic = &sc->sc_ic;
                   1470:        struct ifaddr *ifa;
                   1471:        struct ifreq *ifr;
                   1472:        int s, error = 0;
                   1473:
                   1474:        s = splnet();
                   1475:
                   1476:        switch (cmd) {
                   1477:        case SIOCSIFADDR:
                   1478:                ifa = (struct ifaddr *)data;
                   1479:                ifp->if_flags |= IFF_UP;
                   1480: #ifdef INET
                   1481:                if (ifa->ifa_addr->sa_family == AF_INET)
                   1482:                        arp_ifinit(&ic->ic_ac, ifa);
                   1483: #endif
                   1484:                /* FALLTHROUGH */
                   1485:        case SIOCSIFFLAGS:
                   1486:                if (ifp->if_flags & IFF_UP) {
                   1487:                        if (!(ifp->if_flags & IFF_RUNNING))
                   1488:                                iwi_init(ifp);
                   1489:                } else {
                   1490:                        if (ifp->if_flags & IFF_RUNNING)
                   1491:                                iwi_stop(ifp, 1);
                   1492:                }
                   1493:                break;
                   1494:
                   1495:        case SIOCADDMULTI:
                   1496:        case SIOCDELMULTI:
                   1497:                ifr = (struct ifreq *)data;
                   1498:                error = (cmd == SIOCADDMULTI) ?
                   1499:                    ether_addmulti(ifr, &ic->ic_ac) :
                   1500:                    ether_delmulti(ifr, &ic->ic_ac);
                   1501:
                   1502:                if (error == ENETRESET)
                   1503:                        error = 0;
                   1504:                break;
                   1505:
                   1506:        case SIOCG80211TXPOWER:
                   1507:                /*
                   1508:                 * If the hardware radio transmitter switch is off, report a
                   1509:                 * tx power of IEEE80211_TXPOWER_MIN to indicate that radio
                   1510:                 * transmitter is killed.
                   1511:                 */
                   1512:                ((struct ieee80211_txpower *)data)->i_val =
                   1513:                    (CSR_READ_4(sc, IWI_CSR_IO) & IWI_IO_RADIO_ENABLED) ?
                   1514:                    sc->sc_ic.ic_txpower : IEEE80211_TXPOWER_MIN;
                   1515:                break;
                   1516:
                   1517:        default:
                   1518:                error = ieee80211_ioctl(ifp, cmd, data);
                   1519:        }
                   1520:
                   1521:        if (error == ENETRESET) {
                   1522:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1523:                    (IFF_UP | IFF_RUNNING))
                   1524:                        iwi_init(ifp);
                   1525:                error = 0;
                   1526:        }
                   1527:
                   1528:        splx(s);
                   1529:        return error;
                   1530: }
                   1531:
                   1532: void
                   1533: iwi_stop_master(struct iwi_softc *sc)
                   1534: {
                   1535:        int ntries;
                   1536:
                   1537:        /* disable interrupts */
                   1538:        CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
                   1539:
                   1540:        CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
                   1541:        for (ntries = 0; ntries < 5; ntries++) {
                   1542:                if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
                   1543:                        break;
                   1544:                DELAY(10);
                   1545:        }
                   1546:        if (ntries == 5) {
                   1547:                printf("%s: timeout waiting for master\n",
                   1548:                    sc->sc_dev.dv_xname);
                   1549:        }
                   1550:
                   1551:        CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
                   1552:            IWI_RST_PRINCETON_RESET);
                   1553:
                   1554:        sc->flags &= ~IWI_FLAG_FW_INITED;
                   1555: }
                   1556:
                   1557: int
                   1558: iwi_reset(struct iwi_softc *sc)
                   1559: {
                   1560:        int i, ntries;
                   1561:
                   1562:        iwi_stop_master(sc);
                   1563:
                   1564:        /* move adapter to D0 state */
                   1565:        CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
                   1566:            IWI_CTL_INIT);
                   1567:
                   1568:        CSR_WRITE_4(sc, IWI_CSR_READ_INT, IWI_READ_INT_INIT_HOST);
                   1569:
                   1570:        /* wait for clock stabilization */
                   1571:        for (ntries = 0; ntries < 1000; ntries++) {
                   1572:                if (CSR_READ_4(sc, IWI_CSR_CTL) & IWI_CTL_CLOCK_READY)
                   1573:                        break;
                   1574:                DELAY(200);
                   1575:        }
                   1576:        if (ntries == 1000) {
                   1577:                printf("%s: timeout waiting for clock stabilization\n",
                   1578:                    sc->sc_dev.dv_xname);
                   1579:                return ETIMEDOUT;
                   1580:        }
                   1581:
                   1582:        CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
                   1583:            IWI_RST_SW_RESET);
                   1584:
                   1585:        DELAY(10);
                   1586:
                   1587:        CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
                   1588:            IWI_CTL_INIT);
                   1589:
                   1590:        /* clear NIC memory */
                   1591:        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0);
                   1592:        for (i = 0; i < 0xc000; i++)
                   1593:                CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
                   1594:
                   1595:        return 0;
                   1596: }
                   1597:
                   1598: int
                   1599: iwi_load_ucode(struct iwi_softc *sc, const char *data, int size)
                   1600: {
                   1601:        const uint16_t *w;
                   1602:        int ntries, i;
                   1603:
                   1604:        CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
                   1605:            IWI_RST_STOP_MASTER);
                   1606:        for (ntries = 0; ntries < 5; ntries++) {
                   1607:                if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
                   1608:                        break;
                   1609:                DELAY(10);
                   1610:        }
                   1611:        if (ntries == 5) {
                   1612:                printf("%s: timeout waiting for master\n",
                   1613:                    sc->sc_dev.dv_xname);
                   1614:                return ETIMEDOUT;
                   1615:        }
                   1616:
                   1617:        MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
                   1618:        DELAY(5000);
                   1619:
                   1620:        CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
                   1621:            ~IWI_RST_PRINCETON_RESET);
                   1622:
                   1623:        DELAY(5000);
                   1624:        MEM_WRITE_4(sc, 0x3000e0, 0);
                   1625:        DELAY(1000);
                   1626:        MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, 1);
                   1627:        DELAY(1000);
                   1628:        MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, 0);
                   1629:        DELAY(1000);
                   1630:        MEM_WRITE_1(sc, 0x200000, 0x00);
                   1631:        MEM_WRITE_1(sc, 0x200000, 0x40);
                   1632:        DELAY(1000);
                   1633:
                   1634:        /* adapter is buggy, we must set the address for each word */
                   1635:        for (w = (const uint16_t *)data; size > 0; w++, size -= 2)
                   1636:                MEM_WRITE_2(sc, 0x200010, htole16(*w));
                   1637:
                   1638:        MEM_WRITE_1(sc, 0x200000, 0x00);
                   1639:        MEM_WRITE_1(sc, 0x200000, 0x80);
                   1640:
                   1641:        /* wait until we get an answer */
                   1642:        for (ntries = 0; ntries < 100; ntries++) {
                   1643:                if (MEM_READ_1(sc, 0x200000) & 1)
                   1644:                        break;
                   1645:                DELAY(100);
                   1646:        }
                   1647:        if (ntries == 100) {
                   1648:                printf("%s: timeout waiting for ucode to initialize\n",
                   1649:                    sc->sc_dev.dv_xname);
                   1650:                return ETIMEDOUT;
                   1651:        }
                   1652:
                   1653:        /* read the answer or the firmware will not initialize properly */
                   1654:        for (i = 0; i < 7; i++)
                   1655:                MEM_READ_4(sc, 0x200004);
                   1656:
                   1657:        MEM_WRITE_1(sc, 0x200000, 0x00);
                   1658:
                   1659:        return 0;
                   1660: }
                   1661:
                   1662: /* macro to handle unaligned little endian data in firmware image */
                   1663: #define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
                   1664:
                   1665: int
                   1666: iwi_load_firmware(struct iwi_softc *sc, const char *data, int size)
                   1667: {
                   1668:        bus_dmamap_t map;
                   1669:        bus_dma_segment_t seg;
                   1670:        caddr_t virtaddr;
                   1671:        u_char *p, *end;
                   1672:        uint32_t sentinel, ctl, src, dst, sum, len, mlen;
                   1673:        int ntries, nsegs, error;
                   1674:
                   1675:        /* allocate DMA memory to store firmware image */
                   1676:        error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
                   1677:            BUS_DMA_NOWAIT, &map);
                   1678:        if (error != 0) {
                   1679:                printf("%s: could not create firmware DMA map\n",
                   1680:                    sc->sc_dev.dv_xname);
                   1681:                goto fail1;
                   1682:        }
                   1683:
                   1684:        error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
                   1685:            &nsegs, BUS_DMA_NOWAIT);
                   1686:        if (error != 0) {
                   1687:                printf("%s: could not allocate firmware DMA memory\n",
                   1688:                    sc->sc_dev.dv_xname);
                   1689:                goto fail2;
                   1690:        }
                   1691:
                   1692:        error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, size, &virtaddr,
                   1693:            BUS_DMA_NOWAIT);
                   1694:        if (error != 0) {
                   1695:                printf("%s: could not map firmware DMA memory\n",
                   1696:                    sc->sc_dev.dv_xname);
                   1697:                goto fail3;
                   1698:        }
                   1699:
                   1700:        error = bus_dmamap_load(sc->sc_dmat, map, virtaddr, size, NULL,
                   1701:            BUS_DMA_NOWAIT);
                   1702:        if (error != 0) {
                   1703:                printf("%s: could not load firmware DMA map\n",
                   1704:                    sc->sc_dev.dv_xname);
                   1705:                goto fail4;
                   1706:        }
                   1707:
                   1708:        /* copy firmware image to DMA memory */
                   1709:        bcopy(data, virtaddr, size);
                   1710:
                   1711:        /* make sure the adapter will get up-to-date values */
                   1712:        bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_PREWRITE);
                   1713:
                   1714:        /* tell the adapter where the command blocks are stored */
                   1715:        MEM_WRITE_4(sc, 0x3000a0, 0x27000);
                   1716:
                   1717:        /*
                   1718:         * Store command blocks into adapter's internal memory using register
                   1719:         * indirections. The adapter will read the firmware image through DMA
                   1720:         * using information stored in command blocks.
                   1721:         */
                   1722:        src = map->dm_segs[0].ds_addr;
                   1723:        p = virtaddr;
                   1724:        end = p + size;
                   1725:        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0x27000);
                   1726:
                   1727:        while (p < end) {
                   1728:                dst = GETLE32(p); p += 4; src += 4;
                   1729:                len = GETLE32(p); p += 4; src += 4;
                   1730:                p += len;
                   1731:
                   1732:                while (len > 0) {
                   1733:                        mlen = min(len, IWI_CB_MAXDATALEN);
                   1734:
                   1735:                        ctl = IWI_CB_DEFAULT_CTL | mlen;
                   1736:                        sum = ctl ^ src ^ dst;
                   1737:
                   1738:                        /* write a command block */
                   1739:                        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, ctl);
                   1740:                        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, src);
                   1741:                        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, dst);
                   1742:                        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, sum);
                   1743:
                   1744:                        src += mlen;
                   1745:                        dst += mlen;
                   1746:                        len -= mlen;
                   1747:                }
                   1748:        }
                   1749:
                   1750:        /* write a fictive final command block (sentinel) */
                   1751:        sentinel = CSR_READ_4(sc, IWI_CSR_AUTOINC_ADDR);
                   1752:        CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
                   1753:
                   1754:        CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
                   1755:            ~(IWI_RST_MASTER_DISABLED | IWI_RST_STOP_MASTER));
                   1756:
                   1757:        /* tell the adapter to start processing command blocks */
                   1758:        MEM_WRITE_4(sc, 0x3000a4, 0x540100);
                   1759:
                   1760:        /* wait until the adapter has processed all command blocks */
                   1761:        for (ntries = 0; ntries < 400; ntries++) {
                   1762:                if (MEM_READ_4(sc, 0x3000d0) >= sentinel)
                   1763:                        break;
                   1764:                DELAY(100);
                   1765:        }
                   1766:        if (ntries == 400) {
                   1767:                printf("%s: timeout processing cb\n", sc->sc_dev.dv_xname);
                   1768:                error = ETIMEDOUT;
                   1769:                goto fail5;
                   1770:        }
                   1771:
                   1772:        /* we're done with command blocks processing */
                   1773:        MEM_WRITE_4(sc, 0x3000a4, 0x540c00);
                   1774:
                   1775:        /* allow interrupts so we know when the firmware is inited */
                   1776:        CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
                   1777:
                   1778:        /* tell the adapter to initialize the firmware */
                   1779:        CSR_WRITE_4(sc, IWI_CSR_RST, 0);
                   1780:
                   1781:        CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
                   1782:            IWI_CTL_ALLOW_STANDBY);
                   1783:
                   1784:        /* wait at most one second for firmware initialization to complete */
                   1785:        if ((error = tsleep(sc, 0, "iwiinit", hz)) != 0) {
                   1786:                printf("%s: timeout waiting for firmware initialization to "
                   1787:                    "complete\n", sc->sc_dev.dv_xname);
                   1788:                goto fail5;
                   1789:        }
                   1790:
                   1791: fail5: bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_POSTWRITE);
                   1792:        bus_dmamap_unload(sc->sc_dmat, map);
                   1793: fail4: bus_dmamem_unmap(sc->sc_dmat, virtaddr, size);
                   1794: fail3: bus_dmamem_free(sc->sc_dmat, &seg, 1);
                   1795: fail2: bus_dmamap_destroy(sc->sc_dmat, map);
                   1796: fail1: return error;
                   1797: }
                   1798:
                   1799: int
                   1800: iwi_config(struct iwi_softc *sc)
                   1801: {
                   1802:        struct ieee80211com *ic = &sc->sc_ic;
                   1803:        struct ifnet *ifp = &ic->ic_if;
                   1804:        struct iwi_configuration config;
                   1805:        struct iwi_rateset rs;
                   1806:        struct iwi_txpower power;
                   1807:        struct ieee80211_key *k;
                   1808:        struct iwi_wep_key wepkey;
                   1809:        uint32_t data;
                   1810:        int error, nchan, i;
                   1811:
                   1812:        IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
                   1813:        DPRINTF(("Setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
                   1814:        error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
                   1815:            IEEE80211_ADDR_LEN, 0);
                   1816:        if (error != 0)
                   1817:                return error;
                   1818:
                   1819:        bzero(&config, sizeof config);
                   1820:        config.multicast_enabled = 1;
                   1821:        config.silence_threshold = 30;
                   1822:        config.report_noise = 1;
                   1823:        config.answer_pbreq = (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
                   1824:        DPRINTF(("Configuring adapter\n"));
                   1825:        error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config, 0);
                   1826:        if (error != 0)
                   1827:                return error;
                   1828:
                   1829:        data = htole32(IWI_POWER_MODE_CAM);
                   1830:        DPRINTF(("Setting power mode to %u\n", letoh32(data)));
                   1831:        error = iwi_cmd(sc, IWI_CMD_SET_POWER_MODE, &data, sizeof data, 0);
                   1832:        if (error != 0)
                   1833:                return error;
                   1834:
                   1835:        data = htole32(ic->ic_rtsthreshold);
                   1836:        DPRINTF(("Setting RTS threshold to %u\n", letoh32(data)));
                   1837:        error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data, 0);
                   1838:        if (error != 0)
                   1839:                return error;
                   1840:
                   1841:        data = htole32(ic->ic_fragthreshold);
                   1842:        DPRINTF(("Setting fragmentation threshold to %u\n", letoh32(data)));
                   1843:        error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data, 0);
                   1844:        if (error != 0)
                   1845:                return error;
                   1846:
                   1847:        /*
                   1848:         * Set default Tx power for 802.11b/g and 802.11a channels.
                   1849:         */
                   1850:        nchan = 0;
                   1851:        for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
                   1852:                if (!IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i]))
                   1853:                        continue;
                   1854:                power.chan[nchan].chan = i;
                   1855:                power.chan[nchan].power = IWI_TXPOWER_MAX;
                   1856:                nchan++;
                   1857:        }
                   1858:        power.nchan = nchan;
                   1859:
                   1860:        power.mode = IWI_MODE_11G;
                   1861:        DPRINTF(("Setting .11g channels tx power\n"));
                   1862:        error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power, 0);
                   1863:        if (error != 0)
                   1864:                return error;
                   1865:
                   1866:        power.mode = IWI_MODE_11B;
                   1867:        DPRINTF(("Setting .11b channels tx power\n"));
                   1868:        error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power, 0);
                   1869:        if (error != 0)
                   1870:                return error;
                   1871:
                   1872:        nchan = 0;
                   1873:        for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
                   1874:                if (!IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i]))
                   1875:                        continue;
                   1876:                power.chan[nchan].chan = i;
                   1877:                power.chan[nchan].power = IWI_TXPOWER_MAX;
                   1878:                nchan++;
                   1879:        }
                   1880:        power.nchan = nchan;
                   1881:
                   1882:        if (nchan > 0) {        /* 2915ABG only */
                   1883:                power.mode = IWI_MODE_11A;
                   1884:                DPRINTF(("Setting .11a channels tx power\n"));
                   1885:                error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
                   1886:                    0);
                   1887:                if (error != 0)
                   1888:                        return error;
                   1889:        }
                   1890:
                   1891:        rs.mode = IWI_MODE_11G;
                   1892:        rs.type = IWI_RATESET_TYPE_SUPPORTED;
                   1893:        rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates;
                   1894:        bcopy(ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates, rs.rates,
                   1895:            rs.nrates);
                   1896:        DPRINTF(("Setting .11bg supported rates (%u)\n", rs.nrates));
                   1897:        error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
                   1898:        if (error != 0)
                   1899:                return error;
                   1900:
                   1901:        rs.mode = IWI_MODE_11A;
                   1902:        rs.type = IWI_RATESET_TYPE_SUPPORTED;
                   1903:        rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates;
                   1904:        bcopy(ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates, rs.rates,
                   1905:            rs.nrates);
                   1906:        DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
                   1907:        error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
                   1908:        if (error != 0)
                   1909:                return error;
                   1910:
                   1911:        /* if we have a desired ESSID, set it now */
                   1912:        if (ic->ic_des_esslen != 0) {
                   1913: #ifdef IWI_DEBUG
                   1914:                if (iwi_debug > 0) {
                   1915:                        printf("Setting desired ESSID to ");
                   1916:                        ieee80211_print_essid(ic->ic_des_essid,
                   1917:                            ic->ic_des_esslen);
                   1918:                        printf("\n");
                   1919:                }
                   1920: #endif
                   1921:                error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
                   1922:                    ic->ic_des_esslen, 0);
                   1923:                if (error != 0)
                   1924:                        return error;
                   1925:        }
                   1926:
                   1927:        data = htole32(arc4random());
                   1928:        DPRINTF(("Setting initialization vector to %u\n", letoh32(data)));
                   1929:        error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data, 0);
                   1930:        if (error != 0)
                   1931:                return error;
                   1932:
                   1933:        if (ic->ic_flags & IEEE80211_F_WEPON) {
                   1934:                k = ic->ic_nw_keys;
                   1935:                for (i = 0; i < IEEE80211_WEP_NKID; i++, k++) {
                   1936:                        wepkey.cmd = IWI_WEP_KEY_CMD_SETKEY;
                   1937:                        wepkey.idx = i;
                   1938:                        wepkey.len = k->k_len;
                   1939:                        bzero(wepkey.key, sizeof wepkey.key);
                   1940:                        bcopy(k->k_key, wepkey.key, k->k_len);
                   1941:                        DPRINTF(("Setting wep key index %u len %u\n",
                   1942:                            wepkey.idx, wepkey.len));
                   1943:                        error = iwi_cmd(sc, IWI_CMD_SET_WEP_KEY, &wepkey,
                   1944:                            sizeof wepkey, 0);
                   1945:                        if (error != 0)
                   1946:                                return error;
                   1947:                }
                   1948:        }
                   1949:
                   1950:        /* enable adapter */
                   1951:        DPRINTF(("Enabling adapter\n"));
                   1952:        return iwi_cmd(sc, IWI_CMD_ENABLE, NULL, 0, 0);
                   1953: }
                   1954:
                   1955: int
                   1956: iwi_set_chan(struct iwi_softc *sc, struct ieee80211_channel *chan)
                   1957: {
                   1958:        struct ieee80211com *ic = &sc->sc_ic;
                   1959:        struct iwi_scan scan;
                   1960:
                   1961:        bzero(&scan, sizeof scan);
                   1962:        memset(scan.type, IWI_SCAN_TYPE_PASSIVE, sizeof scan.type);
                   1963:        scan.passive = htole16(2000);
                   1964:        scan.channels[0] = 1 |
                   1965:            (IEEE80211_IS_CHAN_5GHZ(chan) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ);
                   1966:        scan.channels[1] = ieee80211_chan2ieee(ic, chan);
                   1967:
                   1968:        DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan)));
                   1969:        return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, 1);
                   1970: }
                   1971:
                   1972: int
                   1973: iwi_scan(struct iwi_softc *sc)
                   1974: {
                   1975:        struct ieee80211com *ic = &sc->sc_ic;
                   1976:        struct iwi_scan scan;
                   1977:        uint8_t *p;
                   1978:        int i, count;
                   1979:
                   1980:        bzero(&scan, sizeof scan);
                   1981:
                   1982:        if (ic->ic_des_esslen != 0) {
                   1983:                scan.bdirected = htole16(40);
                   1984:                memset(scan.type, IWI_SCAN_TYPE_BDIRECTED, sizeof scan.type);
                   1985:        } else {
                   1986:                scan.broadcast = htole16(40);
                   1987:                memset(scan.type, IWI_SCAN_TYPE_BROADCAST, sizeof scan.type);
                   1988:        }
                   1989:
                   1990:        p = scan.channels;
                   1991:        count = 0;
                   1992:        for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
                   1993:                if (IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i])) {
                   1994:                        *++p = i;
                   1995:                        count++;
                   1996:                }
                   1997:        }
                   1998:        *(p - count) = IWI_CHAN_5GHZ | count;
                   1999:
                   2000:        p = (count > 0) ? p + 1 : scan.channels;
                   2001:        count = 0;
                   2002:        for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
                   2003:                if (IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i])) {
                   2004:                        *++p = i;
                   2005:                        count++;
                   2006:                }
                   2007:        }
                   2008:        *(p - count) = IWI_CHAN_2GHZ | count;
                   2009:
                   2010:        DPRINTF(("Start scanning\n"));
                   2011:        return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, 1);
                   2012: }
                   2013:
                   2014: int
                   2015: iwi_auth_and_assoc(struct iwi_softc *sc)
                   2016: {
                   2017:        struct ieee80211com *ic = &sc->sc_ic;
                   2018:        struct ieee80211_node *ni = ic->ic_bss;
                   2019:        struct iwi_configuration config;
                   2020:        struct iwi_associate assoc;
                   2021:        struct iwi_rateset rs;
                   2022:        uint16_t capinfo;
                   2023:        uint32_t data;
                   2024:        int error;
                   2025:
                   2026:        /* update adapter configuration */
                   2027:        bzero(&config, sizeof config);
                   2028:        config.multicast_enabled = 1;
                   2029:        config.silence_threshold = 30;
                   2030:        config.report_noise = 1;
                   2031:        config.answer_pbreq = (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
                   2032:        if (ic->ic_curmode == IEEE80211_MODE_11G)
                   2033:                config.bg_autodetection = 1;
                   2034:        DPRINTF(("Configuring adapter\n"));
                   2035:        error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config, 1);
                   2036:        if (error != 0)
                   2037:                return error;
                   2038:
                   2039: #ifdef IWI_DEBUG
                   2040:        if (iwi_debug > 0) {
                   2041:                printf("Setting ESSID to ");
                   2042:                ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
                   2043:                printf("\n");
                   2044:        }
                   2045: #endif
                   2046:        error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen, 1);
                   2047:        if (error != 0)
                   2048:                return error;
                   2049:
                   2050:        /* the rate set has already been "negotiated" */
                   2051:        rs.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
                   2052:            IWI_MODE_11G;
                   2053:        rs.type = IWI_RATESET_TYPE_NEGOTIATED;
                   2054:        rs.nrates = ni->ni_rates.rs_nrates;
                   2055:        if (rs.nrates > sizeof rs.rates) {
                   2056: #ifdef DIAGNOSTIC
                   2057:                /* should not happen since the rates are negotiated */
                   2058:                printf("%s: XXX too many rates (count=%d, last=%d)\n",
                   2059:                    sc->sc_dev.dv_xname, ni->ni_rates.rs_nrates,
                   2060:                    ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] &
                   2061:                    IEEE80211_RATE_VAL);
                   2062: #endif
                   2063:                rs.nrates = sizeof rs.rates;
                   2064:        }
                   2065:        bcopy(ni->ni_rates.rs_rates, rs.rates, rs.nrates);
                   2066:        DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
                   2067:        error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 1);
                   2068:        if (error != 0)
                   2069:                return error;
                   2070:
                   2071:        data = htole32(ni->ni_rssi);
                   2072:        DPRINTF(("Setting sensitivity to %d\n", (int8_t)ni->ni_rssi));
                   2073:        error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data, 1);
                   2074:        if (error != 0)
                   2075:                return error;
                   2076:
                   2077:        bzero(&assoc, sizeof assoc);
                   2078:        if (ic->ic_flags & IEEE80211_F_SIBSS)
                   2079:                assoc.type = IWI_ASSOC_SIBSS;
                   2080:        else
                   2081:                assoc.type = IWI_ASSOC_ASSOCIATE;
                   2082:        if (ic->ic_curmode == IEEE80211_MODE_11A)
                   2083:                assoc.mode = IWI_MODE_11A;
                   2084:        else if (ic->ic_curmode == IEEE80211_MODE_11B)
                   2085:                assoc.mode = IWI_MODE_11B;
                   2086:        else    /* assume 802.11b/g */
                   2087:                assoc.mode = IWI_MODE_11G;
                   2088:        assoc.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
                   2089: #if 0
                   2090:        if (ni->ni_challenge != NULL)   /* XXX */
                   2091:                assoc.auth = (ic->ic_wep_txkey << 4) | IWI_AUTH_SHARED;
                   2092: #endif
                   2093:        if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
                   2094:                assoc.plen = IWI_ASSOC_SHPREAMBLE;
                   2095:        bcopy(ni->ni_tstamp, assoc.tstamp, 8);
                   2096:        capinfo = IEEE80211_CAPINFO_ESS;
                   2097:        if (ic->ic_flags & IEEE80211_F_WEPON)
                   2098:                capinfo |= IEEE80211_CAPINFO_PRIVACY;
                   2099:        if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
                   2100:            IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
                   2101:                capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
                   2102:        if (ic->ic_flags & IEEE80211_F_SHSLOT)
                   2103:                capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
                   2104:        assoc.capinfo = htole16(capinfo);
                   2105:
                   2106:        assoc.lintval = htole16(ic->ic_lintval);
                   2107:        assoc.intval = htole16(ni->ni_intval);
                   2108:        IEEE80211_ADDR_COPY(assoc.bssid, ni->ni_bssid);
                   2109:        if (ic->ic_opmode == IEEE80211_M_IBSS)
                   2110:                IEEE80211_ADDR_COPY(assoc.dst, etherbroadcastaddr);
                   2111:        else
                   2112:                IEEE80211_ADDR_COPY(assoc.dst, ni->ni_bssid);
                   2113:
                   2114:        DPRINTF(("Trying to associate to %s channel %u auth %u\n",
                   2115:            ether_sprintf(assoc.bssid), assoc.chan, assoc.auth));
                   2116:        return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc, 1);
                   2117: }
                   2118:
                   2119: int
                   2120: iwi_init(struct ifnet *ifp)
                   2121: {
                   2122:        struct iwi_softc *sc = ifp->if_softc;
                   2123:        struct ieee80211com *ic = &sc->sc_ic;
                   2124:        struct iwi_firmware_hdr *hdr;
                   2125:        const char *name, *fw;
                   2126:        u_char *data;
                   2127:        size_t size;
                   2128:        int i, error;
                   2129:
                   2130:        iwi_stop(ifp, 0);
                   2131:
                   2132:        if ((error = iwi_reset(sc)) != 0) {
                   2133:                printf("%s: could not reset adapter\n", sc->sc_dev.dv_xname);
                   2134:                goto fail1;
                   2135:        }
                   2136:
                   2137:        switch (sc->sc_ic.ic_opmode) {
                   2138:        case IEEE80211_M_STA:
                   2139:        case IEEE80211_M_HOSTAP:
                   2140:                name = "iwi-bss";
                   2141:                break;
                   2142:        case IEEE80211_M_IBSS:
                   2143:        case IEEE80211_M_AHDEMO:
                   2144:                name = "iwi-ibss";
                   2145:                break;
                   2146:        case IEEE80211_M_MONITOR:
                   2147:                name = "iwi-monitor";
                   2148:                break;
                   2149:        default:
                   2150:                name = NULL;    /* should not get there */
                   2151:        }
                   2152:
                   2153:        if ((error = loadfirmware(name, &data, &size)) != 0) {
                   2154:                printf("%s: could not read firmware %s\n",
                   2155:                    sc->sc_dev.dv_xname, name);
                   2156:                goto fail1;
                   2157:        }
                   2158:
                   2159:        if (size < sizeof (struct iwi_firmware_hdr)) {
                   2160:                printf("%s: firmware image too short: %u bytes\n",
                   2161:                    sc->sc_dev.dv_xname, size);
                   2162:                error = EINVAL;
                   2163:                goto fail2;
                   2164:        }
                   2165:
                   2166:        hdr = (struct iwi_firmware_hdr *)data;
                   2167:
                   2168:        if (hdr->vermaj < 3 || hdr->bootsz == 0 || hdr->ucodesz == 0 ||
                   2169:            hdr->mainsz == 0) {
                   2170:                printf("%s: firmware image too old (need at least 3.0)\n",
                   2171:                    sc->sc_dev.dv_xname);
                   2172:                error = EINVAL;
                   2173:                goto fail2;
                   2174:        }
                   2175:
                   2176:        if (size < sizeof (struct iwi_firmware_hdr) + letoh32(hdr->bootsz) +
                   2177:            letoh32(hdr->ucodesz) + letoh32(hdr->mainsz)) {
                   2178:                printf("%s: firmware image too short: %u bytes\n",
                   2179:                    sc->sc_dev.dv_xname, size);
                   2180:                error = EINVAL;
                   2181:                goto fail2;
                   2182:        }
                   2183:
                   2184:        fw = (const char *)data + sizeof (struct iwi_firmware_hdr);
                   2185:        if ((error = iwi_load_firmware(sc, fw, letoh32(hdr->bootsz))) != 0) {
                   2186:                printf("%s: could not load boot firmware\n",
                   2187:                    sc->sc_dev.dv_xname);
                   2188:                goto fail2;
                   2189:        }
                   2190:
                   2191:        fw = (const char *)data + sizeof (struct iwi_firmware_hdr) +
                   2192:            letoh32(hdr->bootsz);
                   2193:        if ((error = iwi_load_ucode(sc, fw, letoh32(hdr->ucodesz))) != 0) {
                   2194:                printf("%s: could not load microcode\n", sc->sc_dev.dv_xname);
                   2195:                goto fail2;
                   2196:        }
                   2197:
                   2198:        iwi_stop_master(sc);
                   2199:
                   2200:        CSR_WRITE_4(sc, IWI_CSR_CMD_BASE, sc->cmdq.map->dm_segs[0].ds_addr);
                   2201:        CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, IWI_CMD_RING_COUNT);
                   2202:        CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
                   2203:
                   2204:        CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].map->dm_segs[0].ds_addr);
                   2205:        CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, IWI_TX_RING_COUNT);
                   2206:        CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur);
                   2207:
                   2208:        CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].map->dm_segs[0].ds_addr);
                   2209:        CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, IWI_TX_RING_COUNT);
                   2210:        CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur);
                   2211:
                   2212:        CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].map->dm_segs[0].ds_addr);
                   2213:        CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, IWI_TX_RING_COUNT);
                   2214:        CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur);
                   2215:
                   2216:        CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].map->dm_segs[0].ds_addr);
                   2217:        CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, IWI_TX_RING_COUNT);
                   2218:        CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur);
                   2219:
                   2220:        for (i = 0; i < IWI_RX_RING_COUNT; i++) {
                   2221:                struct iwi_rx_data *data = &sc->rxq.data[i];
                   2222:                CSR_WRITE_4(sc, data->reg, data->map->dm_segs[0].ds_addr);
                   2223:        }
                   2224:
                   2225:        CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, IWI_RX_RING_COUNT - 1);
                   2226:
                   2227:        fw = (const char *)data + sizeof (struct iwi_firmware_hdr) +
                   2228:            letoh32(hdr->bootsz) + letoh32(hdr->ucodesz);
                   2229:        if ((error = iwi_load_firmware(sc, fw, letoh32(hdr->mainsz))) != 0) {
                   2230:                printf("%s: could not load main firmware\n",
                   2231:                    sc->sc_dev.dv_xname);
                   2232:                goto fail2;
                   2233:        }
                   2234:
                   2235:        free(data, M_DEVBUF);
                   2236:        sc->flags |= IWI_FLAG_FW_INITED;
                   2237:
                   2238:        if ((error = iwi_config(sc)) != 0) {
                   2239:                printf("%s: device configuration failed\n",
                   2240:                    sc->sc_dev.dv_xname);
                   2241:                goto fail1;
                   2242:        }
                   2243:
                   2244:        ifp->if_flags &= ~IFF_OACTIVE;
                   2245:        ifp->if_flags |= IFF_RUNNING;
                   2246:
                   2247:        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                   2248:                ieee80211_begin_scan(ifp);
                   2249:        else
                   2250:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   2251:
                   2252:        return 0;
                   2253:
                   2254: fail2: free(data, M_DEVBUF);
                   2255: fail1: iwi_stop(ifp, 0);
                   2256:        return error;
                   2257: }
                   2258:
                   2259: void
                   2260: iwi_stop(struct ifnet *ifp, int disable)
                   2261: {
                   2262:        struct iwi_softc *sc = ifp->if_softc;
                   2263:        struct ieee80211com *ic = &sc->sc_ic;
                   2264:        int i;
                   2265:
                   2266:        sc->sc_tx_timer = 0;
                   2267:        ifp->if_timer = 0;
                   2268:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2269:
                   2270:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   2271:
                   2272:        iwi_stop_master(sc);
                   2273:
                   2274:        CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SW_RESET);
                   2275:
                   2276:        /* reset rings */
                   2277:        iwi_reset_cmd_ring(sc, &sc->cmdq);
                   2278:        for (i = 0; i < 4; i++)
                   2279:                iwi_reset_tx_ring(sc, &sc->txq[i]);
                   2280:        iwi_reset_rx_ring(sc, &sc->rxq);
                   2281: }
                   2282:
                   2283: struct cfdriver iwi_cd = {
                   2284:        NULL, "iwi", DV_IFNET
                   2285: };

CVSweb