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

Annotation of sys/dev/ic/malo.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: malo.c,v 1.72 2007/07/18 18:10:31 damien Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
                      5:  * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include "bpfilter.h"
                     21:
                     22: #include <sys/cdefs.h>
                     23: #include <sys/param.h>
                     24: #include <sys/types.h>
                     25:
                     26: #include <sys/device.h>
                     27: #include <sys/kernel.h>
                     28: #include <sys/malloc.h>
                     29: #include <sys/mbuf.h>
                     30: #include <sys/proc.h>
                     31: #include <sys/socket.h>
                     32: #include <sys/sockio.h>
                     33: #include <sys/systm.h>
                     34:
                     35: #include <machine/bus.h>
                     36: #include <machine/endian.h>
                     37: #include <machine/intr.h>
                     38:
                     39: #include <net/if.h>
                     40: #include <net/if_media.h>
                     41:
                     42: #if NBPFILTER > 0
                     43: #include <net/bpf.h>
                     44: #endif
                     45:
                     46: #include <netinet/in.h>
                     47: #include <netinet/in_systm.h>
                     48: #include <netinet/if_ether.h>
                     49:
                     50: #include <net80211/ieee80211_var.h>
                     51: #include <net80211/ieee80211_radiotap.h>
                     52:
                     53: #include <dev/ic/malo.h>
                     54:
                     55: #ifdef MALO_DEBUG
                     56: #define DPRINTF(x)     do { if (malo_debug > 0) printf x; } while (0)
                     57: #define DPRINTFN(n, x) do { if (malo_debug >= (n)) printf x; } while (0)
                     58: int malo_debug = 1;
                     59: #else
                     60: #define DPRINTF(x)
                     61: #define DPRINTFN(n, x)
                     62: #endif
                     63:
                     64: /* internal structures and defines */
                     65: struct malo_node {
                     66:        struct ieee80211_node           ni;
                     67: };
                     68:
                     69: struct malo_rx_data {
                     70:        bus_dmamap_t    map;
                     71:        struct mbuf     *m;
                     72: };
                     73:
                     74: struct malo_tx_data {
                     75:        bus_dmamap_t            map;
                     76:        struct mbuf             *m;
                     77:        uint32_t                softstat;
                     78:        struct ieee80211_node   *ni;
                     79: };
                     80:
                     81: /* RX descriptor used by HW */
                     82: struct malo_rx_desc {
                     83:        uint8_t         rxctrl;
                     84:        uint8_t         rssi;
                     85:        uint8_t         status;
                     86:        uint8_t         channel;
                     87:        uint16_t        len;
                     88:        uint8_t         reserved1;      /* actually unused */
                     89:        uint8_t         datarate;
                     90:        uint32_t        physdata;       /* DMA address of data */
                     91:        uint32_t        physnext;       /* DMA address of next control block */
                     92:        uint16_t        qosctrl;
                     93:        uint16_t        reserved2;
                     94: } __packed;
                     95:
                     96: /* TX descriptor used by HW */
                     97: struct malo_tx_desc {
                     98:        uint32_t        status;
                     99:        uint8_t         datarate;
                    100:        uint8_t         txpriority;
                    101:        uint16_t        qosctrl;
                    102:        uint32_t        physdata;       /* DMA address of data */
                    103:        uint16_t        len;
                    104:        uint8_t         destaddr[6];
                    105:        uint32_t        physnext;       /* DMA address of next control block */
                    106:        uint32_t        reserved1;      /* SAP packet info ??? */
                    107:        uint32_t        reserved2;
                    108: } __packed;
                    109:
                    110: #define MALO_RX_RING_COUNT     256
                    111: #define MALO_TX_RING_COUNT     256
                    112: #define MALO_MAX_SCATTER       8       /* XXX unknown, wild guess */
                    113:
                    114: /*
                    115:  * Firmware commands
                    116:  */
                    117: #define MALO_CMD_GET_HW_SPEC           0x0003
                    118: #define MALO_CMD_SET_WEPKEY            0x0013
                    119: #define MALO_CMD_SET_RADIO             0x001c
                    120: #define MALO_CMD_SET_AID               0x010d
                    121: #define MALO_CMD_SET_TXPOWER           0x001e
                    122: #define MALO_CMD_SET_ANTENNA           0x0020
                    123: #define MALO_CMD_SET_PRESCAN           0x0107
                    124: #define MALO_CMD_SET_POSTSCAN          0x0108
                    125: #define MALO_CMD_SET_RATE              0x0110
                    126: #define MALO_CMD_SET_CHANNEL           0x010a
                    127: #define MALO_CMD_SET_RTS               0x0113
                    128: #define MALO_CMD_SET_SLOT              0x0114
                    129: #define MALO_CMD_RESPONSE              0x8000
                    130:
                    131: #define MALO_CMD_RESULT_OK             0x0000  /* everything is fine */
                    132: #define MALO_CMD_RESULT_ERROR          0x0001  /* general error */
                    133: #define MALO_CMD_RESULT_NOSUPPORT      0x0002  /* command not valid */
                    134: #define MALO_CMD_RESULT_PENDING                0x0003  /* will be processed */
                    135: #define MALO_CMD_RESULT_BUSY           0x0004  /* command ignored */
                    136: #define MALO_CMD_RESULT_PARTIALDATA    0x0005  /* buffer too small */
                    137:
                    138: struct malo_cmdheader {
                    139:        uint16_t        cmd;
                    140:        uint16_t        size;           /* size of the command, incl. header */
                    141:        uint16_t        seqnum;         /* seems not to matter that much */
                    142:        uint16_t        result;         /* set to 0 on request */
                    143:        /* following the data payload, up to 256 bytes */
                    144: };
                    145:
                    146: struct malo_hw_spec {
                    147:        uint16_t        HwVersion;
                    148:        uint16_t        NumOfWCB;
                    149:        uint16_t        NumOfMCastAdr;
                    150:        uint8_t         PermanentAddress[6];
                    151:        uint16_t        RegionCode;
                    152:        uint16_t        NumberOfAntenna;
                    153:        uint32_t        FWReleaseNumber;
                    154:        uint32_t        WcbBase0;
                    155:        uint32_t        RxPdWrPtr;
                    156:        uint32_t        RxPdRdPtr;
                    157:        uint32_t        CookiePtr;
                    158:        uint32_t        WcbBase1;
                    159:        uint32_t        WcbBase2;
                    160:        uint32_t        WcbBase3;
                    161: } __packed;
                    162:
                    163: struct malo_cmd_wepkey {
                    164:        uint16_t        action;
                    165:        uint8_t         len;
                    166:        uint8_t         flags;
                    167:        uint16_t        index;
                    168:        uint8_t         value[IEEE80211_KEYBUF_SIZE];
                    169:        uint8_t         txmickey[IEEE80211_WEP_MICLEN];
                    170:        uint8_t         rxmickey[IEEE80211_WEP_MICLEN];
                    171:        uint64_t        rxseqctr;
                    172:        uint64_t        txseqctr;
                    173: } __packed;
                    174:
                    175: struct malo_cmd_radio {
                    176:        uint16_t        action;
                    177:        uint16_t        preamble_mode;
                    178:        uint16_t        enable;
                    179: } __packed;
                    180:
                    181: struct malo_cmd_aid {
                    182:        uint16_t        associd;
                    183:        uint8_t         macaddr[6];
                    184:        uint32_t        gprotection;
                    185:        uint8_t         aprates[14];
                    186: } __packed;
                    187:
                    188: struct malo_cmd_txpower {
                    189:        uint16_t        action;
                    190:        uint16_t        supportpowerlvl;
                    191:        uint16_t        currentpowerlvl;
                    192:        uint16_t        reserved;
                    193:        uint16_t        powerlvllist[8];
                    194: } __packed;
                    195:
                    196: struct malo_cmd_antenna {
                    197:        uint16_t        action;
                    198:        uint16_t        mode;
                    199: } __packed;
                    200:
                    201: struct malo_cmd_postscan {
                    202:        uint32_t        isibss;
                    203:        uint8_t         bssid[6];
                    204: } __packed;
                    205:
                    206: struct malo_cmd_channel {
                    207:        uint16_t        action;
                    208:        uint8_t         channel;
                    209: } __packed;
                    210:
                    211: struct malo_cmd_rate {
                    212:        uint8_t         dataratetype;
                    213:        uint8_t         rateindex;
                    214:        uint8_t         aprates[14];
                    215: } __packed;
                    216:
                    217: struct malo_cmd_slot {
                    218:        uint16_t        action;
                    219:        uint8_t         slot;
                    220: } __packed;
                    221:
                    222: #define malo_mem_write4(sc, off, x) \
                    223:        bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
                    224: #define malo_mem_write2(sc, off, x) \
                    225:        bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
                    226: #define malo_mem_write1(sc, off, x) \
                    227:        bus_space_write_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
                    228:
                    229: #define malo_mem_read4(sc, off) \
                    230:        bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
                    231: #define malo_mem_read1(sc, off) \
                    232:        bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
                    233:
                    234: #define malo_ctl_write4(sc, off, x) \
                    235:        bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (x))
                    236: #define malo_ctl_read4(sc, off) \
                    237:        bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
                    238: #define malo_ctl_read1(sc, off) \
                    239:        bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
                    240:
                    241: #define malo_ctl_barrier(sc, t) \
                    242:        bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00, 0xff, (t))
                    243:
                    244: struct cfdriver malo_cd = {
                    245:        NULL, "malo", DV_IFNET
                    246: };
                    247:
                    248: int    malo_alloc_cmd(struct malo_softc *sc);
                    249: void   malo_free_cmd(struct malo_softc *sc);
                    250: void   malo_send_cmd(struct malo_softc *sc, bus_addr_t addr);
                    251: int    malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr);
                    252: int    malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring,
                    253:            int count);
                    254: void   malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
                    255: void   malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
                    256: int    malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
                    257:            int count);
                    258: void   malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
                    259: void   malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
                    260: int    malo_init(struct ifnet *ifp);
                    261: int    malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
                    262: void   malo_start(struct ifnet *ifp);
                    263: void   malo_stop(struct malo_softc *sc);
                    264: void   malo_watchdog(struct ifnet *ifp);
                    265: int    malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
                    266:            int arg);
                    267: void   malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
                    268:            int isnew);
                    269: struct ieee80211_node *
                    270:        malo_node_alloc(struct ieee80211com *ic);
                    271: int    malo_media_change(struct ifnet *ifp);
                    272: void   malo_media_status(struct ifnet *ifp, struct ifmediareq *imr);
                    273: int    malo_chip2rate(int chip_rate);
                    274: int    malo_fix2rate(int fix_rate);
                    275: void   malo_next_scan(void *arg);
                    276: void   malo_tx_intr(struct malo_softc *sc);
                    277: int    malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0,
                    278:            struct ieee80211_node *ni);
                    279: int    malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
                    280:            struct ieee80211_node *ni);
                    281: void   malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
                    282:            int len, int rate, const bus_dma_segment_t *segs, int nsegs);
                    283: void   malo_rx_intr(struct malo_softc *sc);
                    284: int    malo_load_bootimg(struct malo_softc *sc);
                    285: int    malo_load_firmware(struct malo_softc *sc);
                    286:
                    287: int    malo_set_wepkey(struct malo_softc *sc);
                    288: int    malo_set_slot(struct malo_softc *sc);
                    289: void   malo_update_slot(struct ieee80211com *ic);
                    290: #ifdef MALO_DEBUG
                    291: void   malo_hexdump(void *buf, int len);
                    292: #endif
                    293: static char *
                    294:        malo_cmd_string(uint16_t cmd);
                    295: static char *
                    296:        malo_cmd_string_result(uint16_t result);
                    297: int    malo_cmd_get_spec(struct malo_softc *sc);
                    298: int    malo_cmd_set_wepkey(struct malo_softc *sc, struct ieee80211_key *k,
                    299:            uint16_t k_index);
                    300: int    malo_cmd_set_prescan(struct malo_softc *sc);
                    301: int    malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr,
                    302:            uint8_t ibsson);
                    303: int    malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel);
                    304: int    malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna_type);
                    305: int    malo_cmd_set_radio(struct malo_softc *sc, uint16_t mode,
                    306:            uint16_t preamble);
                    307: int    malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid,
                    308:            uint16_t associd);
                    309: int    malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel);
                    310: int    malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold);
                    311: int    malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot);
                    312: int    malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate);
                    313:
                    314: int
                    315: malo_intr(void *arg)
                    316: {
                    317:        struct malo_softc *sc = arg;
                    318:        uint32_t status;
                    319:
                    320:        status = malo_ctl_read4(sc, 0x0c30);
                    321:        if (status == 0xffffffff || status == 0)
                    322:                /* not for us */
                    323:                return (0);
                    324:
                    325:        if (status & 0x1)
                    326:                malo_tx_intr(sc);
                    327:        if (status & 0x2)
                    328:                malo_rx_intr(sc);
                    329:        if (status & 0x4) {
                    330:                struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                    331:
                    332:                if (letoh16(hdr->result) != MALO_CMD_RESULT_OK) {
                    333:                        printf("%s: firmware cmd %s failed with %s\n",
                    334:                            sc->sc_dev.dv_xname,
                    335:                            malo_cmd_string(hdr->cmd),
                    336:                            malo_cmd_string_result(hdr->result));
                    337:                }
                    338: #ifdef MALO_DEBUG
                    339:                printf("%s: cmd answer for %s=%s\n",
                    340:                    sc->sc_dev.dv_xname,
                    341:                    malo_cmd_string(hdr->cmd),
                    342:                    malo_cmd_string_result(hdr->result));
                    343:                if (malo_debug > 2)
                    344:                        malo_hexdump(hdr, letoh16(hdr->size));
                    345: #endif
                    346:        }
                    347:
                    348:        if (status & ~0x7)
                    349:                DPRINTF(("%s: unkown interrupt %x\n", sc->sc_dev.dv_xname,
                    350:                    status));
                    351:
                    352:        /* just ack the interrupt */
                    353:        malo_ctl_write4(sc, 0x0c30, 0);
                    354:
                    355:        return (1);
                    356: }
                    357:
                    358: int
                    359: malo_attach(struct malo_softc *sc)
                    360: {
                    361:        struct ieee80211com *ic = &sc->sc_ic;
                    362:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                    363:        int i;
                    364:
                    365:        /* initialize channel scanning timer */
                    366:        timeout_set(&sc->sc_scan_to, malo_next_scan, sc);
                    367:
                    368:        /* allocate DMA structures */
                    369:        malo_alloc_cmd(sc);
                    370:        malo_alloc_rx_ring(sc, &sc->sc_rxring, MALO_RX_RING_COUNT);
                    371:        malo_alloc_tx_ring(sc, &sc->sc_txring, MALO_TX_RING_COUNT);
                    372:
                    373:        /* setup interface */
                    374:        ifp->if_softc = sc;
                    375:        ifp->if_init = malo_init;
                    376:        ifp->if_ioctl = malo_ioctl;
                    377:        ifp->if_start = malo_start;
                    378:        ifp->if_watchdog = malo_watchdog;
                    379:        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
                    380:        strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
                    381:        IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
                    382:        IFQ_SET_READY(&ifp->if_snd);
                    383:
                    384:        /* set supported rates */
                    385:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    386:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
                    387:        sc->sc_last_txrate = -1;
                    388:
                    389:        /* set channels */
                    390:        for (i = 1; i <= 14; i++) {
                    391:                ic->ic_channels[i].ic_freq =
                    392:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
                    393:                ic->ic_channels[i].ic_flags =
                    394:                    IEEE80211_CHAN_PUREG |
                    395:                    IEEE80211_CHAN_B |
                    396:                    IEEE80211_CHAN_G;
                    397:        }
                    398:
                    399:        /* set the rest */
                    400:        ic->ic_caps =
                    401:            IEEE80211_C_IBSS |
                    402:            IEEE80211_C_MONITOR |
                    403:            IEEE80211_C_SHPREAMBLE |
                    404:            IEEE80211_C_SHSLOT |
                    405:            IEEE80211_C_WEP;
                    406:        ic->ic_opmode = IEEE80211_M_STA;
                    407:        ic->ic_state = IEEE80211_S_INIT;
                    408:        ic->ic_max_rssi = 75;
                    409:        for (i = 0; i < 6; i++)
                    410:                ic->ic_myaddr[i] = malo_ctl_read1(sc, 0xa528 + i);
                    411:
                    412:        /* show our mac address */
                    413:        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
                    414:
                    415:        /* attach interface */
                    416:        if_attach(ifp);
                    417:        ieee80211_ifattach(ifp);
                    418:
                    419:        /* post attach vector functions */
                    420:        sc->sc_newstate = ic->ic_newstate;
                    421:        ic->ic_newstate = malo_newstate;
                    422:        ic->ic_newassoc = malo_newassoc;
                    423:        ic->ic_node_alloc = malo_node_alloc;
                    424:        ic->ic_updateslot = malo_update_slot;
                    425:
                    426:        ieee80211_media_init(ifp, malo_media_change, malo_media_status);
                    427:
                    428: #if NBPFILTER > 0
                    429:        bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
                    430:            sizeof(struct ieee80211_frame) + 64);
                    431:
                    432:        sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
                    433:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    434:        sc->sc_rxtap.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT);
                    435:
                    436:        sc->sc_txtap_len = sizeof(sc->sc_txtapu);
                    437:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    438:        sc->sc_txtap.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT);
                    439: #endif
                    440:
                    441:        return (0);
                    442: }
                    443:
                    444: int
                    445: malo_detach(void *arg)
                    446: {
                    447:        struct malo_softc *sc = arg;
                    448:        struct ieee80211com *ic = &sc->sc_ic;
                    449:        struct ifnet *ifp = &ic->ic_if;
                    450:
                    451:        /* remove channel scanning timer */
                    452:        timeout_del(&sc->sc_scan_to);
                    453:
                    454:        malo_stop(sc);
                    455:        ieee80211_ifdetach(ifp);
                    456:        if_detach(ifp);
                    457:        malo_free_cmd(sc);
                    458:        malo_free_rx_ring(sc, &sc->sc_rxring);
                    459:        malo_free_tx_ring(sc, &sc->sc_txring);
                    460:
                    461:        return (0);
                    462: }
                    463:
                    464: int
                    465: malo_alloc_cmd(struct malo_softc *sc)
                    466: {
                    467:        int error, nsegs;
                    468:
                    469:        error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
                    470:            PAGE_SIZE, 0, BUS_DMA_ALLOCNOW, &sc->sc_cmd_dmam);
                    471:        if (error != 0) {
                    472:                printf("%s: can not create DMA tag\n", sc->sc_dev.dv_xname);
                    473:                return (-1);
                    474:        }
                    475:
                    476:        error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
                    477:            0, &sc->sc_cmd_dmas, 1, &nsegs, BUS_DMA_WAITOK);
                    478:        if (error != 0) {
                    479:                printf("%s: error alloc dma memory\n", sc->sc_dev.dv_xname);
                    480:                return (-1);
                    481:        }
                    482:
                    483:        error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs,
                    484:            PAGE_SIZE, (caddr_t *)&sc->sc_cmd_mem, BUS_DMA_WAITOK);
                    485:        if (error != 0) {
                    486:                printf("%s: error map dma memory\n", sc->sc_dev.dv_xname);
                    487:                return (-1);
                    488:        }
                    489:
                    490:        error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_dmam,
                    491:            sc->sc_cmd_mem, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
                    492:        if (error != 0) {
                    493:                printf("%s: error load dma memory\n", sc->sc_dev.dv_xname);
                    494:                bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs);
                    495:                return (-1);
                    496:        }
                    497:
                    498:        sc->sc_cookie = sc->sc_cmd_mem;
                    499:        *sc->sc_cookie = htole32(0xaa55aa55);
                    500:        sc->sc_cmd_mem = sc->sc_cmd_mem + sizeof(uint32_t);
                    501:        sc->sc_cookie_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr;
                    502:        sc->sc_cmd_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr +
                    503:            sizeof(uint32_t);
                    504:
                    505:        return (0);
                    506: }
                    507:
                    508: void
                    509: malo_free_cmd(struct malo_softc *sc)
                    510: {
                    511:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                    512:            BUS_DMASYNC_POSTWRITE);
                    513:        bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_dmam);
                    514:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cookie, PAGE_SIZE);
                    515:        bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, 1);
                    516: }
                    517:
                    518: void
                    519: malo_send_cmd(struct malo_softc *sc, bus_addr_t addr)
                    520: {
                    521:        malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
                    522:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    523:        malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
                    524:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    525: }
                    526:
                    527: int
                    528: malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr)
                    529: {
                    530:        int i;
                    531:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                    532:
                    533:        malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
                    534:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    535:        malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
                    536:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    537:
                    538:        for (i = 0; i < 10; i++) {
                    539:                delay(100);
                    540:                bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                    541:                    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
                    542:                if (hdr->cmd & htole16(0x8000))
                    543:                        break;
                    544:        }
                    545:
                    546:        if (i == 10)
                    547:                return (ETIMEDOUT);
                    548:
                    549:        return (0);
                    550: }
                    551:
                    552: int
                    553: malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, int count)
                    554: {
                    555:        struct malo_rx_desc *desc;
                    556:        struct malo_rx_data *data;
                    557:        int i, nsegs, error;
                    558:
                    559:        ring->count = count;
                    560:        ring->cur = ring->next = 0;
                    561:
                    562:        error = bus_dmamap_create(sc->sc_dmat,
                    563:            count * sizeof(struct malo_rx_desc), 1,
                    564:            count * sizeof(struct malo_rx_desc), 0,
                    565:            BUS_DMA_NOWAIT, &ring->map);
                    566:        if (error != 0) {
                    567:                printf("%s: could not create desc DMA map\n",
                    568:                    sc->sc_dev.dv_xname);
                    569:                goto fail;
                    570:        }
                    571:
                    572:        error = bus_dmamem_alloc(sc->sc_dmat,
                    573:            count * sizeof(struct malo_rx_desc),
                    574:            PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
                    575:        if (error != 0) {
                    576:                printf("%s: could not allocate DMA memory\n",
                    577:                    sc->sc_dev.dv_xname);
                    578:                goto fail;
                    579:        }
                    580:
                    581:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
                    582:            count * sizeof(struct malo_rx_desc), (caddr_t *)&ring->desc,
                    583:            BUS_DMA_NOWAIT);
                    584:        if (error != 0) {
                    585:                printf("%s: could not map desc DMA memory\n",
                    586:                    sc->sc_dev.dv_xname);
                    587:                goto fail;
                    588:        }
                    589:
                    590:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
                    591:            count * sizeof(struct malo_rx_desc), NULL, BUS_DMA_NOWAIT);
                    592:        if (error != 0) {
                    593:                printf("%s: could not load desc DMA map\n",
                    594:                    sc->sc_dev.dv_xname);
                    595:                goto fail;
                    596:        }
                    597:
                    598:        bzero(ring->desc, count * sizeof(struct malo_rx_desc));
                    599:        ring->physaddr = ring->map->dm_segs->ds_addr;
                    600:
                    601:        ring->data = malloc(count * sizeof (struct malo_rx_data), M_DEVBUF,
                    602:            M_NOWAIT);
                    603:        if (ring->data == NULL) {
                    604:                printf("%s: could not allocate soft data\n",
                    605:                    sc->sc_dev.dv_xname);
                    606:                error = ENOMEM;
                    607:                goto fail;
                    608:        }
                    609:
                    610:        /*
                    611:         * Pre-allocate Rx buffers and populate Rx ring.
                    612:         */
                    613:        bzero(ring->data, count * sizeof (struct malo_rx_data));
                    614:        for (i = 0; i < count; i++) {
                    615:                desc = &ring->desc[i];
                    616:                data = &ring->data[i];
                    617:
                    618:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
                    619:                    0, BUS_DMA_NOWAIT, &data->map);
                    620:                if (error != 0) {
                    621:                        printf("%s: could not create DMA map\n",
                    622:                            sc->sc_dev.dv_xname);
                    623:                        goto fail;
                    624:                }
                    625:
                    626:                MGETHDR(data->m, M_DONTWAIT, MT_DATA);
                    627:                if (data->m == NULL) {
                    628:                        printf("%s: could not allocate rx mbuf\n",
                    629:                            sc->sc_dev.dv_xname);
                    630:                        error = ENOMEM;
                    631:                        goto fail;
                    632:                }
                    633:
                    634:                MCLGET(data->m, M_DONTWAIT);
                    635:                if (!(data->m->m_flags & M_EXT)) {
                    636:                        printf("%s: could not allocate rx mbuf cluster\n",
                    637:                            sc->sc_dev.dv_xname);
                    638:                        error = ENOMEM;
                    639:                        goto fail;
                    640:                }
                    641:
                    642:                error = bus_dmamap_load(sc->sc_dmat, data->map,
                    643:                    mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
                    644:                if (error != 0) {
                    645:                        printf("%s: could not load rx buf DMA map",
                    646:                            sc->sc_dev.dv_xname);
                    647:                        goto fail;
                    648:                }
                    649:
                    650:                desc->status = htole16(1);
                    651:                desc->physdata = htole32(data->map->dm_segs->ds_addr);
                    652:                desc->physnext = htole32(ring->physaddr +
                    653:                    (i + 1) % count * sizeof(struct malo_rx_desc));
                    654:        }
                    655:
                    656:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
                    657:            BUS_DMASYNC_PREWRITE);
                    658:
                    659:        return (0);
                    660:
                    661: fail:  malo_free_rx_ring(sc, ring);
                    662:        return (error);
                    663: }
                    664:
                    665: void
                    666: malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
                    667: {
                    668:        int i;
                    669:
                    670:        for (i = 0; i < ring->count; i++)
                    671:                ring->desc[i].status = 0;
                    672:
                    673:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
                    674:            BUS_DMASYNC_PREWRITE);
                    675:
                    676:        ring->cur = ring->next = 0;
                    677: }
                    678:
                    679: void
                    680: malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
                    681: {
                    682:        struct malo_rx_data *data;
                    683:        int i;
                    684:
                    685:        if (ring->desc != NULL) {
                    686:                bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
                    687:                    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    688:                bus_dmamap_unload(sc->sc_dmat, ring->map);
                    689:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
                    690:                    ring->count * sizeof(struct malo_rx_desc));
                    691:                bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
                    692:        }
                    693:
                    694:        if (ring->data != NULL) {
                    695:                for (i = 0; i < ring->count; i++) {
                    696:                        data = &ring->data[i];
                    697:
                    698:                        if (data->m != NULL) {
                    699:                                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                    700:                                    data->map->dm_mapsize,
                    701:                                    BUS_DMASYNC_POSTREAD);
                    702:                                bus_dmamap_unload(sc->sc_dmat, data->map);
                    703:                                m_freem(data->m);
                    704:                        }
                    705:
                    706:                        if (data->map != NULL)
                    707:                                bus_dmamap_destroy(sc->sc_dmat, data->map);
                    708:                }
                    709:                free(ring->data, M_DEVBUF);
                    710:        }
                    711: }
                    712:
                    713: int
                    714: malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
                    715:     int count)
                    716: {
                    717:        int i, nsegs, error;
                    718:
                    719:        ring->count = count;
                    720:        ring->queued = 0;
                    721:        ring->cur = ring->next = ring->stat = 0;
                    722:
                    723:        error = bus_dmamap_create(sc->sc_dmat,
                    724:            count * sizeof(struct malo_tx_desc), 1,
                    725:            count * sizeof(struct malo_tx_desc), 0, BUS_DMA_NOWAIT, &ring->map);
                    726:        if (error != 0) {
                    727:                printf("%s: could not create desc DMA map\n",
                    728:                    sc->sc_dev.dv_xname);
                    729:                goto fail;
                    730:        }
                    731:
                    732:        error = bus_dmamem_alloc(sc->sc_dmat,
                    733:            count * sizeof(struct malo_tx_desc),
                    734:            PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
                    735:        if (error != 0) {
                    736:                printf("%s: could not allocate DMA memory\n",
                    737:                    sc->sc_dev.dv_xname);
                    738:                goto fail;
                    739:        }
                    740:
                    741:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
                    742:            count * sizeof(struct malo_tx_desc), (caddr_t *)&ring->desc,
                    743:            BUS_DMA_NOWAIT);
                    744:        if (error != 0) {
                    745:                printf("%s: could not map desc DMA memory\n",
                    746:                    sc->sc_dev.dv_xname);
                    747:                goto fail;
                    748:        }
                    749:
                    750:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
                    751:            count * sizeof(struct malo_tx_desc), NULL, BUS_DMA_NOWAIT);
                    752:        if (error != 0) {
                    753:                printf("%s: could not load desc DMA map\n",
                    754:                    sc->sc_dev.dv_xname);
                    755:                goto fail;
                    756:        }
                    757:
                    758:        memset(ring->desc, 0, count * sizeof(struct malo_tx_desc));
                    759:        ring->physaddr = ring->map->dm_segs->ds_addr;
                    760:
                    761:        ring->data = malloc(count * sizeof(struct malo_tx_data), M_DEVBUF,
                    762:            M_NOWAIT);
                    763:        if (ring->data == NULL) {
                    764:                printf("%s: could not allocate soft data\n",
                    765:                    sc->sc_dev.dv_xname);
                    766:                error = ENOMEM;
                    767:                goto fail;
                    768:        }
                    769:
                    770:        memset(ring->data, 0, count * sizeof(struct malo_tx_data));
                    771:        for (i = 0; i < count; i++) {
                    772:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                    773:                    MALO_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
                    774:                    &ring->data[i].map);
                    775:                if (error != 0) {
                    776:                        printf("%s: could not create DMA map\n",
                    777:                            sc->sc_dev.dv_xname);
                    778:                        goto fail;
                    779:                }
                    780:                ring->desc[i].physnext = htole32(ring->physaddr +
                    781:                    (i + 1) % count * sizeof(struct malo_tx_desc));
                    782:        }
                    783:
                    784:        return (0);
                    785:
                    786: fail:  malo_free_tx_ring(sc, ring);
                    787:        return (error);
                    788: }
                    789:
                    790: void
                    791: malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
                    792: {
                    793:        struct malo_tx_desc *desc;
                    794:        struct malo_tx_data *data;
                    795:        int i;
                    796:
                    797:        for (i = 0; i < ring->count; i++) {
                    798:                desc = &ring->desc[i];
                    799:                data = &ring->data[i];
                    800:
                    801:                if (data->m != NULL) {
                    802:                        bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                    803:                            data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    804:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                    805:                        m_freem(data->m);
                    806:                        data->m = NULL;
                    807:                }
                    808:
                    809:                /*
                    810:                 * The node has already been freed at that point so don't call
                    811:                 * ieee80211_release_node() here.
                    812:                 */
                    813:                data->ni = NULL;
                    814:
                    815:                desc->status = 0;
                    816:        }
                    817:
                    818:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
                    819:            BUS_DMASYNC_PREWRITE);
                    820:
                    821:        ring->queued = 0;
                    822:        ring->cur = ring->next = ring->stat = 0;
                    823: }
                    824:
                    825: void
                    826: malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
                    827: {
                    828:        struct malo_tx_data *data;
                    829:        int i;
                    830:
                    831:        if (ring->desc != NULL) {
                    832:                bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
                    833:                    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    834:                bus_dmamap_unload(sc->sc_dmat, ring->map);
                    835:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
                    836:                    ring->count * sizeof(struct malo_tx_desc));
                    837:                bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
                    838:        }
                    839:
                    840:        if (ring->data != NULL) {
                    841:                for (i = 0; i < ring->count; i++) {
                    842:                        data = &ring->data[i];
                    843:
                    844:                        if (data->m != NULL) {
                    845:                                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                    846:                                    data->map->dm_mapsize,
                    847:                                    BUS_DMASYNC_POSTWRITE);
                    848:                                bus_dmamap_unload(sc->sc_dmat, data->map);
                    849:                                m_freem(data->m);
                    850:                        }
                    851:
                    852:                        /*
                    853:                         * The node has already been freed at that point so
                    854:                         * don't call ieee80211_release_node() here.
                    855:                         */
                    856:                        data->ni = NULL;
                    857:
                    858:                        if (data->map != NULL)
                    859:                                bus_dmamap_destroy(sc->sc_dmat, data->map);
                    860:                }
                    861:                free(ring->data, M_DEVBUF);
                    862:        }
                    863: }
                    864:
                    865: int
                    866: malo_init(struct ifnet *ifp)
                    867: {
                    868:        struct malo_softc *sc = ifp->if_softc;
                    869:        struct ieee80211com *ic = &sc->sc_ic;
                    870:        uint8_t chan;
                    871:        int error;
                    872:
                    873:        DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
                    874:
                    875:        /* if interface already runs stop it first */
                    876:        if (ifp->if_flags & IFF_RUNNING)
                    877:                malo_stop(sc);
                    878:
                    879:        /* power on cardbus socket */
                    880:        if (sc->sc_enable)
                    881:                sc->sc_enable(sc);
                    882:
                    883:        /* disable interrupts */
                    884:        malo_ctl_read4(sc, 0x0c30);
                    885:        malo_ctl_write4(sc, 0x0c30, 0);
                    886:        malo_ctl_write4(sc, 0x0c34, 0);
                    887:        malo_ctl_write4(sc, 0x0c3c, 0);
                    888:
                    889:        /* load firmware */
                    890:        if ((error = malo_load_bootimg(sc)))
                    891:                goto fail;
                    892:        if ((error = malo_load_firmware(sc)))
                    893:                goto fail;
                    894:
                    895:        /* enable interrupts */
                    896:        malo_ctl_write4(sc, 0x0c34, 0x1f);
                    897:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    898:        malo_ctl_write4(sc, 0x0c3c, 0x1f);
                    899:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                    900:
                    901:        if ((error = malo_cmd_get_spec(sc)))
                    902:                goto fail;
                    903:
                    904:        /* select default channel */
                    905:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                    906:        chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                    907:
                    908:        /* initialize hardware */
                    909:        if ((error = malo_cmd_set_channel(sc, chan))) {
                    910:                printf("%s: setting channel failed!\n",
                    911:                    sc->sc_dev.dv_xname);
                    912:                goto fail;
                    913:        }
                    914:        if ((error = malo_cmd_set_antenna(sc, 1))) {
                    915:                printf("%s: setting RX antenna failed!\n",
                    916:                    sc->sc_dev.dv_xname);
                    917:                goto fail;
                    918:        }
                    919:        if ((error = malo_cmd_set_antenna(sc, 2))) {
                    920:                printf("%s: setting TX antenna failed!\n",
                    921:                    sc->sc_dev.dv_xname);
                    922:                goto fail;
                    923:        }
                    924:        if ((error = malo_cmd_set_radio(sc, 1, 5))) {
                    925:                printf("%s: turn radio on failed!\n",
                    926:                    sc->sc_dev.dv_xname);
                    927:                goto fail;
                    928:        }
                    929:        if ((error = malo_cmd_set_txpower(sc, 100))) {
                    930:                printf("%s: setting TX power failed!\n",
                    931:                    sc->sc_dev.dv_xname);
                    932:                goto fail;
                    933:        }
                    934:        if ((error = malo_cmd_set_rts(sc, IEEE80211_RTS_MAX))) {
                    935:                printf("%s: setting RTS failed!\n",
                    936:                    sc->sc_dev.dv_xname);
                    937:                goto fail;
                    938:        }
                    939:
                    940:        /* WEP */
                    941:        if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
                    942:                /* set key */
                    943:                if (malo_set_wepkey(sc)) {
                    944:                        printf("%s: setting WEP key failed!\n",
                    945:                            sc->sc_dev.dv_xname);
                    946:                        goto fail;
                    947:                }
                    948:        }
                    949:
                    950:        ifp->if_flags |= IFF_RUNNING;
                    951:
                    952:        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                    953:                /* start background scanning */
                    954:                ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                    955:        else
                    956:                /* in monitor mode change directly into run state */
                    957:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                    958:
                    959:        return (0);
                    960:
                    961: fail:
                    962:        /* reset adapter */
                    963:        DPRINTF(("%s: malo_init failed, reseting card\n",
                    964:            sc->sc_dev.dv_xname));
                    965:        malo_ctl_write4(sc, 0x0c18, (1 << 15));
                    966:        return (error);
                    967: }
                    968:
                    969: int
                    970: malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                    971: {
                    972:        struct malo_softc *sc = ifp->if_softc;
                    973:        struct ieee80211com *ic = &sc->sc_ic;
                    974:        struct ifaddr *ifa;
                    975:        struct ifreq *ifr;
                    976:        int s, error = 0;
                    977:        uint8_t chan;
                    978:
                    979:        s = splnet();
                    980:
                    981:        switch (cmd) {
                    982:        case SIOCSIFADDR:
                    983:                ifa = (struct ifaddr *)data;
                    984:                ifp->if_flags |= IFF_UP;
                    985: #ifdef INET
                    986:                if (ifa->ifa_addr->sa_family == AF_INET)
                    987:                        arp_ifinit(&ic->ic_ac, ifa);
                    988: #endif
                    989:                /* FALLTHROUGH */
                    990:        case SIOCSIFFLAGS:
                    991:                if (ifp->if_flags & IFF_UP) {
                    992:                        if ((ifp->if_flags & IFF_RUNNING) == 0)
                    993:                                malo_init(ifp);
                    994:                } else {
                    995:                        if (ifp->if_flags & IFF_RUNNING)
                    996:                                malo_stop(sc);
                    997:                }
                    998:                break;
                    999:         case SIOCADDMULTI:
                   1000:         case SIOCDELMULTI:
                   1001:                ifr = (struct ifreq *)data;
                   1002:                error = (cmd == SIOCADDMULTI) ?
                   1003:                    ether_addmulti(ifr, &ic->ic_ac) :
                   1004:                    ether_delmulti(ifr, &ic->ic_ac);
                   1005:
                   1006:                if (error == ENETRESET)
                   1007:                        error = 0;
                   1008:                break;
                   1009:        case SIOCS80211CHANNEL:
                   1010:                /* allow fast channel switching in monitor mode */
                   1011:                error = ieee80211_ioctl(ifp, cmd, data);
                   1012:                if (error == ENETRESET &&
                   1013:                    ic->ic_opmode == IEEE80211_M_MONITOR) {
                   1014:                        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1015:                            (IFF_UP | IFF_RUNNING)) {
                   1016:                                ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                   1017:                                chan = ieee80211_chan2ieee(ic,
                   1018:                                    ic->ic_bss->ni_chan);
                   1019:                                malo_cmd_set_channel(sc, chan);
                   1020:                        }
                   1021:                        error = 0;
                   1022:                }
                   1023:                break;
                   1024:        default:
                   1025:                error = ieee80211_ioctl(ifp, cmd, data);
                   1026:                break;
                   1027:        }
                   1028:
                   1029:        if (error == ENETRESET) {
                   1030:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1031:                    (IFF_UP | IFF_RUNNING))
                   1032:                        malo_init(ifp);
                   1033:                error = 0;
                   1034:        }
                   1035:
                   1036:        splx(s);
                   1037:
                   1038:        return (error);
                   1039: }
                   1040:
                   1041: void
                   1042: malo_start(struct ifnet *ifp)
                   1043: {
                   1044:        struct malo_softc *sc = ifp->if_softc;
                   1045:        struct ieee80211com *ic = &sc->sc_ic;
                   1046:        struct mbuf *m0;
                   1047:        struct ieee80211_node *ni;
                   1048:
                   1049:        DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
                   1050:
                   1051:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   1052:                return;
                   1053:
                   1054:        for (;;) {
                   1055:                IF_POLL(&ic->ic_mgtq, m0);
                   1056:                if (m0 != NULL) {
                   1057:                        if (sc->sc_txring.queued >= MALO_TX_RING_COUNT) {
                   1058:                                ifp->if_flags |= IFF_OACTIVE;
                   1059:                                break;
                   1060:                        }
                   1061:                        IF_DEQUEUE(&ic->ic_mgtq, m0);
                   1062:
                   1063:                        ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
                   1064:                        m0->m_pkthdr.rcvif = NULL;
                   1065: #if NBPFILTER > 0
                   1066:                        if (ic->ic_rawbpf != NULL)
                   1067:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   1068: #endif
                   1069:                        if (malo_tx_mgt(sc, m0, ni) != 0)
                   1070:                                break;
                   1071:                } else {
                   1072:                        if (ic->ic_state != IEEE80211_S_RUN)
                   1073:                                break;
                   1074:                        IFQ_POLL(&ifp->if_snd, m0);
                   1075:                        if (m0 == NULL)
                   1076:                                break;
                   1077:                        if (sc->sc_txring.queued >= MALO_TX_RING_COUNT - 1) {
                   1078:                                ifp->if_flags |= IFF_OACTIVE;
                   1079:                                break;
                   1080:                        }
                   1081:                        IFQ_DEQUEUE(&ifp->if_snd, m0);
                   1082: #if NBPFILTER > 0
                   1083:                        if (ifp->if_bpf != NULL)
                   1084:                                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   1085: #endif
                   1086:                        m0 = ieee80211_encap(ifp, m0, &ni);
                   1087:                        if (m0 == NULL)
                   1088:                                continue;
                   1089: #if NBPFILTER > 0
                   1090:                        if (ic->ic_rawbpf != NULL)
                   1091:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   1092: #endif
                   1093:                        if (malo_tx_data(sc, m0, ni) != 0) {
                   1094:                                if (ni != NULL)
                   1095:                                        ieee80211_release_node(ic, ni);
                   1096:                                ifp->if_oerrors++;
                   1097:                                break;
                   1098:                        }
                   1099:                }
                   1100:        }
                   1101: }
                   1102:
                   1103: void
                   1104: malo_stop(struct malo_softc *sc)
                   1105: {
                   1106:        struct ieee80211com *ic = &sc->sc_ic;
                   1107:        struct ifnet *ifp = &ic->ic_if;
                   1108:
                   1109:        DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
                   1110:
                   1111:        /* reset adapter */
                   1112:        if (ifp->if_flags & IFF_RUNNING)
                   1113:                malo_ctl_write4(sc, 0x0c18, (1 << 15));
                   1114:
                   1115:        /* device is not running anymore */
                   1116:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1117:
                   1118:        /* change back to initial state */
                   1119:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   1120:
                   1121:        /* reset RX / TX rings */
                   1122:        malo_reset_tx_ring(sc, &sc->sc_txring);
                   1123:        malo_reset_rx_ring(sc, &sc->sc_rxring);
                   1124:
                   1125:        /* set initial rate */
                   1126:        sc->sc_last_txrate = -1;
                   1127:
                   1128:        /* power off cardbus socket */
                   1129:        if (sc->sc_disable)
                   1130:                sc->sc_disable(sc);
                   1131: }
                   1132:
                   1133: void
                   1134: malo_watchdog(struct ifnet *ifp)
                   1135: {
                   1136:
                   1137: }
                   1138:
                   1139: int
                   1140: malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   1141: {
                   1142:        struct malo_softc *sc = ic->ic_if.if_softc;
                   1143:        enum ieee80211_state ostate;
                   1144:        uint8_t chan;
                   1145:        int rate;
                   1146:
                   1147:        DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
                   1148:
                   1149:        ostate = ic->ic_state;
                   1150:        timeout_del(&sc->sc_scan_to);
                   1151:
                   1152:        switch (nstate) {
                   1153:        case IEEE80211_S_INIT:
                   1154:                break;
                   1155:        case IEEE80211_S_SCAN:
                   1156:                if (ostate == IEEE80211_S_INIT) {
                   1157:                        if (malo_cmd_set_prescan(sc) != 0)
                   1158:                                DPRINTF(("%s: can't set prescan\n",
                   1159:                                    sc->sc_dev.dv_xname));
                   1160:                } else {
                   1161:                        chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   1162:
                   1163:                        malo_cmd_set_channel(sc, chan);
                   1164:                }
                   1165:                timeout_add(&sc->sc_scan_to, hz / 2);
                   1166:                break;
                   1167:        case IEEE80211_S_AUTH:
                   1168:                DPRINTF(("newstate AUTH\n"));
                   1169:                malo_cmd_set_postscan(sc, ic->ic_myaddr, 1);
                   1170:                chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   1171:                malo_cmd_set_channel(sc, chan);
                   1172:                break;
                   1173:        case IEEE80211_S_ASSOC:
                   1174:                DPRINTF(("newstate ASSOC\n"));
                   1175:                if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
                   1176:                        malo_cmd_set_radio(sc, 1, 3); /* short preamble */
                   1177:                else
                   1178:                        malo_cmd_set_radio(sc, 1, 1); /* long preamble */
                   1179:
                   1180:                malo_cmd_set_aid(sc, ic->ic_bss->ni_bssid,
                   1181:                    ic->ic_bss->ni_associd);
                   1182:
                   1183:                if (ic->ic_fixed_rate == -1)
                   1184:                        /* automatic rate adaption */
                   1185:                        malo_cmd_set_rate(sc, 0);
                   1186:                else {
                   1187:                        /* fixed rate */
                   1188:                        rate = malo_fix2rate(ic->ic_fixed_rate);
                   1189:                        malo_cmd_set_rate(sc, rate);
                   1190:                }
                   1191:
                   1192:                malo_set_slot(sc);
                   1193:                break;
                   1194:        case IEEE80211_S_RUN:
                   1195:                DPRINTF(("newstate RUN\n"));
                   1196:                break;
                   1197:        default:
                   1198:                break;
                   1199:        }
                   1200:
                   1201:        return (sc->sc_newstate(ic, nstate, arg));
                   1202: }
                   1203:
                   1204: void
                   1205: malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
                   1206: {
                   1207:
                   1208: }
                   1209:
                   1210: struct ieee80211_node *
                   1211: malo_node_alloc(struct ieee80211com *ic)
                   1212: {
                   1213:        struct malo_node *wn;
                   1214:
                   1215:        wn = malloc(sizeof(struct malo_node), M_DEVBUF, M_NOWAIT);
                   1216:        if (wn == NULL)
                   1217:                return (NULL);
                   1218:
                   1219:        bzero(wn, sizeof(struct malo_node));
                   1220:
                   1221:        return ((struct ieee80211_node *)wn);
                   1222: }
                   1223:
                   1224: int
                   1225: malo_media_change(struct ifnet *ifp)
                   1226: {
                   1227:        int error;
                   1228:
                   1229:        DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
                   1230:
                   1231:        error = ieee80211_media_change(ifp);
                   1232:        if (error != ENETRESET)
                   1233:                return (error);
                   1234:
                   1235:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
                   1236:                malo_init(ifp);
                   1237:
                   1238:        return (0);
                   1239: }
                   1240:
                   1241: void
                   1242: malo_media_status(struct ifnet *ifp, struct ifmediareq *imr)
                   1243: {
                   1244:        struct malo_softc *sc = ifp->if_softc;
                   1245:        struct ieee80211com *ic = &sc->sc_ic;
                   1246:
                   1247:        imr->ifm_status = IFM_AVALID;
                   1248:        imr->ifm_active = IFM_IEEE80211;
                   1249:        if (ic->ic_state == IEEE80211_S_RUN)
                   1250:                imr->ifm_status |= IFM_ACTIVE;
                   1251:
                   1252:        /* report last TX rate used by chip */
                   1253:        imr->ifm_active |= ieee80211_rate2media(ic, sc->sc_last_txrate,
                   1254:            ic->ic_curmode);
                   1255:
                   1256:        switch (ic->ic_opmode) {
                   1257:        case IEEE80211_M_STA:
                   1258:                break;
                   1259:        case IEEE80211_M_IBSS:
                   1260:                imr->ifm_active |= IFM_IEEE80211_ADHOC;
                   1261:                break;
                   1262:        case IEEE80211_M_MONITOR:
                   1263:                imr->ifm_active |= IFM_IEEE80211_MONITOR;
                   1264:                break;
                   1265:        case IEEE80211_M_AHDEMO:
                   1266:                break;
                   1267:        case IEEE80211_M_HOSTAP:
                   1268:                break;
                   1269:        }
                   1270:
                   1271:        switch (ic->ic_curmode) {
                   1272:                case IEEE80211_MODE_11B:
                   1273:                        imr->ifm_active |= IFM_IEEE80211_11B;
                   1274:                        break;
                   1275:                case IEEE80211_MODE_11G:
                   1276:                        imr->ifm_active |= IFM_IEEE80211_11G;
                   1277:                        break;
                   1278:        }
                   1279: }
                   1280:
                   1281: int
                   1282: malo_chip2rate(int chip_rate)
                   1283: {
                   1284:        switch (chip_rate) {
                   1285:        /* CCK rates */
                   1286:        case  0:        return (2);
                   1287:        case  1:        return (4);
                   1288:        case  2:        return (11);
                   1289:        case  3:        return (22);
                   1290:
                   1291:        /* OFDM rates */
                   1292:        case  4:        return (0); /* reserved */
                   1293:        case  5:        return (12);
                   1294:        case  6:        return (18);
                   1295:        case  7:        return (24);
                   1296:        case  8:        return (36);
                   1297:        case  9:        return (48);
                   1298:        case 10:        return (72);
                   1299:        case 11:        return (96);
                   1300:        case 12:        return (108);
                   1301:
                   1302:        /* no rate select yet or unknown rate */
                   1303:        default:        return (-1);
                   1304:        }
                   1305: }
                   1306:
                   1307: int
                   1308: malo_fix2rate(int fix_rate)
                   1309: {
                   1310:        switch (fix_rate) {
                   1311:        /* CCK rates */
                   1312:        case  0:        return (2);
                   1313:        case  1:        return (4);
                   1314:        case  2:        return (11);
                   1315:        case  3:        return (22);
                   1316:
                   1317:        /* OFDM rates */
                   1318:        case  4:        return (12);
                   1319:        case  5:        return (18);
                   1320:        case  6:        return (24);
                   1321:        case  7:        return (36);
                   1322:        case  8:        return (48);
                   1323:        case  9:        return (72);
                   1324:        case 10:        return (96);
                   1325:        case 11:        return (108);
                   1326:
                   1327:        /* unknown rate: should not happen */
                   1328:        default:        return (0);
                   1329:        }
                   1330: }
                   1331:
                   1332: void
                   1333: malo_next_scan(void *arg)
                   1334: {
                   1335:        struct malo_softc *sc = arg;
                   1336:        struct ieee80211com *ic = &sc->sc_ic;
                   1337:        struct ifnet *ifp = &ic->ic_if;
                   1338:        int s;
                   1339:
                   1340:        DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
                   1341:
                   1342:        s = splnet();
                   1343:
                   1344:        if (ic->ic_state == IEEE80211_S_SCAN)
                   1345:                ieee80211_next_scan(ifp);
                   1346:
                   1347:        splx(s);
                   1348: }
                   1349:
                   1350: void
                   1351: malo_tx_intr(struct malo_softc *sc)
                   1352: {
                   1353:        struct ieee80211com *ic = &sc->sc_ic;
                   1354:        struct ifnet *ifp = &ic->ic_if;
                   1355:        struct malo_tx_desc *desc;
                   1356:        struct malo_tx_data *data;
                   1357:        struct malo_node *rn;
                   1358:        int stat;
                   1359:
                   1360:        DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
                   1361:
                   1362:        stat = sc->sc_txring.stat;
                   1363:        for (;;) {
                   1364:                desc = &sc->sc_txring.desc[sc->sc_txring.stat];
                   1365:                data = &sc->sc_txring.data[sc->sc_txring.stat];
                   1366:                rn = (struct malo_node *)data->ni;
                   1367:
                   1368:                /* check if TX descriptor is not owned by FW anymore */
                   1369:                if ((letoh32(desc->status) & 0x80000000) ||
                   1370:                    !(letoh32(data->softstat) & 0x80))
                   1371:                        break;
                   1372:
                   1373:                /* if no frame has been sent, ignore */
                   1374:                if (rn == NULL)
                   1375:                        goto next;
                   1376:
                   1377:                /* check TX state */
                   1378:                switch (letoh32(desc->status) & 0x1) {
                   1379:                case 0x1:
                   1380:                        DPRINTFN(2, ("data frame was sent successfully\n"));
                   1381:                        ifp->if_opackets++;
                   1382:                        break;
                   1383:                default:
                   1384:                        DPRINTF(("data frame sending error\n"));
                   1385:                        ifp->if_oerrors++;
                   1386:                        break;
                   1387:                }
                   1388:
                   1389:                /* save last used TX rate */
                   1390:                sc->sc_last_txrate = malo_chip2rate(desc->datarate);
                   1391:
                   1392:                /* cleanup TX data and TX descritpor */
                   1393:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   1394:                    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1395:                bus_dmamap_unload(sc->sc_dmat, data->map);
                   1396:                m_freem(data->m);
                   1397:                ieee80211_release_node(ic, data->ni);
                   1398:                data->m = NULL;
                   1399:                data->ni = NULL;
                   1400:                data->softstat &= htole32(~0x80);
                   1401:                desc->status = 0;
                   1402:                desc->len = 0;
                   1403:
                   1404:                DPRINTFN(2, ("tx done idx=%u\n", sc->sc_txring.stat));
                   1405:
                   1406:                sc->sc_txring.queued--;
                   1407: next:
                   1408:                if (++sc->sc_txring.stat >= sc->sc_txring.count)
                   1409:                        sc->sc_txring.stat = 0;
                   1410:                if (sc->sc_txring.stat == stat)
                   1411:                        break;
                   1412:        }
                   1413:
                   1414:        sc->sc_tx_timer = 0;
                   1415:        ifp->if_flags &= ~IFF_OACTIVE;
                   1416:        malo_start(ifp);
                   1417: }
                   1418:
                   1419: int
                   1420: malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                   1421: {
                   1422:        struct ieee80211com *ic = &sc->sc_ic;
                   1423:        struct ifnet *ifp = &ic->ic_if;
                   1424:        struct malo_tx_desc *desc;
                   1425:        struct malo_tx_data *data;
                   1426:        struct ieee80211_frame *wh;
                   1427:        int error;
                   1428:
                   1429:        DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
                   1430:
                   1431:        desc = &sc->sc_txring.desc[sc->sc_txring.cur];
                   1432:        data = &sc->sc_txring.data[sc->sc_txring.cur];
                   1433:
                   1434:        if (m0->m_len < sizeof(struct ieee80211_frame)) {
                   1435:                m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
                   1436:                if (m0 == NULL) {
                   1437:                        ifp->if_ierrors++;
                   1438:                        return (ENOBUFS);
                   1439:                }
                   1440:        }
                   1441:        wh = mtod(m0, struct ieee80211_frame *);
                   1442:
                   1443:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   1444:                m0 = ieee80211_wep_crypt(ifp, m0, 1);
                   1445:                if (m0 == NULL)
                   1446:                        return (ENOBUFS);
                   1447:
                   1448:                /* packet header may have moved, reset our local pointer */
                   1449:                wh = mtod(m0, struct ieee80211_frame *);
                   1450:        }
                   1451:
                   1452: #if NBPFILTER > 0
                   1453:        if (sc->sc_drvbpf != NULL) {
                   1454:                struct mbuf mb;
                   1455:                struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
                   1456:
                   1457:                tap->wt_flags = 0;
                   1458:                tap->wt_rate = sc->sc_last_txrate;
                   1459:                tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   1460:                tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1461:
                   1462:                mb.m_data = (caddr_t)tap;
                   1463:                mb.m_len = sc->sc_txtap_len;
                   1464:                mb.m_next = m0;
                   1465:                mb.m_nextpkt = NULL;
                   1466:                mb.m_type = 0;
                   1467:                mb.m_flags = 0;
                   1468:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
                   1469:        }
                   1470: #endif
                   1471:        /*
                   1472:         * inject FW specific fields into the 802.11 frame
                   1473:         *
                   1474:         *  2 bytes FW len (inject)
                   1475:         * 24 bytes 802.11 frame header
                   1476:         *  6 bytes addr4 (inject)
                   1477:         *  n bytes 802.11 frame body
                   1478:         */
                   1479:        if (M_LEADINGSPACE(m0) < 8) {
                   1480:                if (M_TRAILINGSPACE(m0) < 8)
                   1481:                        panic("%s: not enough space for mbuf dance",
                   1482:                            sc->sc_dev.dv_xname);
                   1483:                bcopy(m0->m_data, m0->m_data + 8, m0->m_len);
                   1484:                m0->m_data += 8;
                   1485:        }
                   1486:
                   1487:        /* move frame header */
                   1488:        bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh));
                   1489:        m0->m_data -= 8;
                   1490:        m0->m_len += 8;
                   1491:        m0->m_pkthdr.len += 8;
                   1492:        *mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */
                   1493:
                   1494:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
                   1495:            BUS_DMA_NOWAIT);
                   1496:        if (error != 0) {
                   1497:                printf("%s: could not map mbuf (error %d)\n",
                   1498:                    sc->sc_dev.dv_xname, error);
                   1499:                m_freem(m0);
                   1500:                return (error);
                   1501:        }
                   1502:
                   1503:        data->m = m0;
                   1504:        data->ni = ni;
                   1505:        data->softstat |= htole32(0x80);
                   1506:
                   1507:        malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 0,
                   1508:            data->map->dm_segs, data->map->dm_nsegs);
                   1509:
                   1510:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                   1511:            BUS_DMASYNC_PREWRITE);
                   1512:        bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
                   1513:            sc->sc_txring.cur * sizeof(struct malo_tx_desc),
                   1514:            sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
                   1515:
                   1516:        DPRINTFN(2, ("%s: sending mgmt frame, pktlen=%u, idx=%u\n",
                   1517:            sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur));
                   1518:
                   1519:        sc->sc_txring.queued++;
                   1520:        sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
                   1521:
                   1522:        /* kick mgmt TX */
                   1523:        malo_ctl_write4(sc, 0x0c18, 1);
                   1524:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                   1525:
                   1526:        return (0);
                   1527: }
                   1528:
                   1529: int
                   1530: malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
                   1531:     struct ieee80211_node *ni)
                   1532: {
                   1533:        struct ieee80211com *ic = &sc->sc_ic;
                   1534:        struct ifnet *ifp = &ic->ic_if;
                   1535:        struct malo_tx_desc *desc;
                   1536:        struct malo_tx_data *data;
                   1537:        struct ieee80211_frame *wh;
                   1538:        struct mbuf *mnew;
                   1539:        int error;
                   1540:
                   1541:        DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
                   1542:
                   1543:        desc = &sc->sc_txring.desc[sc->sc_txring.cur];
                   1544:        data = &sc->sc_txring.data[sc->sc_txring.cur];
                   1545:
                   1546:        if (m0->m_len < sizeof(struct ieee80211_frame)) {
                   1547:                m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
                   1548:                if (m0 == NULL) {
                   1549:                        ifp->if_ierrors++;
                   1550:                        return (ENOBUFS);
                   1551:                }
                   1552:        }
                   1553:        wh = mtod(m0, struct ieee80211_frame *);
                   1554:
                   1555:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   1556:                m0 = ieee80211_wep_crypt(ifp, m0, 1);
                   1557:                if (m0 == NULL)
                   1558:                        return (ENOBUFS);
                   1559:
                   1560:                /* packet header may have moved, reset our local pointer */
                   1561:                wh = mtod(m0, struct ieee80211_frame *);
                   1562:        }
                   1563:
                   1564: #if NBPFILTER > 0
                   1565:        if (sc->sc_drvbpf != NULL) {
                   1566:                struct mbuf mb;
                   1567:                struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
                   1568:
                   1569:                tap->wt_flags = 0;
                   1570:                tap->wt_rate = sc->sc_last_txrate;
                   1571:                tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   1572:                tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1573:
                   1574:                mb.m_data = (caddr_t)tap;
                   1575:                mb.m_len = sc->sc_txtap_len;
                   1576:                mb.m_next = m0;
                   1577:                mb.m_nextpkt = NULL;
                   1578:                mb.m_type = 0;
                   1579:                mb.m_flags = 0;
                   1580:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
                   1581:        }
                   1582: #endif
                   1583:
                   1584:        /*
                   1585:         * inject FW specific fields into the 802.11 frame
                   1586:         *
                   1587:         *  2 bytes FW len (inject)
                   1588:         * 24 bytes 802.11 frame header
                   1589:         *  6 bytes addr4 (inject)
                   1590:         *  n bytes 802.11 frame body
                   1591:         *
                   1592:         * For now copy all into a new mcluster.
                   1593:         */
                   1594:        MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                   1595:        if (mnew == NULL)
                   1596:                return (ENOBUFS);
                   1597:        MCLGET(mnew, M_DONTWAIT);
                   1598:        if (!(mnew->m_flags & M_EXT)) {
                   1599:                m_free(mnew);
                   1600:                return (ENOBUFS);
                   1601:        }
                   1602:
                   1603:        *mtod(mnew, uint16_t *) = htole16(m0->m_pkthdr.len - 24); /* FW len */
                   1604:        bcopy(wh, mtod(mnew, caddr_t) + 2, sizeof(*wh));
                   1605:        bzero(mtod(mnew, caddr_t) + 26, 6);
                   1606:        m_copydata(m0, sizeof(*wh), m0->m_pkthdr.len - sizeof(*wh),
                   1607:            mtod(mnew, caddr_t) + 32);
                   1608:        mnew->m_pkthdr.len = mnew->m_len = m0->m_pkthdr.len + 8;
                   1609:        m_freem(m0);
                   1610:        m0 = mnew;
                   1611:
                   1612:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
                   1613:            BUS_DMA_NOWAIT);
                   1614:        if (error != 0) {
                   1615:                printf("%s: could not map mbuf (error %d)\n",
                   1616:                    sc->sc_dev.dv_xname, error);
                   1617:                m_freem(m0);
                   1618:                return (error);
                   1619:        }
                   1620:
                   1621:        data->m = m0;
                   1622:        data->ni = ni;
                   1623:        data->softstat |= htole32(0x80);
                   1624:
                   1625:        malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 1,
                   1626:            data->map->dm_segs, data->map->dm_nsegs);
                   1627:
                   1628:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                   1629:            BUS_DMASYNC_PREWRITE);
                   1630:        bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
                   1631:            sc->sc_txring.cur * sizeof(struct malo_tx_desc),
                   1632:            sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
                   1633:
                   1634:        DPRINTFN(2, ("%s: sending data frame, pktlen=%u, idx=%u\n",
                   1635:            sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur));
                   1636:
                   1637:        sc->sc_txring.queued++;
                   1638:        sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
                   1639:
                   1640:        /* kick data TX */
                   1641:        malo_ctl_write4(sc, 0x0c18, 1);
                   1642:        malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
                   1643:
                   1644:        return (0);
                   1645: }
                   1646:
                   1647: void
                   1648: malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
                   1649:     int len, int rate, const bus_dma_segment_t *segs, int nsegs)
                   1650: {
                   1651:        desc->len = htole16(segs[0].ds_len);
                   1652:        desc->datarate = rate; /* 0 = mgmt frame, 1 = data frame */
                   1653:        desc->physdata = htole32(segs[0].ds_addr);
                   1654:        desc->status = htole32(0x00000001 | 0x80000000);
                   1655: }
                   1656:
                   1657: void
                   1658: malo_rx_intr(struct malo_softc *sc)
                   1659: {
                   1660:        struct ieee80211com *ic = &sc->sc_ic;
                   1661:        struct ifnet *ifp = &ic->ic_if;
                   1662:        struct malo_rx_desc *desc;
                   1663:        struct malo_rx_data *data;
                   1664:        struct ieee80211_frame *wh;
                   1665:        struct ieee80211_node *ni;
                   1666:        struct mbuf *mnew, *m;
                   1667:        uint32_t rxRdPtr, rxWrPtr;
                   1668:        int error, i;
                   1669:
                   1670:        rxRdPtr = malo_mem_read4(sc, sc->sc_RxPdRdPtr);
                   1671:        rxWrPtr = malo_mem_read4(sc, sc->sc_RxPdWrPtr);
                   1672:
                   1673:        for (i = 0; i < MALO_RX_RING_COUNT && rxRdPtr != rxWrPtr; i++) {
                   1674:                desc = &sc->sc_rxring.desc[sc->sc_rxring.cur];
                   1675:                data = &sc->sc_rxring.data[sc->sc_rxring.cur];
                   1676:
                   1677:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
                   1678:                    sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
                   1679:                    sizeof(struct malo_rx_desc), BUS_DMASYNC_POSTREAD);
                   1680:
                   1681:                DPRINTFN(3, ("rx intr idx=%d, rxctrl=0x%02x, rssi=%d, "
                   1682:                    "status=0x%02x, channel=%d, len=%d, res1=%02x, rate=%d, "
                   1683:                    "physdata=0x%04x, physnext=0x%04x, qosctrl=%02x, res2=%d\n",
                   1684:                    sc->sc_rxring.cur, desc->rxctrl, desc->rssi, desc->status,
                   1685:                    desc->channel, letoh16(desc->len), desc->reserved1,
                   1686:                    desc->datarate, letoh32(desc->physdata),
                   1687:                    letoh32(desc->physnext), desc->qosctrl, desc->reserved2));
                   1688:
                   1689:                if ((desc->rxctrl & 0x80) == 0)
                   1690:                        break;
                   1691:
                   1692:                MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                   1693:                if (mnew == NULL) {
                   1694:                        ifp->if_ierrors++;
                   1695:                        goto skip;
                   1696:                }
                   1697:
                   1698:                MCLGET(mnew, M_DONTWAIT);
                   1699:                if (!(mnew->m_flags & M_EXT)) {
                   1700:                        m_freem(mnew);
                   1701:                        ifp->if_ierrors++;
                   1702:                        goto skip;
                   1703:                }
                   1704:
                   1705:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   1706:                    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1707:                bus_dmamap_unload(sc->sc_dmat, data->map);
                   1708:
                   1709:                error = bus_dmamap_load(sc->sc_dmat, data->map,
                   1710:                    mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
                   1711:                if (error != 0) {
                   1712:                        m_freem(mnew);
                   1713:
                   1714:                        error = bus_dmamap_load(sc->sc_dmat, data->map,
                   1715:                            mtod(data->m, void *), MCLBYTES, NULL,
                   1716:                            BUS_DMA_NOWAIT);
                   1717:                        if (error != 0) {
                   1718:                                panic("%s: could not load old rx mbuf",
                   1719:                                    sc->sc_dev.dv_xname);
                   1720:                        }
                   1721:                        ifp->if_ierrors++;
                   1722:                        goto skip;
                   1723:                }
                   1724:
                   1725:                /*
                   1726:                 * New mbuf mbuf successfully loaded
                   1727:                 */
                   1728:                m = data->m;
                   1729:                data->m = mnew;
                   1730:                desc->physdata = htole32(data->map->dm_segs->ds_addr);
                   1731:
                   1732:                /* finalize mbuf */
                   1733:                m->m_pkthdr.rcvif = ifp;
                   1734:                m->m_pkthdr.len = m->m_len = letoh16(desc->len);
                   1735:
                   1736:                /*
                   1737:                 * cut out FW specific fields from the 802.11 frame
                   1738:                 *
                   1739:                 *  2 bytes FW len (cut out)
                   1740:                 * 24 bytes 802.11 frame header
                   1741:                 *  6 bytes addr4 (cut out)
                   1742:                 *  n bytes 802.11 frame data
                   1743:                 */
                   1744:                bcopy(m->m_data, m->m_data + 6, 26);
                   1745:                m_adj(m, 8);
                   1746:
                   1747: #if NBPFILTER > 0
                   1748:                if (sc->sc_drvbpf != NULL) {
                   1749:                        struct mbuf mb;
                   1750:                        struct malo_rx_radiotap_hdr *tap = &sc->sc_rxtap;
                   1751:
                   1752:                        tap->wr_flags = 0;
                   1753:                        tap->wr_chan_freq =
                   1754:                            htole16(ic->ic_bss->ni_chan->ic_freq);
                   1755:                        tap->wr_chan_flags =
                   1756:                            htole16(ic->ic_bss->ni_chan->ic_flags);
                   1757:                        tap->wr_rssi = desc->rssi;
                   1758:                        tap->wr_max_rssi = ic->ic_max_rssi;
                   1759:
                   1760:                        mb.m_data = (caddr_t)tap;
                   1761:                        mb.m_len = sc->sc_rxtap_len;
                   1762:                        mb.m_next = m;
                   1763:                        mb.m_nextpkt = NULL;
                   1764:                        mb.m_type = 0;
                   1765:                        mb.m_flags = 0;
                   1766:                        bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
                   1767:                }
                   1768: #endif
                   1769:
                   1770:                wh = mtod(m, struct ieee80211_frame *);
                   1771:                ni = ieee80211_find_rxnode(ic, wh);
                   1772:
                   1773:                /* send the frame to the 802.11 layer */
                   1774:                ieee80211_input(ifp, m, ni, desc->rssi, 0);
                   1775:
                   1776:                /* node is no longer needed */
                   1777:                ieee80211_release_node(ic, ni);
                   1778:
                   1779: skip:
                   1780:                desc->rxctrl = 0;
                   1781:                rxRdPtr = letoh32(desc->physnext);
                   1782:
                   1783:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
                   1784:                    sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
                   1785:                    sizeof(struct malo_rx_desc), BUS_DMASYNC_PREWRITE);
                   1786:
                   1787:                sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
                   1788:                    MALO_RX_RING_COUNT;
                   1789:        }
                   1790:
                   1791:        malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr);
                   1792:
                   1793:        /*
                   1794:         * In HostAP mode, ieee80211_input() will enqueue packets in if_snd
                   1795:         * without calling if_start().
                   1796:         */
                   1797:        if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_flags & IFF_OACTIVE))
                   1798:                (*ifp->if_start)(ifp);
                   1799: }
                   1800:
                   1801: int
                   1802: malo_load_bootimg(struct malo_softc *sc)
                   1803: {
                   1804:        char *name = "malo8335-h";
                   1805:        uint8_t *ucode;
                   1806:        size_t size;
                   1807:        int error, i;
                   1808:
                   1809:        /* load boot firmware */
                   1810:        if ((error = loadfirmware(name, &ucode, &size)) != 0) {
                   1811:                printf("%s: error %d, could not read microcode %s!\n",
                   1812:                    sc->sc_dev.dv_xname, error, name);
                   1813:                return (EIO);
                   1814:        }
                   1815:
                   1816:        /*
                   1817:         * It seems we are putting this code directly onto the stack of
                   1818:         * the ARM cpu. I don't know why we need to instruct the DMA
                   1819:         * engine to move the code. This is a big riddle without docu.
                   1820:         */
                   1821:        DPRINTF(("%s: loading boot firmware\n", sc->sc_dev.dv_xname));
                   1822:        malo_mem_write2(sc, 0xbef8, 0x001);
                   1823:        malo_mem_write2(sc, 0xbefa, size);
                   1824:        malo_mem_write4(sc, 0xbefc, 0);
                   1825:
                   1826:        bus_space_write_region_1(sc->sc_mem1_bt, sc->sc_mem1_bh, 0xbf00,
                   1827:            ucode, size);
                   1828:
                   1829:        /*
                   1830:         * we loaded the firmware into card memory now tell the CPU
                   1831:         * to fetch the code and execute it. The memory mapped via the
                   1832:         * first bar is internaly mapped to 0xc0000000.
                   1833:         */
                   1834:        malo_send_cmd(sc, 0xc000bef8);
                   1835:
                   1836:        /* wait for the device to go into FW loading mode */
                   1837:        for (i = 0; i < 10; i++) {
                   1838:                delay(50);
                   1839:                malo_ctl_barrier(sc, BUS_SPACE_BARRIER_READ);
                   1840:                if (malo_ctl_read4(sc, 0x0c14) == 0x5)
                   1841:                        break;
                   1842:        }
                   1843:        if (i == 10) {
                   1844:                printf("%s: timeout at boot firmware load!\n",
                   1845:                    sc->sc_dev.dv_xname);
                   1846:                free(ucode, M_DEVBUF);
                   1847:                return (ETIMEDOUT);
                   1848:        }
                   1849:        free(ucode, M_DEVBUF);
                   1850:
                   1851:        /* tell the card we're done and... */
                   1852:        malo_mem_write2(sc, 0xbef8, 0x001);
                   1853:        malo_mem_write2(sc, 0xbefa, 0);
                   1854:        malo_mem_write4(sc, 0xbefc, 0);
                   1855:        malo_send_cmd(sc, 0xc000bef8);
                   1856:
                   1857:        DPRINTF(("%s: boot firmware loaded\n", sc->sc_dev.dv_xname));
                   1858:
                   1859:        return (0);
                   1860: }
                   1861:
                   1862: int
                   1863: malo_load_firmware(struct malo_softc *sc)
                   1864: {
                   1865:        struct malo_cmdheader *hdr;
                   1866:        char *name = "malo8335-m";
                   1867:        void *data;
                   1868:        uint8_t *ucode;
                   1869:        size_t size, count, bsize;
                   1870:        int i, sn, error;
                   1871:
                   1872:        /* load real firmware now */
                   1873:        if ((error = loadfirmware(name, &ucode, &size)) != 0) {
                   1874:                printf("%s: error %d, could not read microcode %s!\n",
                   1875:                    sc->sc_dev.dv_xname, error, name);
                   1876:                return (EIO);
                   1877:        }
                   1878:
                   1879:        DPRINTF(("%s: uploading firmware\n", sc->sc_dev.dv_xname));
                   1880:
                   1881:        hdr = sc->sc_cmd_mem;
                   1882:        data = hdr + 1;
                   1883:        sn = 1;
                   1884:        for (count = 0; count < size; count += bsize) {
                   1885:                bsize = MIN(256, size - count);
                   1886:
                   1887:                hdr->cmd = htole16(0x0001);
                   1888:                hdr->size = htole16(bsize);
                   1889:                hdr->seqnum = htole16(sn++);
                   1890:                hdr->result = 0;
                   1891:
                   1892:                bcopy(ucode + count, data, bsize);
                   1893:
                   1894:                bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   1895:                    BUS_DMASYNC_PREWRITE);
                   1896:                malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
                   1897:                bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   1898:                    BUS_DMASYNC_POSTWRITE);
                   1899:                delay(500);
                   1900:        }
                   1901:        free(ucode, M_DEVBUF);
                   1902:
                   1903:        DPRINTF(("%s: firmware upload finished\n", sc->sc_dev.dv_xname));
                   1904:
                   1905:        /*
                   1906:         * send a command with size 0 to tell that the firmware has been
                   1907:         * uploaded
                   1908:         */
                   1909:        hdr->cmd = htole16(0x0001);
                   1910:        hdr->size = 0;
                   1911:        hdr->seqnum = htole16(sn++);
                   1912:        hdr->result = 0;
                   1913:
                   1914:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   1915:            BUS_DMASYNC_PREWRITE);
                   1916:        malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
                   1917:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   1918:            BUS_DMASYNC_POSTWRITE);
                   1919:        delay(100);
                   1920:
                   1921:        DPRINTF(("%s: loading firmware\n", sc->sc_dev.dv_xname));
                   1922:
                   1923:        /* wait until firmware has been loaded */
                   1924:        for (i = 0; i < 200; i++) {
                   1925:                malo_ctl_write4(sc, 0x0c10, 0x5a);
                   1926:                delay(500);
                   1927:                malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE |
                   1928:                     BUS_SPACE_BARRIER_READ);
                   1929:                if (malo_ctl_read4(sc, 0x0c14) == 0xf0f1f2f4)
                   1930:                        break;
                   1931:        }
                   1932:        if (i == 200) {
                   1933:                printf("%s: timeout at firmware load!\n", sc->sc_dev.dv_xname);
                   1934:                return (ETIMEDOUT);
                   1935:        }
                   1936:
                   1937:        DPRINTF(("%s: firmware loaded\n", sc->sc_dev.dv_xname));
                   1938:
                   1939:        return (0);
                   1940: }
                   1941:
                   1942: int
                   1943: malo_set_wepkey(struct malo_softc *sc)
                   1944: {
                   1945:        struct ieee80211com *ic = &sc->sc_ic;
                   1946:        int i;
                   1947:
                   1948:        for (i = 0; i < IEEE80211_WEP_NKID; i++) {
                   1949:                struct ieee80211_key *k = &ic->ic_nw_keys[i];
                   1950:
                   1951:                if (k->k_len == 0)
                   1952:                        continue;
                   1953:
                   1954:                if (malo_cmd_set_wepkey(sc, k, i))
                   1955:                        return (ENXIO);
                   1956:        }
                   1957:
                   1958:        return (0);
                   1959: }
                   1960:
                   1961: int
                   1962: malo_set_slot(struct malo_softc *sc)
                   1963: {
                   1964:        struct ieee80211com *ic = &sc->sc_ic;
                   1965:
                   1966:        if (ic->ic_flags & IEEE80211_F_SHSLOT) {
                   1967:                /* set short slot */
                   1968:                if (malo_cmd_set_slot(sc, 1)) {
                   1969:                        printf("%s: setting short slot failed\n",
                   1970:                            sc->sc_dev.dv_xname);
                   1971:                        return (ENXIO);
                   1972:                }
                   1973:        } else {
                   1974:                /* set long slot */
                   1975:                if (malo_cmd_set_slot(sc, 0)) {
                   1976:                        printf("%s: setting long slot failed\n",
                   1977:                            sc->sc_dev.dv_xname);
                   1978:                        return (ENXIO);
                   1979:                }
                   1980:        }
                   1981:
                   1982:        return (0);
                   1983: }
                   1984:
                   1985: void
                   1986: malo_update_slot(struct ieee80211com *ic)
                   1987: {
                   1988:        struct malo_softc *sc = ic->ic_if.if_softc;
                   1989:
                   1990:        malo_set_slot(sc);
                   1991:
                   1992:        if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
                   1993:                /* TODO */
                   1994:        }
                   1995: }
                   1996:
                   1997: #ifdef MALO_DEBUG
                   1998: void
                   1999: malo_hexdump(void *buf, int len)
                   2000: {
                   2001:        u_char b[16];
                   2002:        int i, j, l;
                   2003:
                   2004:        for (i = 0; i < len; i += l) {
                   2005:                printf("%4i:", i);
                   2006:                l = min(sizeof(b), len - i);
                   2007:                bcopy(buf + i, b, l);
                   2008:
                   2009:                for (j = 0; j < sizeof(b); j++) {
                   2010:                        if (j % 2 == 0)
                   2011:                                printf(" ");
                   2012:                        if (j % 8 == 0)
                   2013:                                printf(" ");
                   2014:                        if (j < l)
                   2015:                                printf("%02x", (int)b[j]);
                   2016:                        else
                   2017:                                printf("  ");
                   2018:                }
                   2019:                printf("  |");
                   2020:                for (j = 0; j < l; j++) {
                   2021:                        if (b[j] >= 0x20 && b[j] <= 0x7e)
                   2022:                                printf("%c", b[j]);
                   2023:                        else
                   2024:                                printf(".");
                   2025:                }
                   2026:                printf("|\n");
                   2027:        }
                   2028: }
                   2029: #endif
                   2030:
                   2031: static char *
                   2032: malo_cmd_string(uint16_t cmd)
                   2033: {
                   2034:        int i;
                   2035:        static char cmd_buf[16];
                   2036:        static const struct {
                   2037:                uint16_t         cmd_code;
                   2038:                char            *cmd_string;
                   2039:        } cmds[] = {
                   2040:                { MALO_CMD_GET_HW_SPEC,         "GetHwSpecifications"   },
                   2041:                { MALO_CMD_SET_RADIO,           "SetRadio"              },
                   2042:                { MALO_CMD_SET_TXPOWER,         "SetTxPower"            },
                   2043:                { MALO_CMD_SET_ANTENNA,         "SetAntenna"            },
                   2044:                { MALO_CMD_SET_PRESCAN,         "SetPrescan"            },
                   2045:                { MALO_CMD_SET_POSTSCAN,        "SetPostscan"           },
                   2046:                { MALO_CMD_SET_CHANNEL,         "SetChannel"            },
                   2047:                { MALO_CMD_SET_RTS,             "SetRTS"                },
                   2048:        };
                   2049:
                   2050:        for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
                   2051:                if ((letoh16(cmd) & 0x7fff) == cmds[i].cmd_code)
                   2052:                        return (cmds[i].cmd_string);
                   2053:
                   2054:        snprintf(cmd_buf, sizeof(cmd_buf), "unknown %#x", cmd);
                   2055:        return (cmd_buf);
                   2056: }
                   2057:
                   2058: static char *
                   2059: malo_cmd_string_result(uint16_t result)
                   2060: {
                   2061:        int i;
                   2062:        static const struct {
                   2063:                uint16_t         result_code;
                   2064:                char            *result_string;
                   2065:        } results[] = {
                   2066:                { MALO_CMD_RESULT_OK,           "OK"            },
                   2067:                { MALO_CMD_RESULT_ERROR,        "general error" },
                   2068:                { MALO_CMD_RESULT_NOSUPPORT,    "not supported" },
                   2069:                { MALO_CMD_RESULT_PENDING,      "pending"       },
                   2070:                { MALO_CMD_RESULT_BUSY,         "ignored"       },
                   2071:                { MALO_CMD_RESULT_PARTIALDATA,  "incomplete"    },
                   2072:        };
                   2073:
                   2074:        for (i = 0; i < sizeof(results) / sizeof(results[0]); i++)
                   2075:                if (letoh16(result) == results[i].result_code)
                   2076:                        return (results[i].result_string);
                   2077:
                   2078:        return ("unknown");
                   2079: }
                   2080:
                   2081: int
                   2082: malo_cmd_get_spec(struct malo_softc *sc)
                   2083: {
                   2084:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2085:        struct malo_hw_spec *spec;
                   2086:
                   2087:        hdr->cmd = htole16(MALO_CMD_GET_HW_SPEC);
                   2088:        hdr->size = htole16(sizeof(*hdr) + sizeof(*spec));
                   2089:        hdr->seqnum = htole16(42);      /* the one and only */
                   2090:        hdr->result = 0;
                   2091:        spec = (struct malo_hw_spec *)(hdr + 1);
                   2092:
                   2093:        bzero(spec, sizeof(*spec));
                   2094:        memset(spec->PermanentAddress, 0xff, ETHER_ADDR_LEN);
                   2095:        spec->CookiePtr = htole32(sc->sc_cookie_dmaaddr);
                   2096:
                   2097:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2098:            BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
                   2099:
                   2100:        if (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr) != 0)
                   2101:                return (ETIMEDOUT);
                   2102:
                   2103:        /* XXX get the data from the buffer and feed it to ieee80211 */
                   2104:        DPRINTF(("%s: get_hw_spec: V%x R%x, #WCB %d, #Mcast %d, Regcode %d, "
                   2105:            "#Ant %d\n", sc->sc_dev.dv_xname, htole16(spec->HwVersion),
                   2106:            htole32(spec->FWReleaseNumber), htole16(spec->NumOfWCB),
                   2107:            htole16(spec->NumOfMCastAdr), htole16(spec->RegionCode),
                   2108:            htole16(spec->NumberOfAntenna)));
                   2109:
                   2110:        /* tell the DMA engine where our rings are */
                   2111:        malo_mem_write4(sc, letoh32(spec->RxPdRdPtr) & 0xffff,
                   2112:            sc->sc_rxring.physaddr);
                   2113:        malo_mem_write4(sc, letoh32(spec->RxPdWrPtr) & 0xffff,
                   2114:            sc->sc_rxring.physaddr);
                   2115:        malo_mem_write4(sc, letoh32(spec->WcbBase0) & 0xffff,
                   2116:            sc->sc_txring.physaddr);
                   2117:
                   2118:        /* save DMA RX pointers for later use */
                   2119:        sc->sc_RxPdRdPtr = letoh32(spec->RxPdRdPtr) & 0xffff;
                   2120:        sc->sc_RxPdWrPtr = letoh32(spec->RxPdWrPtr) & 0xffff;
                   2121:
                   2122:        return (0);
                   2123: }
                   2124:
                   2125: int
                   2126: malo_cmd_set_wepkey(struct malo_softc *sc, struct ieee80211_key *k,
                   2127:     uint16_t k_index)
                   2128: {
                   2129:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2130:        struct malo_cmd_wepkey *body;
                   2131:
                   2132:        hdr->cmd = htole16(MALO_CMD_SET_WEPKEY);
                   2133:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2134:        hdr->seqnum = 1;
                   2135:        hdr->result = 0;
                   2136:        body = (struct malo_cmd_wepkey *)(hdr + 1);
                   2137:
                   2138:        bzero(body, sizeof(*body));
                   2139:        body->action = htole16(1);
                   2140:        body->flags = 0;
                   2141:        body->index = k_index;
                   2142:        body->len = k->k_len;
                   2143:        memcpy(body->value, k->k_key, k->k_len);
                   2144:
                   2145:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2146:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2147:
                   2148:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2149: }
                   2150:
                   2151: int
                   2152: malo_cmd_set_prescan(struct malo_softc *sc)
                   2153: {
                   2154:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2155:
                   2156:        hdr->cmd = htole16(MALO_CMD_SET_PRESCAN);
                   2157:        hdr->size = htole16(sizeof(*hdr));
                   2158:        hdr->seqnum = 1;
                   2159:        hdr->result = 0;
                   2160:
                   2161:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2162:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2163:
                   2164:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2165: }
                   2166:
                   2167: int
                   2168: malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, uint8_t ibsson)
                   2169: {
                   2170:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2171:        struct malo_cmd_postscan *body;
                   2172:
                   2173:        hdr->cmd = htole16(MALO_CMD_SET_POSTSCAN);
                   2174:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2175:        hdr->seqnum = 1;
                   2176:        hdr->result = 0;
                   2177:        body = (struct malo_cmd_postscan *)(hdr + 1);
                   2178:
                   2179:        bzero(body, sizeof(*body));
                   2180:        memcpy(&body->bssid, macaddr, ETHER_ADDR_LEN);
                   2181:        body->isibss = htole32(ibsson);
                   2182:
                   2183:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2184:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2185:
                   2186:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2187: }
                   2188:
                   2189: int
                   2190: malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel)
                   2191: {
                   2192:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2193:        struct malo_cmd_channel *body;
                   2194:
                   2195:        hdr->cmd = htole16(MALO_CMD_SET_CHANNEL);
                   2196:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2197:        hdr->seqnum = 1;
                   2198:        hdr->result = 0;
                   2199:        body = (struct malo_cmd_channel *)(hdr + 1);
                   2200:
                   2201:        bzero(body, sizeof(*body));
                   2202:        body->action = htole16(1);
                   2203:        body->channel = channel;
                   2204:
                   2205:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2206:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2207:
                   2208:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2209: }
                   2210:
                   2211: int
                   2212: malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna)
                   2213: {
                   2214:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2215:        struct malo_cmd_antenna *body;
                   2216:
                   2217:        hdr->cmd = htole16(MALO_CMD_SET_ANTENNA);
                   2218:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2219:        hdr->seqnum = 1;
                   2220:        hdr->result = 0;
                   2221:        body = (struct malo_cmd_antenna *)(hdr + 1);
                   2222:
                   2223:        bzero(body, sizeof(*body));
                   2224:        body->action = htole16(antenna);
                   2225:        if (antenna == 1)
                   2226:                body->mode = htole16(0xffff);
                   2227:        else
                   2228:                body->mode = htole16(2);
                   2229:
                   2230:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2231:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2232:
                   2233:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2234: }
                   2235:
                   2236: int
                   2237: malo_cmd_set_radio(struct malo_softc *sc, uint16_t enable,
                   2238:     uint16_t preamble_mode)
                   2239: {
                   2240:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2241:        struct malo_cmd_radio *body;
                   2242:
                   2243:        hdr->cmd = htole16(MALO_CMD_SET_RADIO);
                   2244:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2245:        hdr->seqnum = 1;
                   2246:        hdr->result = 0;
                   2247:        body = (struct malo_cmd_radio *)(hdr + 1);
                   2248:
                   2249:        bzero(body, sizeof(*body));
                   2250:        body->action = htole16(1);
                   2251:        body->preamble_mode = htole16(preamble_mode);
                   2252:        body->enable = htole16(enable);
                   2253:
                   2254:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2255:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2256:
                   2257:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2258: }
                   2259:
                   2260: int
                   2261: malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, uint16_t associd)
                   2262: {
                   2263:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2264:        struct malo_cmd_aid *body;
                   2265:
                   2266:        hdr->cmd = htole16(MALO_CMD_SET_AID);
                   2267:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2268:        hdr->seqnum = 1;
                   2269:        hdr->result = 0;
                   2270:        body = (struct malo_cmd_aid *)(hdr + 1);
                   2271:
                   2272:        bzero(body, sizeof(*body));
                   2273:        body->associd = htole16(associd);
                   2274:        memcpy(&body->macaddr[0], bssid, IEEE80211_ADDR_LEN);
                   2275:
                   2276:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2277:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2278:
                   2279:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2280: }
                   2281:
                   2282: int
                   2283: malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel)
                   2284: {
                   2285:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2286:        struct malo_cmd_txpower *body;
                   2287:
                   2288:        hdr->cmd = htole16(MALO_CMD_SET_TXPOWER);
                   2289:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2290:        hdr->seqnum = 1;
                   2291:        hdr->result = 0;
                   2292:        body = (struct malo_cmd_txpower *)(hdr + 1);
                   2293:
                   2294:        bzero(body, sizeof(*body));
                   2295:        body->action = htole16(1);
                   2296:        if (powerlevel >= 0 && powerlevel < 30)
                   2297:                body->supportpowerlvl = htole16(5);     /* LOW */
                   2298:        else if (powerlevel >= 30 && powerlevel < 60)
                   2299:                body->supportpowerlvl = htole16(10);    /* MEDIUM */
                   2300:        else
                   2301:                body->supportpowerlvl = htole16(15);    /* HIGH */
                   2302:
                   2303:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2304:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2305:
                   2306:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2307: }
                   2308:
                   2309: int
                   2310: malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold)
                   2311: {
                   2312:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2313:
                   2314:        hdr->cmd = htole16(MALO_CMD_SET_RTS);
                   2315:        hdr->size = htole16(sizeof(*hdr) + sizeof(threshold));
                   2316:        hdr->seqnum = 1;
                   2317:        hdr->result = 0;
                   2318:
                   2319:        *(uint32_t *)(hdr + 1) = htole32(threshold);
                   2320:
                   2321:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2322:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2323:
                   2324:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2325: }
                   2326:
                   2327: int
                   2328: malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot)
                   2329: {
                   2330:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2331:        struct malo_cmd_slot *body;
                   2332:
                   2333:        hdr->cmd = htole16(MALO_CMD_SET_SLOT);
                   2334:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2335:        hdr->seqnum = 1;
                   2336:        hdr->result = 0;
                   2337:        body = (struct malo_cmd_slot *)(hdr + 1);
                   2338:
                   2339:        bzero(body, sizeof(*body));
                   2340:        body->action = htole16(1);
                   2341:        body->slot = slot;
                   2342:
                   2343:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2344:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2345:
                   2346:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2347: }
                   2348:
                   2349: int
                   2350: malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate)
                   2351: {
                   2352:        struct ieee80211com *ic = &sc->sc_ic;
                   2353:        struct malo_cmdheader *hdr = sc->sc_cmd_mem;
                   2354:        struct malo_cmd_rate *body;
                   2355:        int i;
                   2356:
                   2357:        hdr->cmd = htole16(MALO_CMD_SET_RATE);
                   2358:        hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
                   2359:        hdr->seqnum = 1;
                   2360:        hdr->result = 0;
                   2361:        body = (struct malo_cmd_rate *)(hdr + 1);
                   2362:
                   2363:        bzero(body, sizeof(*body));
                   2364:
                   2365:        if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
                   2366:                /* TODO */
                   2367:        } else {
                   2368:                body->aprates[0] = 2;
                   2369:                body->aprates[1] = 4;
                   2370:                body->aprates[2] = 11;
                   2371:                body->aprates[3] = 22;
                   2372:                if (ic->ic_curmode == IEEE80211_MODE_11G) {
                   2373:                        body->aprates[4] = 0;
                   2374:                        body->aprates[5] = 12;
                   2375:                        body->aprates[6] = 18;
                   2376:                        body->aprates[7] = 24;
                   2377:                        body->aprates[8] = 36;
                   2378:                        body->aprates[9] = 48;
                   2379:                        body->aprates[10] = 72;
                   2380:                        body->aprates[11] = 96;
                   2381:                        body->aprates[12] = 108;
                   2382:                }
                   2383:        }
                   2384:
                   2385:        if (rate != 0) {
                   2386:                /* fixed rate */
                   2387:                for (i = 0; i < 13; i++) {
                   2388:                        if (body->aprates[i] == rate) {
                   2389:                                body->rateindex = i;
                   2390:                                body->dataratetype = 1;
                   2391:                                break;
                   2392:                        }
                   2393:                }
                   2394:        }
                   2395:
                   2396:        bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
                   2397:            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                   2398:
                   2399:        return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
                   2400: }

CVSweb