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

Annotation of sys/dev/usb/if_uath.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_uath.c,v 1.27 2007/07/18 18:10:31 damien Exp $     */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2006
                      5:  *     Damien Bergamini <damien.bergamini@free.fr>
                      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: /*-
                     21:  * Driver for Atheros AR5005UG/AR5005UX chipsets.
                     22:  * http://www.atheros.com/pt/bulletins/AR5005UGBulletin.pdf
                     23:  * http://www.atheros.com/pt/bulletins/AR5005UXBulletin.pdf
                     24:  *
                     25:  * IMPORTANT NOTICE:
                     26:  * This driver was written without any documentation or support from Atheros
                     27:  * Communications. It is based on a black-box analysis of the Windows binary
                     28:  * driver. It handles both pre and post-firmware devices.
                     29:  */
                     30:
                     31: #include "bpfilter.h"
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/sockio.h>
                     35: #include <sys/sysctl.h>
                     36: #include <sys/mbuf.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/socket.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/malloc.h>
                     41: #include <sys/timeout.h>
                     42: #include <sys/conf.h>
                     43: #include <sys/device.h>
                     44:
                     45: #include <machine/bus.h>
                     46: #include <machine/endian.h>
                     47: #include <machine/intr.h>
                     48:
                     49: #if NBPFILTER > 0
                     50: #include <net/bpf.h>
                     51: #endif
                     52: #include <net/if.h>
                     53: #include <net/if_arp.h>
                     54: #include <net/if_dl.h>
                     55: #include <net/if_media.h>
                     56: #include <net/if_types.h>
                     57:
                     58: #include <netinet/in.h>
                     59: #include <netinet/in_systm.h>
                     60: #include <netinet/in_var.h>
                     61: #include <netinet/if_ether.h>
                     62: #include <netinet/ip.h>
                     63:
                     64: #include <net80211/ieee80211_var.h>
                     65: #include <net80211/ieee80211_radiotap.h>
                     66:
                     67: #include <dev/rndvar.h>
                     68: #include <crypto/arc4.h>
                     69:
                     70: #include <dev/usb/usb.h>
                     71: #include <dev/usb/usbdi.h>
                     72: #include <dev/usb/usbdivar.h>  /* needs_reattach() */
                     73: #include <dev/usb/usbdi_util.h>
                     74: #include <dev/usb/usbdevs.h>
                     75:
                     76: #include <dev/usb/if_uathreg.h>
                     77: #include <dev/usb/if_uathvar.h>
                     78:
                     79: #ifdef USB_DEBUG
                     80: #define UATH_DEBUG
                     81: #endif
                     82:
                     83: #ifdef UATH_DEBUG
                     84: #define DPRINTF(x)     do { if (uath_debug) printf x; } while (0)
                     85: #define DPRINTFN(n, x) do { if (uath_debug >= (n)) printf x; } while (0)
                     86: int uath_debug = 1;
                     87: #else
                     88: #define DPRINTF(x)
                     89: #define DPRINTFN(n, x)
                     90: #endif
                     91:
                     92: /*-
                     93:  * Various supported device vendors/products.
                     94:  * UB51: AR5005UG 802.11b/g, UB52: AR5005UX 802.11a/b/g
                     95:  */
                     96: #define UATH_DEV(v, p, f)                                              \
                     97:        { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, (f) },             \
                     98:        { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p##_NF },               \
                     99:            (f) | UATH_FLAG_PRE_FIRMWARE }
                    100: #define UATH_DEV_UG(v, p)      UATH_DEV(v, p, 0)
                    101: #define UATH_DEV_UX(v, p)      UATH_DEV(v, p, UATH_FLAG_ABG)
                    102: static const struct uath_type {
                    103:        struct usb_devno        dev;
                    104:        unsigned int            flags;
                    105: #define UATH_FLAG_PRE_FIRMWARE (1 << 0)
                    106: #define UATH_FLAG_ABG          (1 << 1)
                    107: } uath_devs[] = {
                    108:        UATH_DEV_UG(ATHEROS,            AR5523),
                    109:        UATH_DEV_UG(ATHEROS2,           AR5523_1),
                    110:        UATH_DEV_UG(ATHEROS2,           AR5523_2),
                    111:        UATH_DEV_UX(ATHEROS2,           AR5523_3),
                    112:        UATH_DEV_UG(CONCEPTRONIC,       AR5523_1),
                    113:        UATH_DEV_UX(CONCEPTRONIC,       AR5523_2),
                    114:        UATH_DEV_UX(DLINK,              DWLAG122),
                    115:        UATH_DEV_UX(DLINK,              DWLAG132),
                    116:        UATH_DEV_UG(DLINK,              DWLG132),
                    117:        UATH_DEV_UG(GIGASET,            AR5523),
                    118:        UATH_DEV_UG(GIGASET,            SMCWUSBTG),
                    119:        UATH_DEV_UG(GLOBALSUN,          AR5523_1),
                    120:        UATH_DEV_UX(GLOBALSUN,          AR5523_2),
                    121:        UATH_DEV_UX(NETGEAR,            WG111U),
                    122:        UATH_DEV_UG(NETGEAR3,           WG111T),
                    123:        UATH_DEV_UG(NETGEAR3,           WPN111),
                    124:        UATH_DEV_UG(UMEDIA,             AR5523_1),
                    125:        UATH_DEV_UX(UMEDIA,             AR5523_2),
                    126:        UATH_DEV_UG(UMEDIA,             TEW444UBEU),
                    127:        UATH_DEV_UG(WISTRONNEWEB,       AR5523_1),
                    128:        UATH_DEV_UX(WISTRONNEWEB,       AR5523_2),
                    129:        UATH_DEV_UG(ZCOM,               AR5523)
                    130: };
                    131: #define uath_lookup(v, p)      \
                    132:        ((const struct uath_type *)usb_lookup(uath_devs, v, p))
                    133:
                    134: void   uath_attachhook(void *);
                    135: int    uath_open_pipes(struct uath_softc *);
                    136: void   uath_close_pipes(struct uath_softc *);
                    137: int    uath_alloc_tx_data_list(struct uath_softc *);
                    138: void   uath_free_tx_data_list(struct uath_softc *);
                    139: int    uath_alloc_rx_data_list(struct uath_softc *);
                    140: void   uath_free_rx_data_list(struct uath_softc *);
                    141: void   uath_free_rx_data(caddr_t, u_int, void *);
                    142: int    uath_alloc_tx_cmd_list(struct uath_softc *);
                    143: void   uath_free_tx_cmd_list(struct uath_softc *);
                    144: int    uath_alloc_rx_cmd_list(struct uath_softc *);
                    145: void   uath_free_rx_cmd_list(struct uath_softc *);
                    146: int    uath_media_change(struct ifnet *);
                    147: void   uath_stat(void *);
                    148: void   uath_next_scan(void *);
                    149: void   uath_task(void *);
                    150: int    uath_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    151: #ifdef UATH_DEBUG
                    152: void   uath_dump_cmd(const uint8_t *, int, char);
                    153: #endif
                    154: int    uath_cmd(struct uath_softc *, uint32_t, const void *, int, void *,
                    155:            int);
                    156: int    uath_cmd_write(struct uath_softc *, uint32_t, const void *, int, int);
                    157: int    uath_cmd_read(struct uath_softc *, uint32_t, const void *, int, void *,
                    158:            int);
                    159: int    uath_write_reg(struct uath_softc *, uint32_t, uint32_t);
                    160: int    uath_write_multi(struct uath_softc *, uint32_t, const void *, int);
                    161: int    uath_read_reg(struct uath_softc *, uint32_t, uint32_t *);
                    162: int    uath_read_eeprom(struct uath_softc *, uint32_t, void *);
                    163: void   uath_cmd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    164: void   uath_data_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    165: void   uath_data_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    166: int    uath_tx_null(struct uath_softc *);
                    167: int    uath_tx_data(struct uath_softc *, struct mbuf *,
                    168:            struct ieee80211_node *);
                    169: void   uath_start(struct ifnet *);
                    170: void   uath_watchdog(struct ifnet *);
                    171: int    uath_ioctl(struct ifnet *, u_long, caddr_t);
                    172: int    uath_query_eeprom(struct uath_softc *);
                    173: int    uath_reset(struct uath_softc *);
                    174: int    uath_reset_tx_queues(struct uath_softc *);
                    175: int    uath_wme_init(struct uath_softc *);
                    176: int    uath_set_chan(struct uath_softc *, struct ieee80211_channel *);
                    177: int    uath_set_key(struct uath_softc *, const struct ieee80211_key *, int);
                    178: int    uath_set_keys(struct uath_softc *);
                    179: int    uath_set_rates(struct uath_softc *, const struct ieee80211_rateset *);
                    180: int    uath_set_rxfilter(struct uath_softc *, uint32_t, uint32_t);
                    181: int    uath_set_led(struct uath_softc *, int, int);
                    182: int    uath_switch_channel(struct uath_softc *, struct ieee80211_channel *);
                    183: int    uath_init(struct ifnet *);
                    184: void   uath_stop(struct ifnet *, int);
                    185: int    uath_loadfirmware(struct uath_softc *, const u_char *, int);
                    186: int    uath_activate(struct device *, enum devact);
                    187:
                    188: int uath_match(struct device *, void *, void *);
                    189: void uath_attach(struct device *, struct device *, void *);
                    190: int uath_detach(struct device *, int);
                    191: int uath_activate(struct device *, enum devact);
                    192:
                    193: struct cfdriver uath_cd = {
                    194:        NULL, "uath", DV_DULL
                    195: };
                    196:
                    197: const struct cfattach uath_ca = {
                    198:        sizeof(struct uath_softc),
                    199:        uath_match,
                    200:        uath_attach,
                    201:        uath_detach,
                    202:        uath_activate,
                    203: };
                    204:
                    205: int
                    206: uath_match(struct device *parent, void *match, void *aux)
                    207: {
                    208:        struct usb_attach_arg *uaa = aux;
                    209:
                    210:        if (uaa->iface != NULL)
                    211:                return UMATCH_NONE;
                    212:
                    213:        return (uath_lookup(uaa->vendor, uaa->product) != NULL) ?
                    214:            UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
                    215: }
                    216:
                    217: void
                    218: uath_attachhook(void *xsc)
                    219: {
                    220:        struct uath_softc *sc = xsc;
                    221:        u_char *fw;
                    222:        size_t size;
                    223:        int error;
                    224:
                    225:        if ((error = loadfirmware("uath-ar5523", &fw, &size)) != 0) {
                    226:                printf("%s: could not read firmware (error=%d)\n",
                    227:                    sc->sc_dev.dv_xname, error);
                    228:                return;
                    229:        }
                    230:
                    231:        error = uath_loadfirmware(sc, fw, size);
                    232:        free(fw, M_DEVBUF);
                    233:
                    234:        if (error == 0) {
                    235:                usb_port_status_t status;
                    236:
                    237:                /*
                    238:                 * Hack alert: the device doesn't always gracefully detach
                    239:                 * from the bus after a firmware upload.  We need to force
                    240:                 * a port reset and a re-exploration on the parent hub.
                    241:                 */
                    242:                usbd_reset_port(sc->sc_uhub, sc->sc_port, &status);
                    243:                usb_needs_reattach(sc->sc_udev);
                    244:        } else {
                    245:                printf("%s: could not load firmware (error=%s)\n",
                    246:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    247:        }
                    248: }
                    249:
                    250: void
                    251: uath_attach(struct device *parent, struct device *self, void *aux)
                    252: {
                    253:        struct uath_softc *sc = (struct uath_softc *)self;
                    254:        struct usb_attach_arg *uaa = aux;
                    255:        struct ieee80211com *ic = &sc->sc_ic;
                    256:        struct ifnet *ifp = &ic->ic_if;
                    257:        usbd_status error;
                    258:        char *devinfop;
                    259:        int i;
                    260:
                    261:        sc->sc_udev = uaa->device;
                    262:        sc->sc_uhub = uaa->device->myhub;
                    263:        sc->sc_port = uaa->port;
                    264:
                    265:        devinfop = usbd_devinfo_alloc(uaa->device, 0);
                    266:        printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
                    267:        usbd_devinfo_free(devinfop);
                    268:
                    269:        sc->sc_flags = uath_lookup(uaa->vendor, uaa->product)->flags;
                    270:
                    271:        if (usbd_set_config_no(sc->sc_udev, UATH_CONFIG_NO, 0) != 0) {
                    272:                printf("%s: could not set configuration no\n",
                    273:                    sc->sc_dev.dv_xname);
                    274:                return;
                    275:        }
                    276:
                    277:        /* get the first interface handle */
                    278:        error = usbd_device2interface_handle(sc->sc_udev, UATH_IFACE_INDEX,
                    279:            &sc->sc_iface);
                    280:        if (error != 0) {
                    281:                printf("%s: could not get interface handle\n",
                    282:                    sc->sc_dev.dv_xname);
                    283:                return;
                    284:        }
                    285:
                    286:        /*
                    287:         * We must open the pipes early because they're used to upload the
                    288:         * firmware (pre-firmware devices) or to send firmware commands.
                    289:         */
                    290:        if (uath_open_pipes(sc) != 0) {
                    291:                printf("%s: could not open pipes\n", sc->sc_dev.dv_xname);
                    292:                return;
                    293:        }
                    294:
                    295:        if (sc->sc_flags & UATH_FLAG_PRE_FIRMWARE) {
                    296:                if (rootvp == NULL)
                    297:                        mountroothook_establish(uath_attachhook, sc);
                    298:                else
                    299:                        uath_attachhook(sc);
                    300:                return;
                    301:        }
                    302:
                    303:        /*
                    304:         * Only post-firmware devices here.
                    305:         */
                    306:        usb_init_task(&sc->sc_task, uath_task, sc);
                    307:        timeout_set(&sc->scan_to, uath_next_scan, sc);
                    308:        timeout_set(&sc->stat_to, uath_stat, sc);
                    309:
                    310:        /*
                    311:         * Allocate xfers for firmware commands.
                    312:         */
                    313:        if (uath_alloc_tx_cmd_list(sc) != 0) {
                    314:                printf("%s: could not allocate Tx command list\n",
                    315:                    sc->sc_dev.dv_xname);
                    316:                goto fail1;
                    317:        }
                    318:        if (uath_alloc_rx_cmd_list(sc) != 0) {
                    319:                printf("%s: could not allocate Rx command list\n",
                    320:                    sc->sc_dev.dv_xname);
                    321:                goto fail2;
                    322:        }
                    323:
                    324:        /*
                    325:         * Queue Rx command xfers.
                    326:         */
                    327:        for (i = 0; i < UATH_RX_CMD_LIST_COUNT; i++) {
                    328:                struct uath_rx_cmd *cmd = &sc->rx_cmd[i];
                    329:
                    330:                usbd_setup_xfer(cmd->xfer, sc->cmd_rx_pipe, cmd, cmd->buf,
                    331:                    UATH_MAX_RXCMDSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
                    332:                    USBD_NO_TIMEOUT, uath_cmd_rxeof);
                    333:                error = usbd_transfer(cmd->xfer);
                    334:                if (error != USBD_IN_PROGRESS && error != 0) {
                    335:                        printf("%s: could not queue Rx command xfer\n",
                    336:                            sc->sc_dev.dv_xname);
                    337:                        goto fail3;
                    338:                }
                    339:        }
                    340:
                    341:        /*
                    342:         * We're now ready to send/receive firmware commands.
                    343:         */
                    344:        if (uath_reset(sc) != 0) {
                    345:                printf("%s: could not initialize adapter\n",
                    346:                    sc->sc_dev.dv_xname);
                    347:                goto fail3;
                    348:        }
                    349:        if (uath_query_eeprom(sc) != 0) {
                    350:                printf("%s: could not read EEPROM\n", sc->sc_dev.dv_xname);
                    351:                goto fail3;
                    352:        }
                    353:
                    354:        printf("%s: MAC/BBP AR5523, RF AR%c112, address %s\n",
                    355:            sc->sc_dev.dv_xname, (sc->sc_flags & UATH_FLAG_ABG) ? '5': '2',
                    356:            ether_sprintf(ic->ic_myaddr));
                    357:
                    358:        /*
                    359:         * Allocate xfers for Tx/Rx data pipes.
                    360:         */
                    361:        if (uath_alloc_tx_data_list(sc) != 0) {
                    362:                printf("%s: could not allocate Tx data list\n",
                    363:                    sc->sc_dev.dv_xname);
                    364:                goto fail3;
                    365:        }
                    366:        if (uath_alloc_rx_data_list(sc) != 0) {
                    367:                printf("%s: could not allocate Rx data list\n",
                    368:                    sc->sc_dev.dv_xname);
                    369:                goto fail4;
                    370:        }
                    371:
                    372:        ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
                    373:        ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
                    374:        ic->ic_state = IEEE80211_S_INIT;
                    375:
                    376:        /* set device capabilities */
                    377:        ic->ic_caps =
                    378:            IEEE80211_C_TXPMGT |        /* tx power management */
                    379:            IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
                    380:            IEEE80211_C_SHSLOT |        /* short slot time supported */
                    381:            IEEE80211_C_WEP;            /* h/w WEP */
                    382:
                    383:        /* set supported .11b and .11g rates */
                    384:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    385:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
                    386:
                    387:        /* set supported .11b and .11g channels (1 through 14) */
                    388:        for (i = 1; i <= 14; i++) {
                    389:                ic->ic_channels[i].ic_freq =
                    390:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
                    391:                ic->ic_channels[i].ic_flags =
                    392:                    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
                    393:                    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
                    394:        }
                    395:
                    396:        ifp->if_softc = sc;
                    397:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    398:        ifp->if_init = uath_init;
                    399:        ifp->if_ioctl = uath_ioctl;
                    400:        ifp->if_start = uath_start;
                    401:        ifp->if_watchdog = uath_watchdog;
                    402:        IFQ_SET_READY(&ifp->if_snd);
                    403:        memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
                    404:
                    405:        if_attach(ifp);
                    406:        ieee80211_ifattach(ifp);
                    407:
                    408:        /* override state transition machine */
                    409:        sc->sc_newstate = ic->ic_newstate;
                    410:        ic->ic_newstate = uath_newstate;
                    411:        ieee80211_media_init(ifp, uath_media_change, ieee80211_media_status);
                    412:
                    413: #if NBPFILTER > 0
                    414:        bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
                    415:            sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
                    416:
                    417:        sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
                    418:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    419:        sc->sc_rxtap.wr_ihdr.it_present = htole32(UATH_RX_RADIOTAP_PRESENT);
                    420:
                    421:        sc->sc_txtap_len = sizeof sc->sc_txtapu;
                    422:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    423:        sc->sc_txtap.wt_ihdr.it_present = htole32(UATH_TX_RADIOTAP_PRESENT);
                    424: #endif
                    425:
                    426:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    427:            &sc->sc_dev);
                    428:
                    429:        return;
                    430:
                    431: fail4: uath_free_tx_data_list(sc);
                    432: fail3: uath_free_rx_cmd_list(sc);
                    433: fail2: uath_free_tx_cmd_list(sc);
                    434: fail1: uath_close_pipes(sc);
                    435: }
                    436:
                    437: int
                    438: uath_detach(struct device *self, int flags)
                    439: {
                    440:        struct uath_softc *sc = (struct uath_softc *)self;
                    441:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                    442:        int s;
                    443:
                    444:        s = splnet();
                    445:
                    446:        if (sc->sc_flags & UATH_FLAG_PRE_FIRMWARE) {
                    447:                uath_close_pipes(sc);
                    448:                splx(s);
                    449:                return 0;
                    450:        }
                    451:
                    452:        /* post-firmware device */
                    453:
                    454:        usb_rem_task(sc->sc_udev, &sc->sc_task);
                    455:        timeout_del(&sc->scan_to);
                    456:        timeout_del(&sc->stat_to);
                    457:
                    458:        ieee80211_ifdetach(ifp);        /* free all nodes */
                    459:        if_detach(ifp);
                    460:
                    461:        sc->sc_dying = 1;
                    462:        DPRINTF(("reclaiming %d references\n", sc->sc_refcnt));
                    463:        while (sc->sc_refcnt > 0)
                    464:                (void)tsleep(UATH_COND_NOREF(sc), 0, "uathdet", 0);
                    465:        DPRINTF(("all references reclaimed\n"));
                    466:
                    467:        /* abort and free xfers */
                    468:        uath_free_tx_data_list(sc);
                    469:        uath_free_rx_data_list(sc);
                    470:        uath_free_tx_cmd_list(sc);
                    471:        uath_free_rx_cmd_list(sc);
                    472:
                    473:        /* close Tx/Rx pipes */
                    474:        uath_close_pipes(sc);
                    475:
                    476:        splx(s);
                    477:
                    478:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    479:            &sc->sc_dev);
                    480:
                    481:        return 0;
                    482: }
                    483:
                    484: int
                    485: uath_open_pipes(struct uath_softc *sc)
                    486: {
                    487:        int error;
                    488:
                    489:        /*
                    490:         * XXX pipes numbers are hardcoded because we don't have any way
                    491:         * to distinguish the data pipes from the firmware command pipes
                    492:         * (both are bulk pipes) using the endpoints descriptors.
                    493:         */
                    494:        error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
                    495:            &sc->cmd_tx_pipe);
                    496:        if (error != 0) {
                    497:                printf("%s: could not open Tx command pipe: %s\n",
                    498:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    499:                goto fail;
                    500:        }
                    501:
                    502:        error = usbd_open_pipe(sc->sc_iface, 0x02, USBD_EXCLUSIVE_USE,
                    503:            &sc->data_tx_pipe);
                    504:        if (error != 0) {
                    505:                printf("%s: could not open Tx data pipe: %s\n",
                    506:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    507:                goto fail;
                    508:        }
                    509:
                    510:        error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
                    511:            &sc->cmd_rx_pipe);
                    512:        if (error != 0) {
                    513:                printf("%s: could not open Rx command pipe: %s\n",
                    514:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    515:                goto fail;
                    516:        }
                    517:
                    518:        error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE,
                    519:            &sc->data_rx_pipe);
                    520:        if (error != 0) {
                    521:                printf("%s: could not open Rx data pipe: %s\n",
                    522:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    523:                goto fail;
                    524:        }
                    525:
                    526:        return 0;
                    527:
                    528: fail:  uath_close_pipes(sc);
                    529:        return error;
                    530: }
                    531:
                    532: void
                    533: uath_close_pipes(struct uath_softc *sc)
                    534: {
                    535:        /* assumes no transfers are pending on the pipes */
                    536:
                    537:        if (sc->data_tx_pipe != NULL)
                    538:                usbd_close_pipe(sc->data_tx_pipe);
                    539:
                    540:        if (sc->data_rx_pipe != NULL)
                    541:                usbd_close_pipe(sc->data_rx_pipe);
                    542:
                    543:        if (sc->cmd_tx_pipe != NULL)
                    544:                usbd_close_pipe(sc->cmd_tx_pipe);
                    545:
                    546:        if (sc->cmd_rx_pipe != NULL)
                    547:                usbd_close_pipe(sc->cmd_rx_pipe);
                    548: }
                    549:
                    550: int
                    551: uath_alloc_tx_data_list(struct uath_softc *sc)
                    552: {
                    553:        int i, error;
                    554:
                    555:        for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++) {
                    556:                struct uath_tx_data *data = &sc->tx_data[i];
                    557:
                    558:                data->sc = sc;  /* backpointer for callbacks */
                    559:
                    560:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    561:                if (data->xfer == NULL) {
                    562:                        printf("%s: could not allocate xfer\n",
                    563:                            sc->sc_dev.dv_xname);
                    564:                        error = ENOMEM;
                    565:                        goto fail;
                    566:                }
                    567:                data->buf = usbd_alloc_buffer(data->xfer, UATH_MAX_TXBUFSZ);
                    568:                if (data->buf == NULL) {
                    569:                        printf("%s: could not allocate xfer buffer\n",
                    570:                            sc->sc_dev.dv_xname);
                    571:                        error = ENOMEM;
                    572:                        goto fail;
                    573:                }
                    574:        }
                    575:        return 0;
                    576:
                    577: fail:  uath_free_tx_data_list(sc);
                    578:        return error;
                    579: }
                    580:
                    581: void
                    582: uath_free_tx_data_list(struct uath_softc *sc)
                    583: {
                    584:        int i;
                    585:
                    586:        /* make sure no transfers are pending */
                    587:        usbd_abort_pipe(sc->data_tx_pipe);
                    588:
                    589:        for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++)
                    590:                if (sc->tx_data[i].xfer != NULL)
                    591:                        usbd_free_xfer(sc->tx_data[i].xfer);
                    592: }
                    593:
                    594: int
                    595: uath_alloc_rx_data_list(struct uath_softc *sc)
                    596: {
                    597:        int i, error;
                    598:
                    599:        SLIST_INIT(&sc->rx_freelist);
                    600:        for (i = 0; i < UATH_RX_DATA_POOL_COUNT; i++) {
                    601:                struct uath_rx_data *data = &sc->rx_data[i];
                    602:
                    603:                data->sc = sc;  /* backpointer for callbacks */
                    604:
                    605:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    606:                if (data->xfer == NULL) {
                    607:                        printf("%s: could not allocate xfer\n",
                    608:                            sc->sc_dev.dv_xname);
                    609:                        error = ENOMEM;
                    610:                        goto fail;
                    611:                }
                    612:                data->buf = usbd_alloc_buffer(data->xfer, sc->rxbufsz);
                    613:                if (data->buf == NULL) {
                    614:                        printf("%s: could not allocate xfer buffer\n",
                    615:                            sc->sc_dev.dv_xname);
                    616:                        error = ENOMEM;
                    617:                        goto fail;
                    618:                }
                    619:                SLIST_INSERT_HEAD(&sc->rx_freelist, data, next);
                    620:        }
                    621:        return 0;
                    622:
                    623: fail:  uath_free_rx_data_list(sc);
                    624:        return error;
                    625: }
                    626:
                    627: void
                    628: uath_free_rx_data_list(struct uath_softc *sc)
                    629: {
                    630:        int i;
                    631:
                    632:        /* make sure no transfers are pending */
                    633:        usbd_abort_pipe(sc->data_rx_pipe);
                    634:
                    635:        for (i = 0; i < UATH_RX_DATA_POOL_COUNT; i++)
                    636:                if (sc->rx_data[i].xfer != NULL)
                    637:                        usbd_free_xfer(sc->rx_data[i].xfer);
                    638: }
                    639:
                    640: void
                    641: uath_free_rx_data(caddr_t buf, u_int size, void *arg)
                    642: {
                    643:        struct uath_rx_data *data = arg;
                    644:        struct uath_softc *sc = data->sc;
                    645:
                    646:        /* put the buffer back in the free list */
                    647:        SLIST_INSERT_HEAD(&sc->rx_freelist, data, next);
                    648:
                    649:        /* release reference to softc */
                    650:        if (--sc->sc_refcnt == 0 && sc->sc_dying)
                    651:                wakeup(UATH_COND_NOREF(sc));
                    652: }
                    653:
                    654: int
                    655: uath_alloc_tx_cmd_list(struct uath_softc *sc)
                    656: {
                    657:        int i, error;
                    658:
                    659:        for (i = 0; i < UATH_TX_CMD_LIST_COUNT; i++) {
                    660:                struct uath_tx_cmd *cmd = &sc->tx_cmd[i];
                    661:
                    662:                cmd->sc = sc;   /* backpointer for callbacks */
                    663:
                    664:                cmd->xfer = usbd_alloc_xfer(sc->sc_udev);
                    665:                if (cmd->xfer == NULL) {
                    666:                        printf("%s: could not allocate xfer\n",
                    667:                            sc->sc_dev.dv_xname);
                    668:                        error = ENOMEM;
                    669:                        goto fail;
                    670:                }
                    671:                cmd->buf = usbd_alloc_buffer(cmd->xfer, UATH_MAX_TXCMDSZ);
                    672:                if (cmd->buf == NULL) {
                    673:                        printf("%s: could not allocate xfer buffer\n",
                    674:                            sc->sc_dev.dv_xname);
                    675:                        error = ENOMEM;
                    676:                        goto fail;
                    677:                }
                    678:        }
                    679:        return 0;
                    680:
                    681: fail:  uath_free_tx_cmd_list(sc);
                    682:        return error;
                    683: }
                    684:
                    685: void
                    686: uath_free_tx_cmd_list(struct uath_softc *sc)
                    687: {
                    688:        int i;
                    689:
                    690:        /* make sure no transfers are pending */
                    691:        usbd_abort_pipe(sc->cmd_tx_pipe);
                    692:
                    693:        for (i = 0; i < UATH_TX_CMD_LIST_COUNT; i++)
                    694:                if (sc->tx_cmd[i].xfer != NULL)
                    695:                        usbd_free_xfer(sc->tx_cmd[i].xfer);
                    696: }
                    697:
                    698: int
                    699: uath_alloc_rx_cmd_list(struct uath_softc *sc)
                    700: {
                    701:        int i, error;
                    702:
                    703:        for (i = 0; i < UATH_RX_CMD_LIST_COUNT; i++) {
                    704:                struct uath_rx_cmd *cmd = &sc->rx_cmd[i];
                    705:
                    706:                cmd->sc = sc;   /* backpointer for callbacks */
                    707:
                    708:                cmd->xfer = usbd_alloc_xfer(sc->sc_udev);
                    709:                if (cmd->xfer == NULL) {
                    710:                        printf("%s: could not allocate xfer\n",
                    711:                            sc->sc_dev.dv_xname);
                    712:                        error = ENOMEM;
                    713:                        goto fail;
                    714:                }
                    715:                cmd->buf = usbd_alloc_buffer(cmd->xfer, UATH_MAX_RXCMDSZ);
                    716:                if (cmd->buf == NULL) {
                    717:                        printf("%s: could not allocate xfer buffer\n",
                    718:                            sc->sc_dev.dv_xname);
                    719:                        error = ENOMEM;
                    720:                        goto fail;
                    721:                }
                    722:        }
                    723:        return 0;
                    724:
                    725: fail:  uath_free_rx_cmd_list(sc);
                    726:        return error;
                    727: }
                    728:
                    729: void
                    730: uath_free_rx_cmd_list(struct uath_softc *sc)
                    731: {
                    732:        int i;
                    733:
                    734:        /* make sure no transfers are pending */
                    735:        usbd_abort_pipe(sc->cmd_rx_pipe);
                    736:
                    737:        for (i = 0; i < UATH_RX_CMD_LIST_COUNT; i++)
                    738:                if (sc->rx_cmd[i].xfer != NULL)
                    739:                        usbd_free_xfer(sc->rx_cmd[i].xfer);
                    740: }
                    741:
                    742: int
                    743: uath_media_change(struct ifnet *ifp)
                    744: {
                    745:        int error;
                    746:
                    747:        error = ieee80211_media_change(ifp);
                    748:        if (error != ENETRESET)
                    749:                return error;
                    750:
                    751:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
                    752:                uath_init(ifp);
                    753:
                    754:        return 0;
                    755: }
                    756:
                    757: /*
                    758:  * This function is called periodically (every second) when associated to
                    759:  * query device statistics.
                    760:  */
                    761: void
                    762: uath_stat(void *arg)
                    763: {
                    764:        struct uath_softc *sc = arg;
                    765:        int error;
                    766:
                    767:        /*
                    768:         * Send request for statistics asynchronously. The timer will be
                    769:         * restarted when we'll get the stats notification.
                    770:         */
                    771:        error = uath_cmd_write(sc, UATH_CMD_STATS, NULL, 0,
                    772:            UATH_CMD_FLAG_ASYNC);
                    773:        if (error != 0) {
                    774:                printf("%s: could not query statistics (error=%d)\n",
                    775:                    sc->sc_dev.dv_xname, error);
                    776:        }
                    777: }
                    778:
                    779: /*
                    780:  * This function is called periodically (every 250ms) during scanning to
                    781:  * switch from one channel to another.
                    782:  */
                    783: void
                    784: uath_next_scan(void *arg)
                    785: {
                    786:        struct uath_softc *sc = arg;
                    787:        struct ieee80211com *ic = &sc->sc_ic;
                    788:        struct ifnet *ifp = &ic->ic_if;
                    789:
                    790:        if (ic->ic_state == IEEE80211_S_SCAN)
                    791:                ieee80211_next_scan(ifp);
                    792: }
                    793:
                    794: void
                    795: uath_task(void *arg)
                    796: {
                    797:        struct uath_softc *sc = arg;
                    798:        struct ieee80211com *ic = &sc->sc_ic;
                    799:        enum ieee80211_state ostate;
                    800:
                    801:        ostate = ic->ic_state;
                    802:
                    803:        switch (sc->sc_state) {
                    804:        case IEEE80211_S_INIT:
                    805:                if (ostate == IEEE80211_S_RUN) {
                    806:                        /* turn link and activity LEDs off */
                    807:                        (void)uath_set_led(sc, UATH_LED_LINK, 0);
                    808:                        (void)uath_set_led(sc, UATH_LED_ACTIVITY, 0);
                    809:                }
                    810:                break;
                    811:
                    812:        case IEEE80211_S_SCAN:
                    813:                if (uath_switch_channel(sc, ic->ic_bss->ni_chan) != 0) {
                    814:                        printf("%s: could not switch channel\n",
                    815:                            sc->sc_dev.dv_xname);
                    816:                        break;
                    817:                }
                    818:                timeout_add(&sc->scan_to, hz / 4);
                    819:                break;
                    820:
                    821:        case IEEE80211_S_AUTH:
                    822:        {
                    823:                struct ieee80211_node *ni = ic->ic_bss;
                    824:                struct uath_cmd_bssid bssid;
                    825:                struct uath_cmd_0b cmd0b;
                    826:                struct uath_cmd_0c cmd0c;
                    827:
                    828:                if (uath_switch_channel(sc, ni->ni_chan) != 0) {
                    829:                        printf("%s: could not switch channel\n",
                    830:                            sc->sc_dev.dv_xname);
                    831:                        break;
                    832:                }
                    833:
                    834:                (void)uath_cmd_write(sc, UATH_CMD_24, NULL, 0, 0);
                    835:
                    836:                bzero(&bssid, sizeof bssid);
                    837:                bssid.len = htobe32(IEEE80211_ADDR_LEN);
                    838:                IEEE80211_ADDR_COPY(bssid.bssid, ni->ni_bssid);
                    839:                (void)uath_cmd_write(sc, UATH_CMD_SET_BSSID, &bssid,
                    840:                    sizeof bssid, 0);
                    841:
                    842:                bzero(&cmd0b, sizeof cmd0b);
                    843:                cmd0b.code = htobe32(2);
                    844:                cmd0b.size = htobe32(sizeof (cmd0b.data));
                    845:                (void)uath_cmd_write(sc, UATH_CMD_0B, &cmd0b, sizeof cmd0b, 0);
                    846:
                    847:                bzero(&cmd0c, sizeof cmd0c);
                    848:                cmd0c.magic1 = htobe32(2);
                    849:                cmd0c.magic2 = htobe32(7);
                    850:                cmd0c.magic3 = htobe32(1);
                    851:                (void)uath_cmd_write(sc, UATH_CMD_0C, &cmd0c, sizeof cmd0c, 0);
                    852:
                    853:                if (uath_set_rates(sc, &ni->ni_rates) != 0) {
                    854:                        printf("%s: could not set negotiated rate set\n",
                    855:                            sc->sc_dev.dv_xname);
                    856:                        break;
                    857:                }
                    858:                break;
                    859:        }
                    860:
                    861:        case IEEE80211_S_ASSOC:
                    862:                break;
                    863:
                    864:        case IEEE80211_S_RUN:
                    865:        {
                    866:                struct ieee80211_node *ni = ic->ic_bss;
                    867:                struct uath_cmd_bssid bssid;
                    868:                struct uath_cmd_xled xled;
                    869:                uint32_t val;
                    870:
                    871:                if (ic->ic_opmode == IEEE80211_M_MONITOR) {
                    872:                        /* make both LEDs blink while monitoring */
                    873:                        bzero(&xled, sizeof xled);
                    874:                        xled.which = htobe32(0);
                    875:                        xled.rate = htobe32(1);
                    876:                        xled.mode = htobe32(2);
                    877:                        (void)uath_cmd_write(sc, UATH_CMD_SET_XLED, &xled,
                    878:                            sizeof xled, 0);
                    879:                        break;
                    880:                }
                    881:
                    882:                /*
                    883:                 * Tx rate is controlled by firmware, report the maximum
                    884:                 * negotiated rate in ifconfig output.
                    885:                 */
                    886:                ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
                    887:
                    888:                val = htobe32(1);
                    889:                (void)uath_cmd_write(sc, UATH_CMD_2E, &val, sizeof val, 0);
                    890:
                    891:                bzero(&bssid, sizeof bssid);
                    892:                bssid.flags1 = htobe32(0xc004);
                    893:                bssid.flags2 = htobe32(0x003b);
                    894:                bssid.len = htobe32(IEEE80211_ADDR_LEN);
                    895:                IEEE80211_ADDR_COPY(bssid.bssid, ni->ni_bssid);
                    896:                (void)uath_cmd_write(sc, UATH_CMD_SET_BSSID, &bssid,
                    897:                    sizeof bssid, 0);
                    898:
                    899:                /* turn link LED on */
                    900:                (void)uath_set_led(sc, UATH_LED_LINK, 1);
                    901:
                    902:                /* make activity LED blink */
                    903:                bzero(&xled, sizeof xled);
                    904:                xled.which = htobe32(1);
                    905:                xled.rate = htobe32(1);
                    906:                xled.mode = htobe32(2);
                    907:                (void)uath_cmd_write(sc, UATH_CMD_SET_XLED, &xled, sizeof xled,
                    908:                    0);
                    909:
                    910:                /* set state to associated */
                    911:                val = htobe32(1);
                    912:                (void)uath_cmd_write(sc, UATH_CMD_SET_STATE, &val, sizeof val,
                    913:                    0);
                    914:
                    915:                /* start statistics timer */
                    916:                timeout_add(&sc->stat_to, hz);
                    917:                break;
                    918:        }
                    919:        }
                    920:        sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
                    921: }
                    922:
                    923: int
                    924: uath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                    925: {
                    926:        struct uath_softc *sc = ic->ic_softc;
                    927:
                    928:        usb_rem_task(sc->sc_udev, &sc->sc_task);
                    929:        timeout_del(&sc->scan_to);
                    930:        timeout_del(&sc->stat_to);
                    931:
                    932:        /* do it in a process context */
                    933:        sc->sc_state = nstate;
                    934:        sc->sc_arg = arg;
                    935:        usb_add_task(sc->sc_udev, &sc->sc_task);
                    936:        return 0;
                    937: }
                    938:
                    939: #ifdef UATH_DEBUG
                    940: void
                    941: uath_dump_cmd(const uint8_t *buf, int len, char prefix)
                    942: {
                    943:        int i;
                    944:
                    945:        for (i = 0; i < len; i++) {
                    946:                if ((i % 16) == 0)
                    947:                        printf("\n%c ", prefix);
                    948:                else if ((i % 4) == 0)
                    949:                        printf(" ");
                    950:                printf("%02x", buf[i]);
                    951:        }
                    952:        printf("\n");
                    953: }
                    954: #endif
                    955:
                    956: /*
                    957:  * Low-level function to send read or write commands to the firmware.
                    958:  */
                    959: int
                    960: uath_cmd(struct uath_softc *sc, uint32_t code, const void *idata, int ilen,
                    961:     void *odata, int flags)
                    962: {
                    963:        struct uath_cmd_hdr *hdr;
                    964:        struct uath_tx_cmd *cmd;
                    965:        uint16_t xferflags;
                    966:        int s, xferlen, error;
                    967:
                    968:        /* grab a xfer */
                    969:        cmd = &sc->tx_cmd[sc->cmd_idx];
                    970:
                    971:        /* always bulk-out a multiple of 4 bytes */
                    972:        xferlen = (sizeof (struct uath_cmd_hdr) + ilen + 3) & ~3;
                    973:
                    974:        hdr = (struct uath_cmd_hdr *)cmd->buf;
                    975:        bzero(hdr, sizeof (struct uath_cmd_hdr));
                    976:        hdr->len   = htobe32(xferlen);
                    977:        hdr->code  = htobe32(code);
                    978:        hdr->priv  = sc->cmd_idx;       /* don't care about endianness */
                    979:        hdr->magic = htobe32((flags & UATH_CMD_FLAG_MAGIC) ? 1 << 24 : 0);
                    980:        bcopy(idata, (uint8_t *)(hdr + 1), ilen);
                    981:
                    982: #ifdef UATH_DEBUG
                    983:        if (uath_debug >= 5) {
                    984:                printf("sending command code=0x%02x flags=0x%x index=%u",
                    985:                    code, flags, sc->cmd_idx);
                    986:                uath_dump_cmd(cmd->buf, xferlen, '+');
                    987:        }
                    988: #endif
                    989:        xferflags = USBD_FORCE_SHORT_XFER | USBD_NO_COPY;
                    990:        if (!(flags & UATH_CMD_FLAG_READ)) {
                    991:                if (!(flags & UATH_CMD_FLAG_ASYNC))
                    992:                        xferflags |= USBD_SYNCHRONOUS;
                    993:        } else
                    994:                s = splusb();
                    995:
                    996:        cmd->odata = odata;
                    997:
                    998:        usbd_setup_xfer(cmd->xfer, sc->cmd_tx_pipe, cmd, cmd->buf, xferlen,
                    999:            xferflags, UATH_CMD_TIMEOUT, NULL);
                   1000:        error = usbd_transfer(cmd->xfer);
                   1001:        if (error != USBD_IN_PROGRESS && error != 0) {
                   1002:                if (flags & UATH_CMD_FLAG_READ)
                   1003:                        splx(s);
                   1004:                printf("%s: could not send command 0x%x (error=%s)\n",
                   1005:                    sc->sc_dev.dv_xname, code, usbd_errstr(error));
                   1006:                return error;
                   1007:        }
                   1008:        sc->cmd_idx = (sc->cmd_idx + 1) % UATH_TX_CMD_LIST_COUNT;
                   1009:
                   1010:        if (!(flags & UATH_CMD_FLAG_READ))
                   1011:                return 0;       /* write: don't wait for reply */
                   1012:
                   1013:        /* wait at most two seconds for command reply */
                   1014:        error = tsleep(cmd, PCATCH, "uathcmd", 2 * hz);
                   1015:        cmd->odata = NULL;      /* in case answer is received too late */
                   1016:        splx(s);
                   1017:        if (error != 0) {
                   1018:                printf("%s: timeout waiting for command reply\n",
                   1019:                    sc->sc_dev.dv_xname);
                   1020:        }
                   1021:        return error;
                   1022: }
                   1023:
                   1024: int
                   1025: uath_cmd_write(struct uath_softc *sc, uint32_t code, const void *data, int len,
                   1026:     int flags)
                   1027: {
                   1028:        flags &= ~UATH_CMD_FLAG_READ;
                   1029:        return uath_cmd(sc, code, data, len, NULL, flags);
                   1030: }
                   1031:
                   1032: int
                   1033: uath_cmd_read(struct uath_softc *sc, uint32_t code, const void *idata,
                   1034:     int ilen, void *odata, int flags)
                   1035: {
                   1036:        flags |= UATH_CMD_FLAG_READ;
                   1037:        return uath_cmd(sc, code, idata, ilen, odata, flags);
                   1038: }
                   1039:
                   1040: int
                   1041: uath_write_reg(struct uath_softc *sc, uint32_t reg, uint32_t val)
                   1042: {
                   1043:        struct uath_write_mac write;
                   1044:        int error;
                   1045:
                   1046:        write.reg = htobe32(reg);
                   1047:        write.len = htobe32(0); /* 0 = single write */
                   1048:        *(uint32_t *)write.data = htobe32(val);
                   1049:
                   1050:        error = uath_cmd_write(sc, UATH_CMD_WRITE_MAC, &write,
                   1051:            3 * sizeof (uint32_t), 0);
                   1052:        if (error != 0) {
                   1053:                printf("%s: could not write register 0x%02x\n",
                   1054:                    sc->sc_dev.dv_xname, reg);
                   1055:        }
                   1056:        return error;
                   1057: }
                   1058:
                   1059: int
                   1060: uath_write_multi(struct uath_softc *sc, uint32_t reg, const void *data,
                   1061:     int len)
                   1062: {
                   1063:        struct uath_write_mac write;
                   1064:        int error;
                   1065:
                   1066:        write.reg = htobe32(reg);
                   1067:        write.len = htobe32(len);
                   1068:        bcopy(data, write.data, len);
                   1069:
                   1070:        /* properly handle the case where len is zero (reset) */
                   1071:        error = uath_cmd_write(sc, UATH_CMD_WRITE_MAC, &write,
                   1072:            (len == 0) ? sizeof (uint32_t) : 2 * sizeof (uint32_t) + len, 0);
                   1073:        if (error != 0) {
                   1074:                printf("%s: could not write %d bytes to register 0x%02x\n",
                   1075:                    sc->sc_dev.dv_xname, len, reg);
                   1076:        }
                   1077:        return error;
                   1078: }
                   1079:
                   1080: int
                   1081: uath_read_reg(struct uath_softc *sc, uint32_t reg, uint32_t *val)
                   1082: {
                   1083:        struct uath_read_mac read;
                   1084:        int error;
                   1085:
                   1086:        reg = htobe32(reg);
                   1087:        error = uath_cmd_read(sc, UATH_CMD_READ_MAC, &reg, sizeof reg, &read,
                   1088:            0);
                   1089:        if (error != 0) {
                   1090:                printf("%s: could not read register 0x%02x\n",
                   1091:                    sc->sc_dev.dv_xname, betoh32(reg));
                   1092:                return error;
                   1093:        }
                   1094:        *val = betoh32(*(uint32_t *)read.data);
                   1095:        return error;
                   1096: }
                   1097:
                   1098: int
                   1099: uath_read_eeprom(struct uath_softc *sc, uint32_t reg, void *odata)
                   1100: {
                   1101:        struct uath_read_mac read;
                   1102:        int len, error;
                   1103:
                   1104:        reg = htobe32(reg);
                   1105:        error = uath_cmd_read(sc, UATH_CMD_READ_EEPROM, &reg, sizeof reg,
                   1106:            &read, 0);
                   1107:        if (error != 0) {
                   1108:                printf("%s: could not read EEPROM offset 0x%02x\n",
                   1109:                    sc->sc_dev.dv_xname, betoh32(reg));
                   1110:                return error;
                   1111:        }
                   1112:        len = betoh32(read.len);
                   1113:        bcopy(read.data, odata, (len == 0) ? sizeof (uint32_t) : len);
                   1114:        return error;
                   1115: }
                   1116:
                   1117: void
                   1118: uath_cmd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
                   1119:     usbd_status status)
                   1120: {
                   1121:        struct uath_rx_cmd *cmd = priv;
                   1122:        struct uath_softc *sc = cmd->sc;
                   1123:        struct uath_cmd_hdr *hdr;
                   1124:
                   1125:        if (status != USBD_NORMAL_COMPLETION) {
                   1126:                if (status == USBD_STALLED)
                   1127:                        usbd_clear_endpoint_stall_async(sc->cmd_rx_pipe);
                   1128:                return;
                   1129:        }
                   1130:
                   1131:        hdr = (struct uath_cmd_hdr *)cmd->buf;
                   1132:
                   1133: #ifdef UATH_DEBUG
                   1134:        if (uath_debug >= 5) {
                   1135:                printf("received command code=0x%x index=%u len=%u",
                   1136:                    betoh32(hdr->code), hdr->priv, betoh32(hdr->len));
                   1137:                uath_dump_cmd(cmd->buf, betoh32(hdr->len), '-');
                   1138:        }
                   1139: #endif
                   1140:
                   1141:        switch (betoh32(hdr->code) & 0xff) {
                   1142:        /* reply to a read command */
                   1143:        default:
                   1144:        {
                   1145:                struct uath_tx_cmd *txcmd = &sc->tx_cmd[hdr->priv];
                   1146:
                   1147:                if (txcmd->odata != NULL) {
                   1148:                        /* copy answer into caller's supplied buffer */
                   1149:                        bcopy((uint8_t *)(hdr + 1), txcmd->odata,
                   1150:                            betoh32(hdr->len) - sizeof (struct uath_cmd_hdr));
                   1151:                }
                   1152:                wakeup(txcmd);  /* wake up caller */
                   1153:                break;
                   1154:        }
                   1155:        /* spontaneous firmware notifications */
                   1156:        case UATH_NOTIF_READY:
                   1157:                DPRINTF(("received device ready notification\n"));
                   1158:                wakeup(UATH_COND_INIT(sc));
                   1159:                break;
                   1160:
                   1161:        case UATH_NOTIF_TX:
                   1162:                /* this notification is sent when UATH_TX_NOTIFY is set */
                   1163:                DPRINTF(("received Tx notification\n"));
                   1164:                break;
                   1165:
                   1166:        case UATH_NOTIF_STATS:
                   1167:                DPRINTFN(2, ("received device statistics\n"));
                   1168:                timeout_add(&sc->stat_to, hz);
                   1169:                break;
                   1170:        }
                   1171:
                   1172:        /* setup a new transfer */
                   1173:        usbd_setup_xfer(xfer, sc->cmd_rx_pipe, cmd, cmd->buf, UATH_MAX_RXCMDSZ,
                   1174:            USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
                   1175:            uath_cmd_rxeof);
                   1176:        (void)usbd_transfer(xfer);
                   1177: }
                   1178:
                   1179: void
                   1180: uath_data_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
                   1181:     usbd_status status)
                   1182: {
                   1183:        struct uath_rx_data *data = priv;
                   1184:        struct uath_softc *sc = data->sc;
                   1185:        struct ieee80211com *ic = &sc->sc_ic;
                   1186:        struct ifnet *ifp = &ic->ic_if;
                   1187:        struct ieee80211_frame *wh;
                   1188:        struct ieee80211_node *ni;
                   1189:        struct uath_rx_data *ndata;
                   1190:        struct uath_rx_desc *desc;
                   1191:        struct mbuf *m;
                   1192:        uint32_t hdr;
                   1193:        int s, len;
                   1194:
                   1195:        if (status != USBD_NORMAL_COMPLETION) {
                   1196:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   1197:                        return;
                   1198:
                   1199:                if (status == USBD_STALLED)
                   1200:                        usbd_clear_endpoint_stall_async(sc->data_rx_pipe);
                   1201:
                   1202:                ifp->if_ierrors++;
                   1203:                return;
                   1204:        }
                   1205:        usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
                   1206:
                   1207:        if (len < UATH_MIN_RXBUFSZ) {
                   1208:                DPRINTF(("wrong xfer size (len=%d)\n", len));
                   1209:                ifp->if_ierrors++;
                   1210:                goto skip;
                   1211:        }
                   1212:
                   1213:        hdr = betoh32(*(uint32_t *)data->buf);
                   1214:
                   1215:        /* Rx descriptor is located at the end, 32-bit aligned */
                   1216:        desc = (struct uath_rx_desc *)
                   1217:            (data->buf + len - sizeof (struct uath_rx_desc));
                   1218:
                   1219:        if (betoh32(desc->len) > sc->rxbufsz) {
                   1220:                DPRINTF(("bad descriptor (len=%d)\n", betoh32(desc->len)));
                   1221:                ifp->if_ierrors++;
                   1222:                goto skip;
                   1223:        }
                   1224:
                   1225:        /* there's probably a "bad CRC" flag somewhere in the descriptor.. */
                   1226:
                   1227:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1228:        if (m == NULL) {
                   1229:                ifp->if_ierrors++;
                   1230:                goto skip;
                   1231:        }
                   1232:
                   1233:        /* grab a new Rx buffer */
                   1234:        ndata = SLIST_FIRST(&sc->rx_freelist);
                   1235:        if (ndata == NULL) {
                   1236:                printf("%s: could not allocate Rx buffer\n",
                   1237:                    sc->sc_dev.dv_xname);
                   1238:                m_freem(m);
                   1239:                ifp->if_ierrors++;
                   1240:                goto skip;
                   1241:        }
                   1242:        SLIST_REMOVE_HEAD(&sc->rx_freelist, next);
                   1243:
                   1244:        MEXTADD(m, data->buf, sc->rxbufsz, 0, uath_free_rx_data, data);
                   1245:
                   1246:        /* finalize mbuf */
                   1247:        m->m_pkthdr.rcvif = ifp;
                   1248:        m->m_data = data->buf + sizeof (uint32_t);
                   1249:        m->m_pkthdr.len = m->m_len = betoh32(desc->len) -
                   1250:            sizeof (struct uath_rx_desc) - IEEE80211_CRC_LEN;
                   1251:
                   1252:        data = ndata;
                   1253:
                   1254:        wh = mtod(m, struct ieee80211_frame *);
                   1255:        if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
                   1256:            ic->ic_opmode != IEEE80211_M_MONITOR) {
                   1257:                /*
                   1258:                 * Hardware decrypts the frame itself but leaves the WEP bit
                   1259:                 * set in the 802.11 header and doesn't remove the IV and CRC
                   1260:                 * fields.
                   1261:                 */
                   1262:                wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
                   1263:                ovbcopy(wh, (caddr_t)wh + IEEE80211_WEP_IVLEN +
                   1264:                    IEEE80211_WEP_KIDLEN, sizeof (struct ieee80211_frame));
                   1265:                m_adj(m, IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN);
                   1266:                m_adj(m, -IEEE80211_WEP_CRCLEN);
                   1267:                wh = mtod(m, struct ieee80211_frame *);
                   1268:        }
                   1269:
                   1270: #if NBPFILTER > 0
                   1271:        /* there are a lot more fields in the Rx descriptor */
                   1272:        if (sc->sc_drvbpf != NULL) {
                   1273:                struct mbuf mb;
                   1274:                struct uath_rx_radiotap_header *tap = &sc->sc_rxtap;
                   1275:
                   1276:                tap->wr_flags = 0;
                   1277:                tap->wr_chan_freq = htole16(betoh32(desc->freq));
                   1278:                tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1279:                tap->wr_dbm_antsignal = (int8_t)betoh32(desc->rssi);
                   1280:
                   1281:                mb.m_data = (caddr_t)tap;
                   1282:                mb.m_len = sc->sc_rxtap_len;
                   1283:                mb.m_next = m;
                   1284:                mb.m_nextpkt = NULL;
                   1285:                mb.m_type = 0;
                   1286:                mb.m_flags = 0;
                   1287:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
                   1288:        }
                   1289: #endif
                   1290:
                   1291:        s = splnet();
                   1292:        sc->sc_refcnt++;
                   1293:        ni = ieee80211_find_rxnode(ic, wh);
                   1294:        ieee80211_input(ifp, m, ni, (int)betoh32(desc->rssi), 0);
                   1295:
                   1296:        /* node is no longer needed */
                   1297:        ieee80211_release_node(ic, ni);
                   1298:        splx(s);
                   1299:
                   1300: skip:  /* setup a new transfer */
                   1301:        usbd_setup_xfer(data->xfer, sc->data_rx_pipe, data, data->buf,
                   1302:            sc->rxbufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
                   1303:            uath_data_rxeof);
                   1304:        (void)usbd_transfer(data->xfer);
                   1305: }
                   1306:
                   1307: int
                   1308: uath_tx_null(struct uath_softc *sc)
                   1309: {
                   1310:        struct uath_tx_data *data;
                   1311:        struct uath_tx_desc *desc;
                   1312:
                   1313:        data = &sc->tx_data[sc->data_idx];
                   1314:
                   1315:        data->ni = NULL;
                   1316:
                   1317:        *(uint32_t *)data->buf = UATH_MAKECTL(1, sizeof (struct uath_tx_desc));
                   1318:        desc = (struct uath_tx_desc *)(data->buf + sizeof (uint32_t));
                   1319:
                   1320:        bzero(desc, sizeof (struct uath_tx_desc));
                   1321:        desc->len  = htobe32(sizeof (struct uath_tx_desc));
                   1322:        desc->type = htobe32(UATH_TX_NULL);
                   1323:
                   1324:        usbd_setup_xfer(data->xfer, sc->data_tx_pipe, data, data->buf,
                   1325:            sizeof (uint32_t) + sizeof (struct uath_tx_desc), USBD_NO_COPY |
                   1326:            USBD_FORCE_SHORT_XFER, UATH_DATA_TIMEOUT, NULL);
                   1327:        if (usbd_sync_transfer(data->xfer) != 0)
                   1328:                return EIO;
                   1329:
                   1330:        sc->data_idx = (sc->data_idx + 1) % UATH_TX_DATA_LIST_COUNT;
                   1331:
                   1332:        return uath_cmd_write(sc, UATH_CMD_0F, NULL, 0, UATH_CMD_FLAG_ASYNC);
                   1333: }
                   1334:
                   1335: void
                   1336: uath_data_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
                   1337:     usbd_status status)
                   1338: {
                   1339:        struct uath_tx_data *data = priv;
                   1340:        struct uath_softc *sc = data->sc;
                   1341:        struct ieee80211com *ic = &sc->sc_ic;
                   1342:        struct ifnet *ifp = &ic->ic_if;
                   1343:        int s;
                   1344:
                   1345:        if (status != USBD_NORMAL_COMPLETION) {
                   1346:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   1347:                        return;
                   1348:
                   1349:                printf("%s: could not transmit buffer: %s\n",
                   1350:                    sc->sc_dev.dv_xname, usbd_errstr(status));
                   1351:
                   1352:                if (status == USBD_STALLED)
                   1353:                        usbd_clear_endpoint_stall_async(sc->data_tx_pipe);
                   1354:
                   1355:                ifp->if_oerrors++;
                   1356:                return;
                   1357:        }
                   1358:
                   1359:        s = splnet();
                   1360:
                   1361:        ieee80211_release_node(ic, data->ni);
                   1362:        data->ni = NULL;
                   1363:
                   1364:        sc->tx_queued--;
                   1365:        ifp->if_opackets++;
                   1366:
                   1367:        sc->sc_tx_timer = 0;
                   1368:        ifp->if_flags &= ~IFF_OACTIVE;
                   1369:        uath_start(ifp);
                   1370:
                   1371:        splx(s);
                   1372: }
                   1373:
                   1374: int
                   1375: uath_tx_data(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                   1376: {
                   1377:        struct ieee80211com *ic = &sc->sc_ic;
                   1378:        struct uath_tx_data *data;
                   1379:        struct uath_tx_desc *desc;
                   1380:        const struct ieee80211_frame *wh;
                   1381:        int paylen, totlen, xferlen, error;
                   1382:
                   1383:        data = &sc->tx_data[sc->data_idx];
                   1384:        desc = (struct uath_tx_desc *)(data->buf + sizeof (uint32_t));
                   1385:
                   1386:        data->ni = ni;
                   1387:
                   1388: #if NBPFILTER > 0
                   1389:        if (sc->sc_drvbpf != NULL) {
                   1390:                struct mbuf mb;
                   1391:                struct uath_tx_radiotap_header *tap = &sc->sc_txtap;
                   1392:
                   1393:                tap->wt_flags = 0;
                   1394:                tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   1395:                tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1396:
                   1397:                mb.m_data = (caddr_t)tap;
                   1398:                mb.m_len = sc->sc_txtap_len;
                   1399:                mb.m_next = m0;
                   1400:                mb.m_nextpkt = NULL;
                   1401:                mb.m_type = 0;
                   1402:                mb.m_flags = 0;
                   1403:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
                   1404:        }
                   1405: #endif
                   1406:
                   1407:        paylen = m0->m_pkthdr.len;
                   1408:        xferlen = sizeof (uint32_t) + sizeof (struct uath_tx_desc) + paylen;
                   1409:
                   1410:        wh = mtod(m0, struct ieee80211_frame *);
                   1411:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   1412:                uint8_t *frm = (uint8_t *)(desc + 1);
                   1413:                uint32_t iv;
                   1414:
                   1415:                /* h/w WEP: it's up to the host to fill the IV field */
                   1416:                bcopy(wh, frm, sizeof (struct ieee80211_frame));
                   1417:                frm += sizeof (struct ieee80211_frame);
                   1418:
                   1419:                /* insert IV: code copied from net80211 */
                   1420:                iv = (ic->ic_iv != 0) ? ic->ic_iv : arc4random();
                   1421:                if (iv >= 0x03ff00 && (iv & 0xf8ff00) == 0x00ff00)
                   1422:                        iv += 0x000100;
                   1423:                ic->ic_iv = iv + 1;
                   1424:
                   1425:                *frm++ = iv & 0xff;
                   1426:                *frm++ = (iv >>  8) & 0xff;
                   1427:                *frm++ = (iv >> 16) & 0xff;
                   1428:                *frm++ = ic->ic_wep_txkey << 6;
                   1429:
                   1430:                m_copydata(m0, sizeof (struct ieee80211_frame),
                   1431:                    m0->m_pkthdr.len - sizeof (struct ieee80211_frame), frm);
                   1432:
                   1433:                paylen  += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
                   1434:                xferlen += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
                   1435:                totlen = xferlen + IEEE80211_WEP_CRCLEN;
                   1436:        } else {
                   1437:                m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(desc + 1));
                   1438:                totlen = xferlen;
                   1439:        }
                   1440:
                   1441:        /* fill Tx descriptor */
                   1442:        *(uint32_t *)data->buf = UATH_MAKECTL(1, xferlen - sizeof (uint32_t));
                   1443:
                   1444:        desc->len    = htobe32(totlen);
                   1445:        desc->priv   = sc->data_idx;    /* don't care about endianness */
                   1446:        desc->paylen = htobe32(paylen);
                   1447:        desc->type   = htobe32(UATH_TX_DATA);
                   1448:        desc->flags  = htobe32(0);
                   1449:        if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
                   1450:                desc->dest  = htobe32(UATH_ID_BROADCAST);
                   1451:                desc->magic = htobe32(3);
                   1452:        } else {
                   1453:                desc->dest  = htobe32(UATH_ID_BSS);
                   1454:                desc->magic = htobe32(1);
                   1455:        }
                   1456:
                   1457:        m_freem(m0);    /* mbuf is no longer needed */
                   1458:
                   1459: #ifdef UATH_DEBUG
                   1460:        if (uath_debug >= 6) {
                   1461:                printf("sending frame index=%u len=%d xferlen=%d",
                   1462:                    sc->data_idx, paylen, xferlen);
                   1463:                uath_dump_cmd(data->buf, xferlen, '+');
                   1464:        }
                   1465: #endif
                   1466:        usbd_setup_xfer(data->xfer, sc->data_tx_pipe, data, data->buf, xferlen,
                   1467:            USBD_FORCE_SHORT_XFER | USBD_NO_COPY, UATH_DATA_TIMEOUT,
                   1468:            uath_data_txeof);
                   1469:        error = usbd_transfer(data->xfer);
                   1470:        if (error != USBD_IN_PROGRESS && error != 0) {
                   1471:                ic->ic_if.if_oerrors++;
                   1472:                return error;
                   1473:        }
                   1474:        sc->data_idx = (sc->data_idx + 1) % UATH_TX_DATA_LIST_COUNT;
                   1475:        sc->tx_queued++;
                   1476:
                   1477:        return 0;
                   1478: }
                   1479:
                   1480: void
                   1481: uath_start(struct ifnet *ifp)
                   1482: {
                   1483:        struct uath_softc *sc = ifp->if_softc;
                   1484:        struct ieee80211com *ic = &sc->sc_ic;
                   1485:        struct ieee80211_node *ni;
                   1486:        struct mbuf *m0;
                   1487:
                   1488:        /*
                   1489:         * net80211 may still try to send management frames even if the
                   1490:         * IFF_RUNNING flag is not set...
                   1491:         */
                   1492:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   1493:                return;
                   1494:
                   1495:        for (;;) {
                   1496:                IF_POLL(&ic->ic_mgtq, m0);
                   1497:                if (m0 != NULL) {
                   1498:                        if (sc->tx_queued >= UATH_TX_DATA_LIST_COUNT) {
                   1499:                                ifp->if_flags |= IFF_OACTIVE;
                   1500:                                break;
                   1501:                        }
                   1502:                        IF_DEQUEUE(&ic->ic_mgtq, m0);
                   1503:
                   1504:                        ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
                   1505:                        m0->m_pkthdr.rcvif = NULL;
                   1506: #if NBPFILTER > 0
                   1507:                        if (ic->ic_rawbpf != NULL)
                   1508:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   1509: #endif
                   1510:                        if (uath_tx_data(sc, m0, ni) != 0)
                   1511:                                break;
                   1512:                } else {
                   1513:                        if (ic->ic_state != IEEE80211_S_RUN)
                   1514:                                break;
                   1515:                        IFQ_POLL(&ifp->if_snd, m0);
                   1516:                        if (m0 == NULL)
                   1517:                                break;
                   1518:                        if (sc->tx_queued >= UATH_TX_DATA_LIST_COUNT) {
                   1519:                                ifp->if_flags |= IFF_OACTIVE;
                   1520:                                break;
                   1521:                        }
                   1522:                        IFQ_DEQUEUE(&ifp->if_snd, m0);
                   1523: #if NBPFILTER > 0
                   1524:                        if (ifp->if_bpf != NULL)
                   1525:                                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   1526: #endif
                   1527:                        m0 = ieee80211_encap(ifp, m0, &ni);
                   1528:                        if (m0 == NULL)
                   1529:                                continue;
                   1530: #if NBPFILTER > 0
                   1531:                        if (ic->ic_rawbpf != NULL)
                   1532:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   1533: #endif
                   1534:                        if (uath_tx_data(sc, m0, ni) != 0) {
                   1535:                                if (ni != NULL)
                   1536:                                        ieee80211_release_node(ic, ni);
                   1537:                                ifp->if_oerrors++;
                   1538:                                break;
                   1539:                        }
                   1540:                }
                   1541:
                   1542:                sc->sc_tx_timer = 5;
                   1543:                ifp->if_timer = 1;
                   1544:        }
                   1545: }
                   1546:
                   1547: void
                   1548: uath_watchdog(struct ifnet *ifp)
                   1549: {
                   1550:        struct uath_softc *sc = ifp->if_softc;
                   1551:
                   1552:        ifp->if_timer = 0;
                   1553:
                   1554:        if (sc->sc_tx_timer > 0) {
                   1555:                if (--sc->sc_tx_timer == 0) {
                   1556:                        printf("%s: device timeout\n", sc->sc_dev.dv_xname);
                   1557:                        /*uath_init(ifp); XXX needs a process context! */
                   1558:                        ifp->if_oerrors++;
                   1559:                        return;
                   1560:                }
                   1561:                ifp->if_timer = 1;
                   1562:        }
                   1563:
                   1564:        ieee80211_watchdog(ifp);
                   1565: }
                   1566:
                   1567: int
                   1568: uath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                   1569: {
                   1570:        struct uath_softc *sc = ifp->if_softc;
                   1571:        struct ieee80211com *ic = &sc->sc_ic;
                   1572:        struct ifaddr *ifa;
                   1573:        struct ifreq *ifr;
                   1574:        int s, error = 0;
                   1575:
                   1576:        s = splnet();
                   1577:
                   1578:        switch (cmd) {
                   1579:        case SIOCSIFADDR:
                   1580:                ifa = (struct ifaddr *)data;
                   1581:                ifp->if_flags |= IFF_UP;
                   1582: #ifdef INET
                   1583:                if (ifa->ifa_addr->sa_family == AF_INET)
                   1584:                        arp_ifinit(&ic->ic_ac, ifa);
                   1585: #endif
                   1586:                /* FALLTHROUGH */
                   1587:        case SIOCSIFFLAGS:
                   1588:                if (ifp->if_flags & IFF_UP) {
                   1589:                        if (!(ifp->if_flags & IFF_RUNNING))
                   1590:                                uath_init(ifp);
                   1591:                } else {
                   1592:                        if (ifp->if_flags & IFF_RUNNING)
                   1593:                                uath_stop(ifp, 1);
                   1594:                }
                   1595:                break;
                   1596:
                   1597:        case SIOCADDMULTI:
                   1598:        case SIOCDELMULTI:
                   1599:                ifr = (struct ifreq *)data;
                   1600:                error = (cmd == SIOCADDMULTI) ?
                   1601:                    ether_addmulti(ifr, &ic->ic_ac) :
                   1602:                    ether_delmulti(ifr, &ic->ic_ac);
                   1603:                if (error == ENETRESET)
                   1604:                        error = 0;
                   1605:                break;
                   1606:
                   1607:        default:
                   1608:                error = ieee80211_ioctl(ifp, cmd, data);
                   1609:        }
                   1610:
                   1611:        if (error == ENETRESET) {
                   1612:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1613:                    (IFF_UP | IFF_RUNNING))
                   1614:                        uath_init(ifp);
                   1615:                error = 0;
                   1616:        }
                   1617:
                   1618:        splx(s);
                   1619:
                   1620:        return error;
                   1621: }
                   1622:
                   1623: int
                   1624: uath_query_eeprom(struct uath_softc *sc)
                   1625: {
                   1626:        uint32_t tmp;
                   1627:        int error;
                   1628:
                   1629:        /* retrieve MAC address */
                   1630:        error = uath_read_eeprom(sc, UATH_EEPROM_MACADDR, sc->sc_ic.ic_myaddr);
                   1631:        if (error != 0) {
                   1632:                printf("%s: could not read MAC address\n",
                   1633:                    sc->sc_dev.dv_xname);
                   1634:                return error;
                   1635:        }
                   1636:
                   1637:        /* retrieve the maximum frame size that the hardware can receive */
                   1638:        error = uath_read_eeprom(sc, UATH_EEPROM_RXBUFSZ, &tmp);
                   1639:        if (error != 0) {
                   1640:                printf("%s: could not read maximum Rx buffer size\n",
                   1641:                    sc->sc_dev.dv_xname);
                   1642:                return error;
                   1643:        }
                   1644:        sc->rxbufsz = betoh32(tmp) & 0xfff;
                   1645:        DPRINTF(("maximum Rx buffer size %d\n", sc->rxbufsz));
                   1646:        return 0;
                   1647: }
                   1648:
                   1649: int
                   1650: uath_reset(struct uath_softc *sc)
                   1651: {
                   1652:        struct uath_cmd_setup setup;
                   1653:        uint32_t reg, val;
                   1654:        int s, error;
                   1655:
                   1656:        /* init device with some voodoo incantations.. */
                   1657:        setup.magic1 = htobe32(1);
                   1658:        setup.magic2 = htobe32(5);
                   1659:        setup.magic3 = htobe32(200);
                   1660:        setup.magic4 = htobe32(27);
                   1661:        s = splusb();
                   1662:        error = uath_cmd_write(sc, UATH_CMD_SETUP, &setup, sizeof setup,
                   1663:            UATH_CMD_FLAG_ASYNC);
                   1664:        /* ..and wait until firmware notifies us that it is ready */
                   1665:        if (error == 0)
                   1666:                error = tsleep(UATH_COND_INIT(sc), PCATCH, "uathinit", 5 * hz);
                   1667:        splx(s);
                   1668:        if (error != 0)
                   1669:                return error;
                   1670:
                   1671:        /* read PHY registers */
                   1672:        for (reg = 0x09; reg <= 0x24; reg++) {
                   1673:                if (reg == 0x0b || reg == 0x0c)
                   1674:                        continue;
                   1675:                DELAY(100);
                   1676:                if ((error = uath_read_reg(sc, reg, &val)) != 0)
                   1677:                        return error;
                   1678:                DPRINTFN(2, ("reg 0x%02x=0x%08x\n", reg, val));
                   1679:        }
                   1680:        return error;
                   1681: }
                   1682:
                   1683: int
                   1684: uath_reset_tx_queues(struct uath_softc *sc)
                   1685: {
                   1686:        int ac, error;
                   1687:
                   1688:        for (ac = 0; ac < 4; ac++) {
                   1689:                const uint32_t qid = htobe32(UATH_AC_TO_QID(ac));
                   1690:
                   1691:                DPRINTF(("resetting Tx queue %d\n", UATH_AC_TO_QID(ac)));
                   1692:                error = uath_cmd_write(sc, UATH_CMD_RESET_QUEUE, &qid,
                   1693:                    sizeof qid, 0);
                   1694:                if (error != 0)
                   1695:                        break;
                   1696:        }
                   1697:        return error;
                   1698: }
                   1699:
                   1700: int
                   1701: uath_wme_init(struct uath_softc *sc)
                   1702: {
                   1703:        struct uath_qinfo qinfo;
                   1704:        int ac, error;
                   1705:        static const struct uath_wme_settings uath_wme_11g[4] = {
                   1706:                { 7, 4, 10,  0, 0 },    /* Background */
                   1707:                { 3, 4, 10,  0, 0 },    /* Best-Effort */
                   1708:                { 3, 3,  4, 26, 0 },    /* Video */
                   1709:                { 2, 2,  3, 47, 0 }     /* Voice */
                   1710:        };
                   1711:
                   1712:        bzero(&qinfo, sizeof qinfo);
                   1713:        qinfo.size   = htobe32(32);
                   1714:        qinfo.magic1 = htobe32(1);      /* XXX ack policy? */
                   1715:        qinfo.magic2 = htobe32(1);
                   1716:        for (ac = 0; ac < 4; ac++) {
                   1717:                qinfo.qid      = htobe32(UATH_AC_TO_QID(ac));
                   1718:                qinfo.ac       = htobe32(ac);
                   1719:                qinfo.aifsn    = htobe32(uath_wme_11g[ac].aifsn);
                   1720:                qinfo.logcwmin = htobe32(uath_wme_11g[ac].logcwmin);
                   1721:                qinfo.logcwmax = htobe32(uath_wme_11g[ac].logcwmax);
                   1722:                qinfo.txop     = htobe32(UATH_TXOP_TO_US(
                   1723:                                     uath_wme_11g[ac].txop));
                   1724:                qinfo.acm      = htobe32(uath_wme_11g[ac].acm);
                   1725:
                   1726:                DPRINTF(("setting up Tx queue %d\n", UATH_AC_TO_QID(ac)));
                   1727:                error = uath_cmd_write(sc, UATH_CMD_SET_QUEUE, &qinfo,
                   1728:                    sizeof qinfo, 0);
                   1729:                if (error != 0)
                   1730:                        break;
                   1731:        }
                   1732:        return error;
                   1733: }
                   1734:
                   1735: int
                   1736: uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c)
                   1737: {
                   1738:        struct uath_set_chan chan;
                   1739:
                   1740:        bzero(&chan, sizeof chan);
                   1741:        chan.flags  = htobe32(0x1400);
                   1742:        chan.freq   = htobe32(c->ic_freq);
                   1743:        chan.magic1 = htobe32(20);
                   1744:        chan.magic2 = htobe32(50);
                   1745:        chan.magic3 = htobe32(1);
                   1746:
                   1747:        DPRINTF(("switching to channel %d\n",
                   1748:            ieee80211_chan2ieee(&sc->sc_ic, c)));
                   1749:        return uath_cmd_write(sc, UATH_CMD_SET_CHAN, &chan, sizeof chan, 0);
                   1750: }
                   1751:
                   1752: int
                   1753: uath_set_key(struct uath_softc *sc, const struct ieee80211_key *k, int index)
                   1754: {
                   1755:        struct uath_cmd_crypto crypto;
                   1756:        int i;
                   1757:
                   1758:        bzero(&crypto, sizeof crypto);
                   1759:        crypto.keyidx = htobe32(index);
                   1760:        crypto.magic1 = htobe32(1);
                   1761:        crypto.size   = htobe32(368);
                   1762:        crypto.mask   = htobe32(0xffff);
                   1763:        crypto.flags  = htobe32(0x80000068);
                   1764:        if (index != UATH_DEFAULT_KEY)
                   1765:                crypto.flags |= htobe32(index << 16);
                   1766:        memset(crypto.magic2, 0xff, sizeof crypto.magic2);
                   1767:
                   1768:        /*
                   1769:         * Each byte of the key must be XOR'ed with 10101010 before being
                   1770:         * transmitted to the firmware.
                   1771:         */
                   1772:        for (i = 0; i < k->k_len; i++)
                   1773:                crypto.key[i] = k->k_key[i] ^ 0xaa;
                   1774:
                   1775:        DPRINTF(("setting crypto key index=%d len=%d\n", index, k->k_len));
                   1776:        return uath_cmd_write(sc, UATH_CMD_CRYPTO, &crypto, sizeof crypto, 0);
                   1777: }
                   1778:
                   1779: int
                   1780: uath_set_keys(struct uath_softc *sc)
                   1781: {
                   1782:        const struct ieee80211com *ic = &sc->sc_ic;
                   1783:        int i, error;
                   1784:
                   1785:        for (i = 0; i < IEEE80211_WEP_NKID; i++) {
                   1786:                const struct ieee80211_key *k = &ic->ic_nw_keys[i];
                   1787:
                   1788:                if (k->k_len > 0 && (error = uath_set_key(sc, k, i)) != 0)
                   1789:                        return error;
                   1790:        }
                   1791:        return uath_set_key(sc, &ic->ic_nw_keys[ic->ic_wep_txkey],
                   1792:            UATH_DEFAULT_KEY);
                   1793: }
                   1794:
                   1795: int
                   1796: uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs)
                   1797: {
                   1798:        struct uath_cmd_rates rates;
                   1799:
                   1800:        bzero(&rates, sizeof rates);
                   1801:        rates.magic1 = htobe32(0x02);
                   1802:        rates.size   = htobe32(1 + sizeof rates.rates);
                   1803:        rates.nrates = rs->rs_nrates;
                   1804:        bcopy(rs->rs_rates, rates.rates, rs->rs_nrates);
                   1805:
                   1806:        DPRINTF(("setting supported rates nrates=%d\n", rs->rs_nrates));
                   1807:        return uath_cmd_write(sc, UATH_CMD_SET_RATES, &rates, sizeof rates, 0);
                   1808: }
                   1809:
                   1810: int
                   1811: uath_set_rxfilter(struct uath_softc *sc, uint32_t filter, uint32_t flags)
                   1812: {
                   1813:        struct uath_cmd_filter rxfilter;
                   1814:
                   1815:        rxfilter.filter = htobe32(filter);
                   1816:        rxfilter.flags  = htobe32(flags);
                   1817:
                   1818:        DPRINTF(("setting Rx filter=0x%x flags=0x%x\n", filter, flags));
                   1819:        return uath_cmd_write(sc, UATH_CMD_SET_FILTER, &rxfilter,
                   1820:            sizeof rxfilter, 0);
                   1821: }
                   1822:
                   1823: int
                   1824: uath_set_led(struct uath_softc *sc, int which, int on)
                   1825: {
                   1826:        struct uath_cmd_led led;
                   1827:
                   1828:        led.which = htobe32(which);
                   1829:        led.state = htobe32(on ? UATH_LED_ON : UATH_LED_OFF);
                   1830:
                   1831:        DPRINTFN(2, ("switching %s led %s\n",
                   1832:            (which == UATH_LED_LINK) ? "link" : "activity",
                   1833:            on ? "on" : "off"));
                   1834:        return uath_cmd_write(sc, UATH_CMD_SET_LED, &led, sizeof led, 0);
                   1835: }
                   1836:
                   1837: int
                   1838: uath_switch_channel(struct uath_softc *sc, struct ieee80211_channel *c)
                   1839: {
                   1840:        uint32_t val;
                   1841:        int error;
                   1842:
                   1843:        /* set radio frequency */
                   1844:        if ((error = uath_set_chan(sc, c)) != 0) {
                   1845:                printf("%s: could not set channel\n", sc->sc_dev.dv_xname);
                   1846:                return error;
                   1847:        }
                   1848:
                   1849:        /* reset Tx rings */
                   1850:        if ((error = uath_reset_tx_queues(sc)) != 0) {
                   1851:                printf("%s: could not reset Tx queues\n",
                   1852:                    sc->sc_dev.dv_xname);
                   1853:                return error;
                   1854:        }
                   1855:
                   1856:        /* set Tx rings WME properties */
                   1857:        if ((error = uath_wme_init(sc)) != 0) {
                   1858:                printf("%s: could not init Tx queues\n",
                   1859:                    sc->sc_dev.dv_xname);
                   1860:                return error;
                   1861:        }
                   1862:
                   1863:        val = htobe32(0);
                   1864:        error = uath_cmd_write(sc, UATH_CMD_SET_STATE, &val, sizeof val, 0);
                   1865:        if (error != 0) {
                   1866:                printf("%s: could not set state\n", sc->sc_dev.dv_xname);
                   1867:                return error;
                   1868:        }
                   1869:
                   1870:        return uath_tx_null(sc);
                   1871: }
                   1872:
                   1873: int
                   1874: uath_init(struct ifnet *ifp)
                   1875: {
                   1876:        struct uath_softc *sc = ifp->if_softc;
                   1877:        struct ieee80211com *ic = &sc->sc_ic;
                   1878:        struct uath_cmd_31 cmd31;
                   1879:        uint32_t val;
                   1880:        int i, error;
                   1881:
                   1882:        /* reset data and command rings */
                   1883:        sc->tx_queued = sc->data_idx = sc->cmd_idx = 0;
                   1884:
                   1885:        val = htobe32(0);
                   1886:        (void)uath_cmd_write(sc, UATH_CMD_02, &val, sizeof val, 0);
                   1887:
                   1888:        /* set MAC address */
                   1889:        IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
                   1890:        (void)uath_write_multi(sc, 0x13, ic->ic_myaddr, IEEE80211_ADDR_LEN);
                   1891:
                   1892:        (void)uath_write_reg(sc, 0x02, 0x00000001);
                   1893:        (void)uath_write_reg(sc, 0x0e, 0x0000003f);
                   1894:        (void)uath_write_reg(sc, 0x10, 0x00000001);
                   1895:        (void)uath_write_reg(sc, 0x06, 0x0000001e);
                   1896:
                   1897:        /*
                   1898:         * Queue Rx data xfers.
                   1899:         */
                   1900:        for (i = 0; i < UATH_RX_DATA_LIST_COUNT; i++) {
                   1901:                struct uath_rx_data *data = SLIST_FIRST(&sc->rx_freelist);
                   1902:
                   1903:                usbd_setup_xfer(data->xfer, sc->data_rx_pipe, data, data->buf,
                   1904:                    sc->rxbufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
                   1905:                    USBD_NO_TIMEOUT, uath_data_rxeof);
                   1906:                error = usbd_transfer(data->xfer);
                   1907:                if (error != USBD_IN_PROGRESS && error != 0) {
                   1908:                        printf("%s: could not queue Rx transfer\n",
                   1909:                            sc->sc_dev.dv_xname);
                   1910:                        goto fail;
                   1911:                }
                   1912:                SLIST_REMOVE_HEAD(&sc->rx_freelist, next);
                   1913:        }
                   1914:
                   1915:        error = uath_cmd_read(sc, UATH_CMD_07, 0, NULL, &val,
                   1916:            UATH_CMD_FLAG_MAGIC);
                   1917:        if (error != 0) {
                   1918:                printf("%s: could not send read command 07h\n",
                   1919:                    sc->sc_dev.dv_xname);
                   1920:                goto fail;
                   1921:        }
                   1922:        DPRINTF(("command 07h return code: %x\n", betoh32(val)));
                   1923:
                   1924:        /* set default channel */
                   1925:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                   1926:        if ((error = uath_set_chan(sc, ic->ic_bss->ni_chan)) != 0) {
                   1927:                printf("%s: could not set channel\n", sc->sc_dev.dv_xname);
                   1928:                goto fail;
                   1929:        }
                   1930:
                   1931:        if ((error = uath_wme_init(sc)) != 0) {
                   1932:                printf("%s: could not setup WME parameters\n",
                   1933:                    sc->sc_dev.dv_xname);
                   1934:                goto fail;
                   1935:        }
                   1936:
                   1937:        /* init MAC registers */
                   1938:        (void)uath_write_reg(sc, 0x19, 0x00000000);
                   1939:        (void)uath_write_reg(sc, 0x1a, 0x0000003c);
                   1940:        (void)uath_write_reg(sc, 0x1b, 0x0000003c);
                   1941:        (void)uath_write_reg(sc, 0x1c, 0x00000000);
                   1942:        (void)uath_write_reg(sc, 0x1e, 0x00000000);
                   1943:        (void)uath_write_reg(sc, 0x1f, 0x00000003);
                   1944:        (void)uath_write_reg(sc, 0x0c, 0x00000000);
                   1945:        (void)uath_write_reg(sc, 0x0f, 0x00000002);
                   1946:        (void)uath_write_reg(sc, 0x0a, 0x00000007);     /* XXX retry? */
                   1947:        (void)uath_write_reg(sc, 0x09, ic->ic_rtsthreshold);
                   1948:
                   1949:        val = htobe32(4);
                   1950:        (void)uath_cmd_write(sc, UATH_CMD_27, &val, sizeof val, 0);
                   1951:        (void)uath_cmd_write(sc, UATH_CMD_27, &val, sizeof val, 0);
                   1952:        (void)uath_cmd_write(sc, UATH_CMD_1B, NULL, 0, 0);
                   1953:
                   1954:        if ((error = uath_set_keys(sc)) != 0) {
                   1955:                printf("%s: could not set crypto keys\n",
                   1956:                    sc->sc_dev.dv_xname);
                   1957:                goto fail;
                   1958:        }
                   1959:
                   1960:        /* enable Rx */
                   1961:        (void)uath_set_rxfilter(sc, 0x0000, 4);
                   1962:        (void)uath_set_rxfilter(sc, 0x0817, 1);
                   1963:
                   1964:        cmd31.magic1 = htobe32(0xffffffff);
                   1965:        cmd31.magic2 = htobe32(0xffffffff);
                   1966:        (void)uath_cmd_write(sc, UATH_CMD_31, &cmd31, sizeof cmd31, 0);
                   1967:
                   1968:        ifp->if_flags &= ~IFF_OACTIVE;
                   1969:        ifp->if_flags |= IFF_RUNNING;
                   1970:
                   1971:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
                   1972:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   1973:        else
                   1974:                ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   1975:
                   1976:        return 0;
                   1977:
                   1978: fail:  uath_stop(ifp, 1);
                   1979:        return error;
                   1980: }
                   1981:
                   1982: void
                   1983: uath_stop(struct ifnet *ifp, int disable)
                   1984: {
                   1985:        struct uath_softc *sc = ifp->if_softc;
                   1986:        struct ieee80211com *ic = &sc->sc_ic;
                   1987:        uint32_t val;
                   1988:        int s;
                   1989:
                   1990:        s = splusb();
                   1991:
                   1992:        sc->sc_tx_timer = 0;
                   1993:        ifp->if_timer = 0;
                   1994:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1995:
                   1996:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);  /* free all nodes */
                   1997:
                   1998:        val = htobe32(0);
                   1999:        (void)uath_cmd_write(sc, UATH_CMD_SET_STATE, &val, sizeof val, 0);
                   2000:        (void)uath_cmd_write(sc, UATH_CMD_RESET, NULL, 0, 0);
                   2001:
                   2002:        val = htobe32(0);
                   2003:        (void)uath_cmd_write(sc, UATH_CMD_15, &val, sizeof val, 0);
                   2004:
                   2005: #if 0
                   2006:        (void)uath_cmd_read(sc, UATH_CMD_SHUTDOWN, NULL, 0, NULL,
                   2007:            UATH_CMD_FLAG_MAGIC);
                   2008: #endif
                   2009:
                   2010:        /* abort any pending transfers */
                   2011:        usbd_abort_pipe(sc->data_tx_pipe);
                   2012:        usbd_abort_pipe(sc->data_rx_pipe);
                   2013:        usbd_abort_pipe(sc->cmd_tx_pipe);
                   2014:
                   2015:        splx(s);
                   2016: }
                   2017:
                   2018: /*
                   2019:  * Load the MIPS R4000 microcode into the device.  Once the image is loaded,
                   2020:  * the device will detach itself from the bus and reattach later with a new
                   2021:  * product Id (a la ezusb).  XXX this could also be implemented in userland
                   2022:  * through /dev/ugen.
                   2023:  */
                   2024: int
                   2025: uath_loadfirmware(struct uath_softc *sc, const u_char *fw, int len)
                   2026: {
                   2027:        usbd_xfer_handle ctlxfer, txxfer, rxxfer;
                   2028:        struct uath_fwblock *txblock, *rxblock;
                   2029:        uint8_t *txdata;
                   2030:        int error = 0;
                   2031:
                   2032:        if ((ctlxfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
                   2033:                printf("%s: could not allocate Tx control xfer\n",
                   2034:                    sc->sc_dev.dv_xname);
                   2035:                error = USBD_NOMEM;
                   2036:                goto fail1;
                   2037:        }
                   2038:        txblock = usbd_alloc_buffer(ctlxfer, sizeof (struct uath_fwblock));
                   2039:        if (txblock == NULL) {
                   2040:                printf("%s: could not allocate Tx control block\n",
                   2041:                    sc->sc_dev.dv_xname);
                   2042:                error = USBD_NOMEM;
                   2043:                goto fail2;
                   2044:        }
                   2045:
                   2046:        if ((txxfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
                   2047:                printf("%s: could not allocate Tx xfer\n",
                   2048:                    sc->sc_dev.dv_xname);
                   2049:                error = USBD_NOMEM;
                   2050:                goto fail2;
                   2051:        }
                   2052:        txdata = usbd_alloc_buffer(txxfer, UATH_MAX_FWBLOCK_SIZE);
                   2053:        if (txdata == NULL) {
                   2054:                printf("%s: could not allocate Tx buffer\n",
                   2055:                    sc->sc_dev.dv_xname);
                   2056:                error = USBD_NOMEM;
                   2057:                goto fail3;
                   2058:        }
                   2059:
                   2060:        if ((rxxfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
                   2061:                printf("%s: could not allocate Rx control xfer\n",
                   2062:                    sc->sc_dev.dv_xname);
                   2063:                error = USBD_NOMEM;
                   2064:                goto fail3;
                   2065:        }
                   2066:        rxblock = usbd_alloc_buffer(rxxfer, sizeof (struct uath_fwblock));
                   2067:        if (rxblock == NULL) {
                   2068:                printf("%s: could not allocate Rx control block\n",
                   2069:                    sc->sc_dev.dv_xname);
                   2070:                error = USBD_NOMEM;
                   2071:                goto fail4;
                   2072:        }
                   2073:
                   2074:        bzero(txblock, sizeof (struct uath_fwblock));
                   2075:        txblock->flags = htobe32(UATH_WRITE_BLOCK);
                   2076:        txblock->total = htobe32(len);
                   2077:
                   2078:        while (len > 0) {
                   2079:                int mlen = min(len, UATH_MAX_FWBLOCK_SIZE);
                   2080:
                   2081:                txblock->remain = htobe32(len - mlen);
                   2082:                txblock->len = htobe32(mlen);
                   2083:
                   2084:                DPRINTF(("sending firmware block: %d bytes remaining\n",
                   2085:                    len - mlen));
                   2086:
                   2087:                /* send firmware block meta-data */
                   2088:                usbd_setup_xfer(ctlxfer, sc->cmd_tx_pipe, sc, txblock,
                   2089:                    sizeof (struct uath_fwblock), USBD_NO_COPY,
                   2090:                    UATH_CMD_TIMEOUT, NULL);
                   2091:                if ((error = usbd_sync_transfer(ctlxfer)) != 0) {
                   2092:                        printf("%s: could not send firmware block info\n",
                   2093:                            sc->sc_dev.dv_xname);
                   2094:                        break;
                   2095:                }
                   2096:
                   2097:                /* send firmware block data */
                   2098:                bcopy(fw, txdata, mlen);
                   2099:                usbd_setup_xfer(txxfer, sc->data_tx_pipe, sc, txdata, mlen,
                   2100:                    USBD_NO_COPY, UATH_DATA_TIMEOUT, NULL);
                   2101:                if ((error = usbd_sync_transfer(txxfer)) != 0) {
                   2102:                        printf("%s: could not send firmware block data\n",
                   2103:                            sc->sc_dev.dv_xname);
                   2104:                        break;
                   2105:                }
                   2106:
                   2107:                /* wait for ack from firmware */
                   2108:                usbd_setup_xfer(rxxfer, sc->cmd_rx_pipe, sc, rxblock,
                   2109:                    sizeof (struct uath_fwblock), USBD_SHORT_XFER_OK |
                   2110:                    USBD_NO_COPY, UATH_CMD_TIMEOUT, NULL);
                   2111:                if ((error = usbd_sync_transfer(rxxfer)) != 0) {
                   2112:                        printf("%s: could not read firmware answer\n",
                   2113:                            sc->sc_dev.dv_xname);
                   2114:                        break;
                   2115:                }
                   2116:
                   2117:                DPRINTFN(2, ("rxblock flags=0x%x total=%d\n",
                   2118:                    betoh32(rxblock->flags), betoh32(rxblock->rxtotal)));
                   2119:                fw += mlen;
                   2120:                len -= mlen;
                   2121:        }
                   2122:
                   2123: fail4: usbd_free_xfer(rxxfer);
                   2124: fail3: usbd_free_xfer(txxfer);
                   2125: fail2: usbd_free_xfer(ctlxfer);
                   2126: fail1: return error;
                   2127: }
                   2128:
                   2129: int
                   2130: uath_activate(struct device *self, enum devact act)
                   2131: {
                   2132:        switch (act) {
                   2133:        case DVACT_ACTIVATE:
                   2134:                break;
                   2135:
                   2136:        case DVACT_DEACTIVATE:
                   2137:                break;
                   2138:        }
                   2139:        return 0;
                   2140: }

CVSweb