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

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

1.1       nbrk        1: /*     $OpenBSD: if_zyd.c,v 1.58 2007/06/14 10:11:15 mbalmer Exp $     */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
                      5:  * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
                      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:  * ZyDAS ZD1211/ZD1211B USB WLAN driver.
                     22:  */
                     23:
                     24: #include "bpfilter.h"
                     25:
                     26: #include <sys/param.h>
                     27: #include <sys/sockio.h>
                     28: #include <sys/proc.h>
                     29: #include <sys/mbuf.h>
                     30: #include <sys/kernel.h>
                     31: #include <sys/socket.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/malloc.h>
                     34: #include <sys/timeout.h>
                     35: #include <sys/conf.h>
                     36: #include <sys/device.h>
                     37:
                     38: #include <machine/bus.h>
                     39: #include <machine/endian.h>
                     40:
                     41: #if NBPFILTER > 0
                     42: #include <net/bpf.h>
                     43: #endif
                     44: #include <net/if.h>
                     45: #include <net/if_arp.h>
                     46: #include <net/if_dl.h>
                     47: #include <net/if_media.h>
                     48: #include <net/if_types.h>
                     49:
                     50: #ifdef INET
                     51: #include <netinet/in.h>
                     52: #include <netinet/in_systm.h>
                     53: #include <netinet/in_var.h>
                     54: #include <netinet/if_ether.h>
                     55: #include <netinet/ip.h>
                     56: #endif
                     57:
                     58: #include <net80211/ieee80211_var.h>
                     59: #include <net80211/ieee80211_amrr.h>
                     60: #include <net80211/ieee80211_radiotap.h>
                     61:
                     62: #include <dev/usb/usb.h>
                     63: #include <dev/usb/usbdi.h>
                     64: #include <dev/usb/usbdi_util.h>
                     65: #include <dev/usb/usbdevs.h>
                     66:
                     67: #include <dev/usb/if_zydreg.h>
                     68:
                     69: #ifdef USB_DEBUG
                     70: #define ZYD_DEBUG
                     71: #endif
                     72:
                     73: #ifdef ZYD_DEBUG
                     74: #define DPRINTF(x)     do { if (zyddebug > 0) printf x; } while (0)
                     75: #define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0)
                     76: int zyddebug = 0;
                     77: #else
                     78: #define DPRINTF(x)
                     79: #define DPRINTFN(n, x)
                     80: #endif
                     81:
                     82: static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
                     83: static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
                     84:
                     85: /* various supported device vendors/products */
                     86: #define ZYD_ZD1211_DEV(v, p)   \
                     87:        { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 }
                     88: #define ZYD_ZD1211B_DEV(v, p)  \
                     89:        { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B }
                     90: static const struct zyd_type {
                     91:        struct usb_devno        dev;
                     92:        uint8_t                 rev;
                     93: #define ZYD_ZD1211     0
                     94: #define ZYD_ZD1211B    1
                     95: } zyd_devs[] = {
                     96:        ZYD_ZD1211_DEV(3COM2,           3CRUSB10075),
                     97:        ZYD_ZD1211_DEV(ABOCOM,          WL54),
                     98:        ZYD_ZD1211_DEV(ASUS,            WL159G),
                     99:        ZYD_ZD1211_DEV(CYBERTAN,        TG54USB),
                    100:        ZYD_ZD1211_DEV(DRAYTEK,         VIGOR550),
                    101:        ZYD_ZD1211_DEV(PLANEX2,         GWUS54GZL),
                    102:        ZYD_ZD1211_DEV(PLANEX3,         GWUS54MINI),
                    103:        ZYD_ZD1211_DEV(SAGEM,           XG760A),
                    104:        ZYD_ZD1211_DEV(SENAO,           NUB8301),
                    105:        ZYD_ZD1211_DEV(SITECOMEU,       WL113),
                    106:        ZYD_ZD1211_DEV(SWEEX,           ZD1211),
                    107:        ZYD_ZD1211_DEV(TEKRAM,          QUICKWLAN),
                    108:        ZYD_ZD1211_DEV(TEKRAM,          ZD1211_1),
                    109:        ZYD_ZD1211_DEV(TEKRAM,          ZD1211_2),
                    110:        ZYD_ZD1211_DEV(TWINMOS,         G240),
                    111:        ZYD_ZD1211_DEV(UMEDIA,          ALL0298V2),
                    112:        ZYD_ZD1211_DEV(UMEDIA,          TEW429UB_A),
                    113:        ZYD_ZD1211_DEV(UMEDIA,          TEW429UB),
                    114:        ZYD_ZD1211_DEV(WISTRONNEWEB,    UR055G),
                    115:        ZYD_ZD1211_DEV(ZCOM,            ZD1211),
                    116:        ZYD_ZD1211_DEV(ZYDAS,           ZD1211),
                    117:        ZYD_ZD1211_DEV(ZYXEL,           AG225H),
                    118:        ZYD_ZD1211_DEV(ZYXEL,           ZYAIRG220),
                    119:
                    120:        ZYD_ZD1211B_DEV(ACCTON,         SMCWUSBG),
                    121:        ZYD_ZD1211B_DEV(ACCTON,         ZD1211B),
                    122:        ZYD_ZD1211B_DEV(ASUS,           A9T_WIFI),
                    123:        ZYD_ZD1211B_DEV(BELKIN,         F5D7050C),
                    124:        ZYD_ZD1211B_DEV(BELKIN,         ZD1211B),
                    125:        ZYD_ZD1211B_DEV(CISCOLINKSYS,   WUSBF54G),
                    126:        ZYD_ZD1211B_DEV(FIBERLINE,      WL430U),
                    127:        ZYD_ZD1211B_DEV(MELCO,          KG54L),
                    128:        ZYD_ZD1211B_DEV(PHILIPS,        SNU5600),
                    129:        ZYD_ZD1211B_DEV(SAGEM,          XG76NA),
                    130:        ZYD_ZD1211B_DEV(SITECOMEU,      ZD1211B),
                    131:        ZYD_ZD1211B_DEV(UMEDIA,         TEW429UBC1),
                    132:        ZYD_ZD1211B_DEV(UNKNOWN1,       ZD1211B_1),
                    133:        ZYD_ZD1211B_DEV(UNKNOWN1,       ZD1211B_2),
                    134:        ZYD_ZD1211B_DEV(UNKNOWN2,       ZD1211B),
                    135:        ZYD_ZD1211B_DEV(UNKNOWN3,       ZD1211B),
                    136:        ZYD_ZD1211B_DEV(USR,            USR5423),
                    137:        ZYD_ZD1211B_DEV(VTECH,          ZD1211B),
                    138:        ZYD_ZD1211B_DEV(ZCOM,           ZD1211B),
                    139:        ZYD_ZD1211B_DEV(ZYDAS,          ZD1211B),
                    140:        ZYD_ZD1211B_DEV(ZYXEL,          M202),
                    141:        ZYD_ZD1211B_DEV(ZYXEL,          G220V2),
                    142: };
                    143: #define zyd_lookup(v, p)       \
                    144:        ((const struct zyd_type *)usb_lookup(zyd_devs, v, p))
                    145:
                    146: int zyd_match(struct device *, void *, void *);
                    147: void zyd_attach(struct device *, struct device *, void *);
                    148: int zyd_detach(struct device *, int);
                    149: int zyd_activate(struct device *, enum devact);
                    150:
                    151: struct cfdriver zyd_cd = {
                    152:        NULL, "zyd", DV_IFNET
                    153: };
                    154:
                    155: const struct cfattach zyd_ca = {
                    156:        sizeof(struct zyd_softc),
                    157:        zyd_match,
                    158:        zyd_attach,
                    159:        zyd_detach,
                    160:        zyd_activate,
                    161: };
                    162:
                    163: void           zyd_attachhook(void *);
                    164: int            zyd_complete_attach(struct zyd_softc *);
                    165: int            zyd_open_pipes(struct zyd_softc *);
                    166: void           zyd_close_pipes(struct zyd_softc *);
                    167: int            zyd_alloc_tx_list(struct zyd_softc *);
                    168: void           zyd_free_tx_list(struct zyd_softc *);
                    169: int            zyd_alloc_rx_list(struct zyd_softc *);
                    170: void           zyd_free_rx_list(struct zyd_softc *);
                    171: struct         ieee80211_node *zyd_node_alloc(struct ieee80211com *);
                    172: int            zyd_media_change(struct ifnet *);
                    173: void           zyd_next_scan(void *);
                    174: void           zyd_task(void *);
                    175: int            zyd_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    176: int            zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
                    177:                    void *, int, u_int);
                    178: int            zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
                    179: int            zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
                    180: int            zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
                    181: int            zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
                    182: int            zyd_rfwrite(struct zyd_softc *, uint32_t);
                    183: void           zyd_lock_phy(struct zyd_softc *);
                    184: void           zyd_unlock_phy(struct zyd_softc *);
                    185: int            zyd_rfmd_init(struct zyd_rf *);
                    186: int            zyd_rfmd_switch_radio(struct zyd_rf *, int);
                    187: int            zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
                    188: int            zyd_al2230_init(struct zyd_rf *);
                    189: int            zyd_al2230_switch_radio(struct zyd_rf *, int);
                    190: int            zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
                    191: int            zyd_al2230_init_b(struct zyd_rf *);
                    192: int            zyd_al7230B_init(struct zyd_rf *);
                    193: int            zyd_al7230B_switch_radio(struct zyd_rf *, int);
                    194: int            zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
                    195: int            zyd_al2210_init(struct zyd_rf *);
                    196: int            zyd_al2210_switch_radio(struct zyd_rf *, int);
                    197: int            zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
                    198: int            zyd_gct_init(struct zyd_rf *);
                    199: int            zyd_gct_switch_radio(struct zyd_rf *, int);
                    200: int            zyd_gct_set_channel(struct zyd_rf *, uint8_t);
                    201: int            zyd_maxim_init(struct zyd_rf *);
                    202: int            zyd_maxim_switch_radio(struct zyd_rf *, int);
                    203: int            zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
                    204: int            zyd_maxim2_init(struct zyd_rf *);
                    205: int            zyd_maxim2_switch_radio(struct zyd_rf *, int);
                    206: int            zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
                    207: int            zyd_rf_attach(struct zyd_softc *, uint8_t);
                    208: const char     *zyd_rf_name(uint8_t);
                    209: int            zyd_hw_init(struct zyd_softc *);
                    210: int            zyd_read_eeprom(struct zyd_softc *);
                    211: int            zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
                    212: int            zyd_set_bssid(struct zyd_softc *, const uint8_t *);
                    213: int            zyd_switch_radio(struct zyd_softc *, int);
                    214: void           zyd_set_led(struct zyd_softc *, int, int);
                    215: int            zyd_set_rxfilter(struct zyd_softc *);
                    216: void           zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
                    217: int            zyd_set_beacon_interval(struct zyd_softc *, int);
                    218: uint8_t                zyd_plcp_signal(int);
                    219: void           zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    220: void           zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t);
                    221: void           zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    222: void           zyd_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    223: int            zyd_tx_data(struct zyd_softc *, struct mbuf *,
                    224:                    struct ieee80211_node *);
                    225: void           zyd_start(struct ifnet *);
                    226: void           zyd_watchdog(struct ifnet *);
                    227: int            zyd_ioctl(struct ifnet *, u_long, caddr_t);
                    228: int            zyd_init(struct ifnet *);
                    229: void           zyd_stop(struct ifnet *, int);
                    230: int            zyd_loadfirmware(struct zyd_softc *, u_char *, size_t);
                    231: void           zyd_iter_func(void *, struct ieee80211_node *);
                    232: void           zyd_amrr_timeout(void *);
                    233: void           zyd_newassoc(struct ieee80211com *, struct ieee80211_node *,
                    234:                    int);
                    235:
                    236: int
                    237: zyd_match(struct device *parent, void *match, void *aux)
                    238: {
                    239:        struct usb_attach_arg *uaa = aux;
                    240:
                    241:        if (!uaa->iface)
                    242:                return UMATCH_NONE;
                    243:
                    244:        return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ?
                    245:            UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
                    246: }
                    247:
                    248: void
                    249: zyd_attachhook(void *xsc)
                    250: {
                    251:        struct zyd_softc *sc = xsc;
                    252:        const char *fwname;
                    253:        u_char *fw;
                    254:        size_t size;
                    255:        int error;
                    256:
                    257:        fwname = (sc->mac_rev == ZYD_ZD1211) ? "zd1211" : "zd1211b";
                    258:        if ((error = loadfirmware(fwname, &fw, &size)) != 0) {
                    259:                printf("%s: could not read firmware file %s (error=%d)\n",
                    260:                    sc->sc_dev.dv_xname, fwname, error);
                    261:                return;
                    262:        }
                    263:
                    264:        error = zyd_loadfirmware(sc, fw, size);
                    265:        free(fw, M_DEVBUF);
                    266:        if (error != 0) {
                    267:                printf("%s: could not load firmware (error=%d)\n",
                    268:                    sc->sc_dev.dv_xname, error);
                    269:                return;
                    270:        }
                    271:
                    272:        /* complete the attach process */
                    273:        if (zyd_complete_attach(sc) == 0)
                    274:                sc->attached = 1;
                    275: }
                    276:
                    277: void
                    278: zyd_attach(struct device *parent, struct device *self, void *aux)
                    279: {
                    280:        struct zyd_softc *sc = (struct zyd_softc *)self;
                    281:        struct usb_attach_arg *uaa = aux;
                    282:        char *devinfop;
                    283:        usb_device_descriptor_t* ddesc;
                    284:
                    285:        sc->sc_udev = uaa->device;
                    286:
                    287:        devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
                    288:        printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
                    289:        usbd_devinfo_free(devinfop);
                    290:
                    291:        sc->mac_rev = zyd_lookup(uaa->vendor, uaa->product)->rev;
                    292:
                    293:        ddesc = usbd_get_device_descriptor(sc->sc_udev);
                    294:        if (UGETW(ddesc->bcdDevice) < 0x4330) {
                    295:                printf("%s: device version mismatch: 0x%x "
                    296:                    "(only >= 43.30 supported)\n", sc->sc_dev.dv_xname,
                    297:                    UGETW(ddesc->bcdDevice));
                    298:                return;
                    299:        }
                    300:
                    301:        if (rootvp == NULL)
                    302:                mountroothook_establish(zyd_attachhook, sc);
                    303:        else
                    304:                zyd_attachhook(sc);
                    305: }
                    306:
                    307: int
                    308: zyd_complete_attach(struct zyd_softc *sc)
                    309: {
                    310:        struct ieee80211com *ic = &sc->sc_ic;
                    311:        struct ifnet *ifp = &ic->ic_if;
                    312:        usbd_status error;
                    313:        int i;
                    314:
                    315:        usb_init_task(&sc->sc_task, zyd_task, sc);
                    316:        timeout_set(&sc->scan_to, zyd_next_scan, sc);
                    317:
                    318:        sc->amrr.amrr_min_success_threshold =  1;
                    319:        sc->amrr.amrr_max_success_threshold = 10;
                    320:        timeout_set(&sc->amrr_to, zyd_amrr_timeout, sc);
                    321:
                    322:        error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1);
                    323:        if (error != 0) {
                    324:                printf("%s: setting config no failed\n",
                    325:                    sc->sc_dev.dv_xname);
                    326:                goto fail;
                    327:        }
                    328:
                    329:        error = usbd_device2interface_handle(sc->sc_udev, ZYD_IFACE_INDEX,
                    330:            &sc->sc_iface);
                    331:        if (error != 0) {
                    332:                printf("%s: getting interface handle failed\n",
                    333:                    sc->sc_dev.dv_xname);
                    334:                goto fail;
                    335:        }
                    336:
                    337:        if ((error = zyd_open_pipes(sc)) != 0) {
                    338:                printf("%s: could not open pipes\n", sc->sc_dev.dv_xname);
                    339:                goto fail;
                    340:        }
                    341:
                    342:        if ((error = zyd_read_eeprom(sc)) != 0) {
                    343:                printf("%s: could not read EEPROM\n", sc->sc_dev.dv_xname);
                    344:                goto fail;
                    345:        }
                    346:
                    347:        if ((error = zyd_rf_attach(sc, sc->rf_rev)) != 0) {
                    348:                printf("%s: could not attach RF\n", sc->sc_dev.dv_xname);
                    349:                goto fail;
                    350:        }
                    351:
                    352:        if ((error = zyd_hw_init(sc)) != 0) {
                    353:                printf("%s: hardware initialization failed\n",
                    354:                    sc->sc_dev.dv_xname);
                    355:                goto fail;
                    356:        }
                    357:
                    358:        printf("%s: HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %s\n",
                    359:            sc->sc_dev.dv_xname, (sc->mac_rev == ZYD_ZD1211) ? "": "B",
                    360:            sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev),
                    361:            sc->pa_rev, ether_sprintf(ic->ic_myaddr));
                    362:
                    363:        ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
                    364:        ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
                    365:        ic->ic_state = IEEE80211_S_INIT;
                    366:
                    367:        /* set device capabilities */
                    368:        ic->ic_caps =
                    369:            IEEE80211_C_MONITOR |       /* monitor mode supported */
                    370:            IEEE80211_C_TXPMGT |        /* tx power management */
                    371:            IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
                    372:            IEEE80211_C_WEP;            /* s/w WEP */
                    373:
                    374:        /* set supported .11b and .11g rates */
                    375:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    376:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
                    377:
                    378:        /* set supported .11b and .11g channels (1 through 14) */
                    379:        for (i = 1; i <= 14; i++) {
                    380:                ic->ic_channels[i].ic_freq =
                    381:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
                    382:                ic->ic_channels[i].ic_flags =
                    383:                    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
                    384:                    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
                    385:        }
                    386:
                    387:        ifp->if_softc = sc;
                    388:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    389:        ifp->if_init = zyd_init;
                    390:        ifp->if_ioctl = zyd_ioctl;
                    391:        ifp->if_start = zyd_start;
                    392:        ifp->if_watchdog = zyd_watchdog;
                    393:        IFQ_SET_READY(&ifp->if_snd);
                    394:        memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
                    395:
                    396:        if_attach(ifp);
                    397:        ieee80211_ifattach(ifp);
                    398:        ic->ic_node_alloc = zyd_node_alloc;
                    399:        ic->ic_newassoc = zyd_newassoc;
                    400:
                    401:        /* override state transition machine */
                    402:        sc->sc_newstate = ic->ic_newstate;
                    403:        ic->ic_newstate = zyd_newstate;
                    404:        ieee80211_media_init(ifp, zyd_media_change, ieee80211_media_status);
                    405:
                    406: #if NBPFILTER > 0
                    407:        bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
                    408:            sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
                    409:
                    410:        sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
                    411:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    412:        sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
                    413:
                    414:        sc->sc_txtap_len = sizeof sc->sc_txtapu;
                    415:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    416:        sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
                    417: #endif
                    418:
                    419:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    420:            &sc->sc_dev);
                    421:
                    422: fail:  return error;
                    423: }
                    424:
                    425: int
                    426: zyd_detach(struct device *self, int flags)
                    427: {
                    428:        struct zyd_softc *sc = (struct zyd_softc *)self;
                    429:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                    430:        int s;
                    431:
                    432:        s = splusb();
                    433:
                    434:        usb_rem_task(sc->sc_udev, &sc->sc_task);
                    435:        timeout_del(&sc->scan_to);
                    436:        timeout_del(&sc->amrr_to);
                    437:
                    438:        zyd_close_pipes(sc);
                    439:
                    440:        if (!sc->attached) {
                    441:                splx(s);
                    442:                return 0;
                    443:        }
                    444:
                    445:        ieee80211_ifdetach(ifp);
                    446:        if_detach(ifp);
                    447:
                    448:        zyd_free_rx_list(sc);
                    449:        zyd_free_tx_list(sc);
                    450:
                    451:        sc->attached = 0;
                    452:
                    453:        splx(s);
                    454:
                    455:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    456:            &sc->sc_dev);
                    457:
                    458:        return 0;
                    459: }
                    460:
                    461: int
                    462: zyd_open_pipes(struct zyd_softc *sc)
                    463: {
                    464:        usb_endpoint_descriptor_t *edesc;
                    465:        int isize;
                    466:        usbd_status error;
                    467:
                    468:        /* interrupt in */
                    469:        edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83);
                    470:        if (edesc == NULL)
                    471:                return EINVAL;
                    472:
                    473:        isize = UGETW(edesc->wMaxPacketSize);
                    474:        if (isize == 0) /* should not happen */
                    475:                return EINVAL;
                    476:
                    477:        sc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT);
                    478:        if (sc->ibuf == NULL)
                    479:                return ENOMEM;
                    480:
                    481:        error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK,
                    482:            &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, isize, zyd_intr,
                    483:            USBD_DEFAULT_INTERVAL);
                    484:        if (error != 0) {
                    485:                printf("%s: open rx intr pipe failed: %s\n",
                    486:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    487:                goto fail;
                    488:        }
                    489:
                    490:        /* interrupt out (not necessarily an interrupt pipe) */
                    491:        error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE,
                    492:            &sc->zyd_ep[ZYD_ENDPT_IOUT]);
                    493:        if (error != 0) {
                    494:                printf("%s: open tx intr pipe failed: %s\n",
                    495:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    496:                goto fail;
                    497:        }
                    498:
                    499:        /* bulk in */
                    500:        error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE,
                    501:            &sc->zyd_ep[ZYD_ENDPT_BIN]);
                    502:        if (error != 0) {
                    503:                printf("%s: open rx pipe failed: %s\n",
                    504:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    505:                goto fail;
                    506:        }
                    507:
                    508:        /* bulk out */
                    509:        error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
                    510:            &sc->zyd_ep[ZYD_ENDPT_BOUT]);
                    511:        if (error != 0) {
                    512:                printf("%s: open tx pipe failed: %s\n",
                    513:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    514:                goto fail;
                    515:        }
                    516:
                    517:        return 0;
                    518:
                    519: fail:  zyd_close_pipes(sc);
                    520:        return error;
                    521: }
                    522:
                    523: void
                    524: zyd_close_pipes(struct zyd_softc *sc)
                    525: {
                    526:        int i;
                    527:
                    528:        for (i = 0; i < ZYD_ENDPT_CNT; i++) {
                    529:                if (sc->zyd_ep[i] != NULL) {
                    530:                        usbd_abort_pipe(sc->zyd_ep[i]);
                    531:                        usbd_close_pipe(sc->zyd_ep[i]);
                    532:                        sc->zyd_ep[i] = NULL;
                    533:                }
                    534:        }
                    535:        if (sc->ibuf != NULL) {
                    536:                free(sc->ibuf, M_USBDEV);
                    537:                sc->ibuf = NULL;
                    538:        }
                    539: }
                    540:
                    541: int
                    542: zyd_alloc_tx_list(struct zyd_softc *sc)
                    543: {
                    544:        int i, error;
                    545:
                    546:        sc->tx_queued = 0;
                    547:
                    548:        for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
                    549:                struct zyd_tx_data *data = &sc->tx_data[i];
                    550:
                    551:                data->sc = sc;  /* backpointer for callbacks */
                    552:
                    553:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    554:                if (data->xfer == NULL) {
                    555:                        printf("%s: could not allocate tx xfer\n",
                    556:                            sc->sc_dev.dv_xname);
                    557:                        error = ENOMEM;
                    558:                        goto fail;
                    559:                }
                    560:                data->buf = usbd_alloc_buffer(data->xfer, ZYD_MAX_TXBUFSZ);
                    561:                if (data->buf == NULL) {
                    562:                        printf("%s: could not allocate tx buffer\n",
                    563:                            sc->sc_dev.dv_xname);
                    564:                        error = ENOMEM;
                    565:                        goto fail;
                    566:                }
                    567:
                    568:                /* clear Tx descriptor */
                    569:                bzero(data->buf, sizeof (struct zyd_tx_desc));
                    570:        }
                    571:        return 0;
                    572:
                    573: fail:  zyd_free_tx_list(sc);
                    574:        return error;
                    575: }
                    576:
                    577: void
                    578: zyd_free_tx_list(struct zyd_softc *sc)
                    579: {
                    580:        struct ieee80211com *ic = &sc->sc_ic;
                    581:        int i;
                    582:
                    583:        for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
                    584:                struct zyd_tx_data *data = &sc->tx_data[i];
                    585:
                    586:                if (data->xfer != NULL) {
                    587:                        usbd_free_xfer(data->xfer);
                    588:                        data->xfer = NULL;
                    589:                }
                    590:                if (data->ni != NULL) {
                    591:                        ieee80211_release_node(ic, data->ni);
                    592:                        data->ni = NULL;
                    593:                }
                    594:        }
                    595: }
                    596:
                    597: int
                    598: zyd_alloc_rx_list(struct zyd_softc *sc)
                    599: {
                    600:        int i, error;
                    601:
                    602:        for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
                    603:                struct zyd_rx_data *data = &sc->rx_data[i];
                    604:
                    605:                data->sc = sc;  /* backpointer for callbacks */
                    606:
                    607:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    608:                if (data->xfer == NULL) {
                    609:                        printf("%s: could not allocate rx xfer\n",
                    610:                            sc->sc_dev.dv_xname);
                    611:                        error = ENOMEM;
                    612:                        goto fail;
                    613:                }
                    614:                data->buf = usbd_alloc_buffer(data->xfer, ZYX_MAX_RXBUFSZ);
                    615:                if (data->buf == NULL) {
                    616:                        printf("%s: could not allocate rx buffer\n",
                    617:                            sc->sc_dev.dv_xname);
                    618:                        error = ENOMEM;
                    619:                        goto fail;
                    620:                }
                    621:        }
                    622:        return 0;
                    623:
                    624: fail:  zyd_free_rx_list(sc);
                    625:        return error;
                    626: }
                    627:
                    628: void
                    629: zyd_free_rx_list(struct zyd_softc *sc)
                    630: {
                    631:        int i;
                    632:
                    633:        for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
                    634:                struct zyd_rx_data *data = &sc->rx_data[i];
                    635:
                    636:                if (data->xfer != NULL) {
                    637:                        usbd_free_xfer(data->xfer);
                    638:                        data->xfer = NULL;
                    639:                }
                    640:        }
                    641: }
                    642:
                    643: struct ieee80211_node *
                    644: zyd_node_alloc(struct ieee80211com *ic)
                    645: {
                    646:        struct zyd_node *zn;
                    647:
                    648:        zn = malloc(sizeof (struct zyd_node), M_DEVBUF, M_NOWAIT);
                    649:        if (zn != NULL)
                    650:                bzero(zn, sizeof (struct zyd_node));
                    651:        return (struct ieee80211_node *)zn;
                    652: }
                    653:
                    654: int
                    655: zyd_media_change(struct ifnet *ifp)
                    656: {
                    657:        int error;
                    658:
                    659:        error = ieee80211_media_change(ifp);
                    660:        if (error != ENETRESET)
                    661:                return error;
                    662:
                    663:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
                    664:                zyd_init(ifp);
                    665:
                    666:        return 0;
                    667: }
                    668:
                    669: /*
                    670:  * This function is called periodically (every 200ms) during scanning to
                    671:  * switch from one channel to another.
                    672:  */
                    673: void
                    674: zyd_next_scan(void *arg)
                    675: {
                    676:        struct zyd_softc *sc = arg;
                    677:        struct ieee80211com *ic = &sc->sc_ic;
                    678:        struct ifnet *ifp = &ic->ic_if;
                    679:
                    680:        if (ic->ic_state == IEEE80211_S_SCAN)
                    681:                ieee80211_next_scan(ifp);
                    682: }
                    683:
                    684: void
                    685: zyd_task(void *arg)
                    686: {
                    687:        struct zyd_softc *sc = arg;
                    688:        struct ieee80211com *ic = &sc->sc_ic;
                    689:        enum ieee80211_state ostate;
                    690:
                    691:        ostate = ic->ic_state;
                    692:
                    693:        switch (sc->sc_state) {
                    694:        case IEEE80211_S_INIT:
                    695:                if (ostate == IEEE80211_S_RUN) {
                    696:                        /* turn link LED off */
                    697:                        zyd_set_led(sc, ZYD_LED1, 0);
                    698:
                    699:                        /* stop data LED from blinking */
                    700:                        zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 0);
                    701:                }
                    702:                break;
                    703:
                    704:        case IEEE80211_S_SCAN:
                    705:                zyd_set_chan(sc, ic->ic_bss->ni_chan);
                    706:                timeout_add(&sc->scan_to, hz / 5);
                    707:                break;
                    708:
                    709:        case IEEE80211_S_AUTH:
                    710:        case IEEE80211_S_ASSOC:
                    711:                zyd_set_chan(sc, ic->ic_bss->ni_chan);
                    712:                break;
                    713:
                    714:        case IEEE80211_S_RUN:
                    715:        {
                    716:                struct ieee80211_node *ni = ic->ic_bss;
                    717:
                    718:                zyd_set_chan(sc, ni->ni_chan);
                    719:
                    720:                if (ic->ic_opmode != IEEE80211_M_MONITOR) {
                    721:                        /* turn link LED on */
                    722:                        zyd_set_led(sc, ZYD_LED1, 1);
                    723:
                    724:                        /* make data LED blink upon Tx */
                    725:                        zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1);
                    726:
                    727:                        zyd_set_bssid(sc, ni->ni_bssid);
                    728:                }
                    729:
                    730:                if (ic->ic_opmode == IEEE80211_M_STA) {
                    731:                        /* fake a join to init the tx rate */
                    732:                        zyd_newassoc(ic, ni, 1);
                    733:                }
                    734:
                    735:                /* start automatic rate control timer */
                    736:                if (ic->ic_fixed_rate == -1)
                    737:                        timeout_add(&sc->amrr_to, hz);
                    738:
                    739:                break;
                    740:        }
                    741:        }
                    742:
                    743:        sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
                    744: }
                    745:
                    746: int
                    747: zyd_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                    748: {
                    749:        struct zyd_softc *sc = ic->ic_softc;
                    750:
                    751:        usb_rem_task(sc->sc_udev, &sc->sc_task);
                    752:        timeout_del(&sc->scan_to);
                    753:        timeout_del(&sc->amrr_to);
                    754:
                    755:        /* do it in a process context */
                    756:        sc->sc_state = nstate;
                    757:        sc->sc_arg = arg;
                    758:        usb_add_task(sc->sc_udev, &sc->sc_task);
                    759:
                    760:        return 0;
                    761: }
                    762:
                    763: int
                    764: zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
                    765:     void *odata, int olen, u_int flags)
                    766: {
                    767:        usbd_xfer_handle xfer;
                    768:        struct zyd_cmd cmd;
                    769:        uint16_t xferflags;
                    770:        usbd_status error;
                    771:        int s;
                    772:
                    773:        if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL)
                    774:                return ENOMEM;
                    775:
                    776:        cmd.code = htole16(code);
                    777:        bcopy(idata, cmd.data, ilen);
                    778:
                    779:        xferflags = USBD_FORCE_SHORT_XFER;
                    780:        if (!(flags & ZYD_CMD_FLAG_READ))
                    781:                xferflags |= USBD_SYNCHRONOUS;
                    782:        else
                    783:                s = splusb();
                    784:
                    785:        sc->odata = odata;
                    786:        sc->olen  = olen;
                    787:
                    788:        usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_IOUT], 0, &cmd,
                    789:            sizeof (uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL);
                    790:        error = usbd_transfer(xfer);
                    791:        if (error != USBD_IN_PROGRESS && error != 0) {
                    792:                if (flags & ZYD_CMD_FLAG_READ)
                    793:                        splx(s);
                    794:                printf("%s: could not send command (error=%s)\n",
                    795:                    sc->sc_dev.dv_xname, usbd_errstr(error));
                    796:                (void)usbd_free_xfer(xfer);
                    797:                return EIO;
                    798:        }
                    799:        if (!(flags & ZYD_CMD_FLAG_READ)) {
                    800:                (void)usbd_free_xfer(xfer);
                    801:                return 0;       /* write: don't wait for reply */
                    802:        }
                    803:        /* wait at most one second for command reply */
                    804:        error = tsleep(sc, PCATCH, "zydcmd", hz);
                    805:        sc->odata = NULL;       /* in case answer is received too late */
                    806:        splx(s);
                    807:
                    808:        (void)usbd_free_xfer(xfer);
                    809:        return error;
                    810: }
                    811:
                    812: int
                    813: zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
                    814: {
                    815:        struct zyd_pair tmp;
                    816:        int error;
                    817:
                    818:        reg = htole16(reg);
                    819:        error = zyd_cmd(sc, ZYD_CMD_IORD, &reg, sizeof reg, &tmp, sizeof tmp,
                    820:            ZYD_CMD_FLAG_READ);
                    821:        if (error == 0)
                    822:                *val = letoh16(tmp.val);
                    823:        return error;
                    824: }
                    825:
                    826: int
                    827: zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
                    828: {
                    829:        struct zyd_pair tmp[2];
                    830:        uint16_t regs[2];
                    831:        int error;
                    832:
                    833:        regs[0] = htole16(ZYD_REG32_HI(reg));
                    834:        regs[1] = htole16(ZYD_REG32_LO(reg));
                    835:        error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof regs, tmp, sizeof tmp,
                    836:            ZYD_CMD_FLAG_READ);
                    837:        if (error == 0)
                    838:                *val = letoh16(tmp[0].val) << 16 | letoh16(tmp[1].val);
                    839:        return error;
                    840: }
                    841:
                    842: int
                    843: zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
                    844: {
                    845:        struct zyd_pair pair;
                    846:
                    847:        pair.reg = htole16(reg);
                    848:        pair.val = htole16(val);
                    849:
                    850:        return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof pair, NULL, 0, 0);
                    851: }
                    852:
                    853: int
                    854: zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
                    855: {
                    856:        struct zyd_pair pair[2];
                    857:
                    858:        pair[0].reg = htole16(ZYD_REG32_HI(reg));
                    859:        pair[0].val = htole16(val >> 16);
                    860:        pair[1].reg = htole16(ZYD_REG32_LO(reg));
                    861:        pair[1].val = htole16(val & 0xffff);
                    862:
                    863:        return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof pair, NULL, 0, 0);
                    864: }
                    865:
                    866: int
                    867: zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
                    868: {
                    869:        struct zyd_rf *rf = &sc->sc_rf;
                    870:        struct zyd_rfwrite req;
                    871:        uint16_t cr203;
                    872:        int i;
                    873:
                    874:        (void)zyd_read16(sc, ZYD_CR203, &cr203);
                    875:        cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
                    876:
                    877:        req.code  = htole16(2);
                    878:        req.width = htole16(rf->width);
                    879:        for (i = 0; i < rf->width; i++) {
                    880:                req.bit[i] = htole16(cr203);
                    881:                if (val & (1 << (rf->width - 1 - i)))
                    882:                        req.bit[i] |= htole16(ZYD_RF_DATA);
                    883:        }
                    884:        return zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
                    885: }
                    886:
                    887: void
                    888: zyd_lock_phy(struct zyd_softc *sc)
                    889: {
                    890:        uint32_t tmp;
                    891:
                    892:        (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
                    893:        tmp &= ~ZYD_UNLOCK_PHY_REGS;
                    894:        (void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
                    895: }
                    896:
                    897: void
                    898: zyd_unlock_phy(struct zyd_softc *sc)
                    899: {
                    900:        uint32_t tmp;
                    901:
                    902:        (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
                    903:        tmp |= ZYD_UNLOCK_PHY_REGS;
                    904:        (void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
                    905: }
                    906:
                    907: /*
                    908:  * RFMD RF methods.
                    909:  */
                    910: int
                    911: zyd_rfmd_init(struct zyd_rf *rf)
                    912: {
                    913: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                    914:        struct zyd_softc *sc = rf->rf_sc;
                    915:        static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
                    916:        static const uint32_t rfini[] = ZYD_RFMD_RF;
                    917:        int i, error;
                    918:
                    919:        /* init RF-dependent PHY registers */
                    920:        for (i = 0; i < N(phyini); i++) {
                    921:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                    922:                if (error != 0)
                    923:                        return error;
                    924:        }
                    925:
                    926:        /* init RFMD radio */
                    927:        for (i = 0; i < N(rfini); i++) {
                    928:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                    929:                        return error;
                    930:        }
                    931:        return 0;
                    932: #undef N
                    933: }
                    934:
                    935: int
                    936: zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
                    937: {
                    938:        struct zyd_softc *sc = rf->rf_sc;
                    939:
                    940:        (void)zyd_write16(sc, ZYD_CR10, on ? 0x89 : 0x15);
                    941:        (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x81);
                    942:
                    943:        return 0;
                    944: }
                    945:
                    946: int
                    947: zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
                    948: {
                    949:        struct zyd_softc *sc = rf->rf_sc;
                    950:        static const struct {
                    951:                uint32_t        r1, r2;
                    952:        } rfprog[] = ZYD_RFMD_CHANTABLE;
                    953:
                    954:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
                    955:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
                    956:
                    957:        return 0;
                    958: }
                    959:
                    960: /*
                    961:  * AL2230 RF methods.
                    962:  */
                    963: int
                    964: zyd_al2230_init(struct zyd_rf *rf)
                    965: {
                    966: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                    967:        struct zyd_softc *sc = rf->rf_sc;
                    968:        static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
                    969:        static const uint32_t rfini[] = ZYD_AL2230_RF;
                    970:        int i, error;
                    971:
                    972:        /* init RF-dependent PHY registers */
                    973:        for (i = 0; i < N(phyini); i++) {
                    974:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                    975:                if (error != 0)
                    976:                        return error;
                    977:        }
                    978:
                    979:        /* init AL2230 radio */
                    980:        for (i = 0; i < N(rfini); i++) {
                    981:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                    982:                        return error;
                    983:        }
                    984:        return 0;
                    985: #undef N
                    986: }
                    987:
                    988: int
                    989: zyd_al2230_init_b(struct zyd_rf *rf)
                    990: {
                    991: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                    992:        struct zyd_softc *sc = rf->rf_sc;
                    993:        static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
                    994:        static const uint32_t rfini[] = ZYD_AL2230_RF_B;
                    995:        int i, error;
                    996:
                    997:        /* init RF-dependent PHY registers */
                    998:        for (i = 0; i < N(phyini); i++) {
                    999:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1000:                if (error != 0)
                   1001:                        return error;
                   1002:        }
                   1003:
                   1004:        /* init AL2230 radio */
                   1005:        for (i = 0; i < N(rfini); i++) {
                   1006:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1007:                        return error;
                   1008:        }
                   1009:        return 0;
                   1010: #undef N
                   1011: }
                   1012:
                   1013: int
                   1014: zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
                   1015: {
                   1016:        struct zyd_softc *sc = rf->rf_sc;
                   1017:        int on251 = (sc->mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f;
                   1018:
                   1019:        (void)zyd_write16(sc, ZYD_CR11,  on ? 0x00 : 0x04);
                   1020:        (void)zyd_write16(sc, ZYD_CR251, on ? on251 : 0x2f);
                   1021:
                   1022:        return 0;
                   1023: }
                   1024:
                   1025: int
                   1026: zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1027: {
                   1028:        struct zyd_softc *sc = rf->rf_sc;
                   1029:        static const struct {
                   1030:                uint32_t        r1, r2, r3;
                   1031:        } rfprog[] = ZYD_AL2230_CHANTABLE;
                   1032:
                   1033:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
                   1034:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
                   1035:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r3);
                   1036:
                   1037:        (void)zyd_write16(sc, ZYD_CR138, 0x28);
                   1038:        (void)zyd_write16(sc, ZYD_CR203, 0x06);
                   1039:
                   1040:        return 0;
                   1041: }
                   1042:
                   1043: /*
                   1044:  * AL7230B RF methods.
                   1045:  */
                   1046: int
                   1047: zyd_al7230B_init(struct zyd_rf *rf)
                   1048: {
                   1049: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1050:        struct zyd_softc *sc = rf->rf_sc;
                   1051:        static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
                   1052:        static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
                   1053:        static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
                   1054:        static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
                   1055:        static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
                   1056:        int i, error;
                   1057:
                   1058:        /* for AL7230B, PHY and RF need to be initialized in "phases" */
                   1059:
                   1060:        /* init RF-dependent PHY registers, part one */
                   1061:        for (i = 0; i < N(phyini_1); i++) {
                   1062:                error = zyd_write16(sc, phyini_1[i].reg, phyini_1[i].val);
                   1063:                if (error != 0)
                   1064:                        return error;
                   1065:        }
                   1066:        /* init AL7230B radio, part one */
                   1067:        for (i = 0; i < N(rfini_1); i++) {
                   1068:                if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
                   1069:                        return error;
                   1070:        }
                   1071:        /* init RF-dependent PHY registers, part two */
                   1072:        for (i = 0; i < N(phyini_2); i++) {
                   1073:                error = zyd_write16(sc, phyini_2[i].reg, phyini_2[i].val);
                   1074:                if (error != 0)
                   1075:                        return error;
                   1076:        }
                   1077:        /* init AL7230B radio, part two */
                   1078:        for (i = 0; i < N(rfini_2); i++) {
                   1079:                if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
                   1080:                        return error;
                   1081:        }
                   1082:        /* init RF-dependent PHY registers, part three */
                   1083:        for (i = 0; i < N(phyini_3); i++) {
                   1084:                error = zyd_write16(sc, phyini_3[i].reg, phyini_3[i].val);
                   1085:                if (error != 0)
                   1086:                        return error;
                   1087:        }
                   1088:
                   1089:        return 0;
                   1090: #undef N
                   1091: }
                   1092:
                   1093: int
                   1094: zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
                   1095: {
                   1096:        struct zyd_softc *sc = rf->rf_sc;
                   1097:
                   1098:        (void)zyd_write16(sc, ZYD_CR11,  on ? 0x00 : 0x04);
                   1099:        (void)zyd_write16(sc, ZYD_CR251, on ? 0x3f : 0x2f);
                   1100:
                   1101:        return 0;
                   1102: }
                   1103:
                   1104: int
                   1105: zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1106: {
                   1107: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1108:        struct zyd_softc *sc = rf->rf_sc;
                   1109:        static const struct {
                   1110:                uint32_t        r1, r2;
                   1111:        } rfprog[] = ZYD_AL7230B_CHANTABLE;
                   1112:        static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
                   1113:        int i, error;
                   1114:
                   1115:        (void)zyd_write16(sc, ZYD_CR240, 0x57);
                   1116:        (void)zyd_write16(sc, ZYD_CR251, 0x2f);
                   1117:
                   1118:        for (i = 0; i < N(rfsc); i++) {
                   1119:                if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
                   1120:                        return error;
                   1121:        }
                   1122:
                   1123:        (void)zyd_write16(sc, ZYD_CR128, 0x14);
                   1124:        (void)zyd_write16(sc, ZYD_CR129, 0x12);
                   1125:        (void)zyd_write16(sc, ZYD_CR130, 0x10);
                   1126:        (void)zyd_write16(sc, ZYD_CR38,  0x38);
                   1127:        (void)zyd_write16(sc, ZYD_CR136, 0xdf);
                   1128:
                   1129:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
                   1130:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
                   1131:        (void)zyd_rfwrite(sc, 0x3c9000);
                   1132:
                   1133:        (void)zyd_write16(sc, ZYD_CR251, 0x3f);
                   1134:        (void)zyd_write16(sc, ZYD_CR203, 0x06);
                   1135:        (void)zyd_write16(sc, ZYD_CR240, 0x08);
                   1136:
                   1137:        return 0;
                   1138: #undef N
                   1139: }
                   1140:
                   1141: /*
                   1142:  * AL2210 RF methods.
                   1143:  */
                   1144: int
                   1145: zyd_al2210_init(struct zyd_rf *rf)
                   1146: {
                   1147: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1148:        struct zyd_softc *sc = rf->rf_sc;
                   1149:        static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
                   1150:        static const uint32_t rfini[] = ZYD_AL2210_RF;
                   1151:        uint32_t tmp;
                   1152:        int i, error;
                   1153:
                   1154:        (void)zyd_write32(sc, ZYD_CR18, 2);
                   1155:
                   1156:        /* init RF-dependent PHY registers */
                   1157:        for (i = 0; i < N(phyini); i++) {
                   1158:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1159:                if (error != 0)
                   1160:                        return error;
                   1161:        }
                   1162:        /* init AL2210 radio */
                   1163:        for (i = 0; i < N(rfini); i++) {
                   1164:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1165:                        return error;
                   1166:        }
                   1167:        (void)zyd_write16(sc, ZYD_CR47, 0x1e);
                   1168:        (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
                   1169:        (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
                   1170:        (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
                   1171:        (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
                   1172:        (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
                   1173:        (void)zyd_write16(sc, ZYD_CR47, 0x1e);
                   1174:        (void)zyd_write32(sc, ZYD_CR18, 3);
                   1175:
                   1176:        return 0;
                   1177: #undef N
                   1178: }
                   1179:
                   1180: int
                   1181: zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
                   1182: {
                   1183:        /* vendor driver does nothing for this RF chip */
                   1184:
                   1185:        return 0;
                   1186: }
                   1187:
                   1188: int
                   1189: zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1190: {
                   1191:        struct zyd_softc *sc = rf->rf_sc;
                   1192:        static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
                   1193:        uint32_t tmp;
                   1194:
                   1195:        (void)zyd_write32(sc, ZYD_CR18, 2);
                   1196:        (void)zyd_write16(sc, ZYD_CR47, 0x1e);
                   1197:        (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
                   1198:        (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
                   1199:        (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
                   1200:        (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
                   1201:
                   1202:        (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
                   1203:        (void)zyd_write16(sc, ZYD_CR47, 0x1e);
                   1204:
                   1205:        /* actually set the channel */
                   1206:        (void)zyd_rfwrite(sc, rfprog[chan - 1]);
                   1207:
                   1208:        (void)zyd_write32(sc, ZYD_CR18, 3);
                   1209:
                   1210:        return 0;
                   1211: }
                   1212:
                   1213: /*
                   1214:  * GCT RF methods.
                   1215:  */
                   1216: int
                   1217: zyd_gct_init(struct zyd_rf *rf)
                   1218: {
                   1219: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1220:        struct zyd_softc *sc = rf->rf_sc;
                   1221:        static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
                   1222:        static const uint32_t rfini[] = ZYD_GCT_RF;
                   1223:        int i, error;
                   1224:
                   1225:        /* init RF-dependent PHY registers */
                   1226:        for (i = 0; i < N(phyini); i++) {
                   1227:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1228:                if (error != 0)
                   1229:                        return error;
                   1230:        }
                   1231:        /* init cgt radio */
                   1232:        for (i = 0; i < N(rfini); i++) {
                   1233:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1234:                        return error;
                   1235:        }
                   1236:        return 0;
                   1237: #undef N
                   1238: }
                   1239:
                   1240: int
                   1241: zyd_gct_switch_radio(struct zyd_rf *rf, int on)
                   1242: {
                   1243:        /* vendor driver does nothing for this RF chip */
                   1244:
                   1245:        return 0;
                   1246: }
                   1247:
                   1248: int
                   1249: zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1250: {
                   1251:        struct zyd_softc *sc = rf->rf_sc;
                   1252:        static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE;
                   1253:
                   1254:        (void)zyd_rfwrite(sc, 0x1c0000);
                   1255:        (void)zyd_rfwrite(sc, rfprog[chan - 1]);
                   1256:        (void)zyd_rfwrite(sc, 0x1c0008);
                   1257:
                   1258:        return 0;
                   1259: }
                   1260:
                   1261: /*
                   1262:  * Maxim RF methods.
                   1263:  */
                   1264: int
                   1265: zyd_maxim_init(struct zyd_rf *rf)
                   1266: {
                   1267: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1268:        struct zyd_softc *sc = rf->rf_sc;
                   1269:        static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
                   1270:        static const uint32_t rfini[] = ZYD_MAXIM_RF;
                   1271:        uint16_t tmp;
                   1272:        int i, error;
                   1273:
                   1274:        /* init RF-dependent PHY registers */
                   1275:        for (i = 0; i < N(phyini); i++) {
                   1276:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1277:                if (error != 0)
                   1278:                        return error;
                   1279:        }
                   1280:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1281:        (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
                   1282:
                   1283:        /* init maxim radio */
                   1284:        for (i = 0; i < N(rfini); i++) {
                   1285:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1286:                        return error;
                   1287:        }
                   1288:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1289:        (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
                   1290:
                   1291:        return 0;
                   1292: #undef N
                   1293: }
                   1294:
                   1295: int
                   1296: zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
                   1297: {
                   1298:        /* vendor driver does nothing for this RF chip */
                   1299:
                   1300:        return 0;
                   1301: }
                   1302:
                   1303: int
                   1304: zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1305: {
                   1306: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1307:        struct zyd_softc *sc = rf->rf_sc;
                   1308:        static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
                   1309:        static const uint32_t rfini[] = ZYD_MAXIM_RF;
                   1310:        static const struct {
                   1311:                uint32_t        r1, r2;
                   1312:        } rfprog[] = ZYD_MAXIM_CHANTABLE;
                   1313:        uint16_t tmp;
                   1314:        int i, error;
                   1315:
                   1316:        /*
                   1317:         * Do the same as we do when initializing it, except for the channel
                   1318:         * values coming from the two channel tables.
                   1319:         */
                   1320:
                   1321:        /* init RF-dependent PHY registers */
                   1322:        for (i = 0; i < N(phyini); i++) {
                   1323:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1324:                if (error != 0)
                   1325:                        return error;
                   1326:        }
                   1327:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1328:        (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
                   1329:
                   1330:        /* first two values taken from the chantables */
                   1331:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
                   1332:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
                   1333:
                   1334:        /* init maxim radio - skipping the two first values */
                   1335:        for (i = 2; i < N(rfini); i++) {
                   1336:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1337:                        return error;
                   1338:        }
                   1339:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1340:        (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
                   1341:
                   1342:        return 0;
                   1343: #undef N
                   1344: }
                   1345:
                   1346: /*
                   1347:  * Maxim2 RF methods.
                   1348:  */
                   1349: int
                   1350: zyd_maxim2_init(struct zyd_rf *rf)
                   1351: {
                   1352: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1353:        struct zyd_softc *sc = rf->rf_sc;
                   1354:        static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
                   1355:        static const uint32_t rfini[] = ZYD_MAXIM2_RF;
                   1356:        uint16_t tmp;
                   1357:        int i, error;
                   1358:
                   1359:        /* init RF-dependent PHY registers */
                   1360:        for (i = 0; i < N(phyini); i++) {
                   1361:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1362:                if (error != 0)
                   1363:                        return error;
                   1364:        }
                   1365:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1366:        (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
                   1367:
                   1368:        /* init maxim2 radio */
                   1369:        for (i = 0; i < N(rfini); i++) {
                   1370:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1371:                        return error;
                   1372:        }
                   1373:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1374:        (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
                   1375:
                   1376:        return 0;
                   1377: #undef N
                   1378: }
                   1379:
                   1380: int
                   1381: zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
                   1382: {
                   1383:        /* vendor driver does nothing for this RF chip */
                   1384:
                   1385:        return 0;
                   1386: }
                   1387:
                   1388: int
                   1389: zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
                   1390: {
                   1391: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
                   1392:        struct zyd_softc *sc = rf->rf_sc;
                   1393:        static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
                   1394:        static const uint32_t rfini[] = ZYD_MAXIM2_RF;
                   1395:        static const struct {
                   1396:                uint32_t        r1, r2;
                   1397:        } rfprog[] = ZYD_MAXIM2_CHANTABLE;
                   1398:        uint16_t tmp;
                   1399:        int i, error;
                   1400:
                   1401:        /*
                   1402:         * Do the same as we do when initializing it, except for the channel
                   1403:         * values coming from the two channel tables.
                   1404:         */
                   1405:
                   1406:        /* init RF-dependent PHY registers */
                   1407:        for (i = 0; i < N(phyini); i++) {
                   1408:                error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
                   1409:                if (error != 0)
                   1410:                        return error;
                   1411:        }
                   1412:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1413:        (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
                   1414:
                   1415:        /* first two values taken from the chantables */
                   1416:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
                   1417:        (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
                   1418:
                   1419:        /* init maxim2 radio - skipping the two first values */
                   1420:        for (i = 2; i < N(rfini); i++) {
                   1421:                if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
                   1422:                        return error;
                   1423:        }
                   1424:        (void)zyd_read16(sc, ZYD_CR203, &tmp);
                   1425:        (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
                   1426:
                   1427:        return 0;
                   1428: #undef N
                   1429: }
                   1430:
                   1431: int
                   1432: zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
                   1433: {
                   1434:        struct zyd_rf *rf = &sc->sc_rf;
                   1435:
                   1436:        rf->rf_sc = sc;
                   1437:
                   1438:        switch (type) {
                   1439:        case ZYD_RF_RFMD:
                   1440:                rf->init         = zyd_rfmd_init;
                   1441:                rf->switch_radio = zyd_rfmd_switch_radio;
                   1442:                rf->set_channel  = zyd_rfmd_set_channel;
                   1443:                rf->width        = 24;  /* 24-bit RF values */
                   1444:                break;
                   1445:        case ZYD_RF_AL2230:
                   1446:                if (sc->mac_rev == ZYD_ZD1211B)
                   1447:                        rf->init = zyd_al2230_init_b;
                   1448:                else
                   1449:                        rf->init = zyd_al2230_init;
                   1450:                rf->switch_radio = zyd_al2230_switch_radio;
                   1451:                rf->set_channel  = zyd_al2230_set_channel;
                   1452:                rf->width        = 24;  /* 24-bit RF values */
                   1453:                break;
                   1454:        case ZYD_RF_AL7230B:
                   1455:                rf->init         = zyd_al7230B_init;
                   1456:                rf->switch_radio = zyd_al7230B_switch_radio;
                   1457:                rf->set_channel  = zyd_al7230B_set_channel;
                   1458:                rf->width        = 24;  /* 24-bit RF values */
                   1459:                break;
                   1460:        case ZYD_RF_AL2210:
                   1461:                rf->init         = zyd_al2210_init;
                   1462:                rf->switch_radio = zyd_al2210_switch_radio;
                   1463:                rf->set_channel  = zyd_al2210_set_channel;
                   1464:                rf->width        = 24;  /* 24-bit RF values */
                   1465:                break;
                   1466:        case ZYD_RF_GCT:
                   1467:                rf->init         = zyd_gct_init;
                   1468:                rf->switch_radio = zyd_gct_switch_radio;
                   1469:                rf->set_channel  = zyd_gct_set_channel;
                   1470:                rf->width        = 21;  /* 21-bit RF values */
                   1471:                break;
                   1472:        case ZYD_RF_MAXIM_NEW:
                   1473:                rf->init         = zyd_maxim_init;
                   1474:                rf->switch_radio = zyd_maxim_switch_radio;
                   1475:                rf->set_channel  = zyd_maxim_set_channel;
                   1476:                rf->width        = 18;  /* 18-bit RF values */
                   1477:                break;
                   1478:        case ZYD_RF_MAXIM_NEW2:
                   1479:                rf->init         = zyd_maxim2_init;
                   1480:                rf->switch_radio = zyd_maxim2_switch_radio;
                   1481:                rf->set_channel  = zyd_maxim2_set_channel;
                   1482:                rf->width        = 18;  /* 18-bit RF values */
                   1483:                break;
                   1484:        default:
                   1485:                printf("%s: sorry, radio \"%s\" is not supported yet\n",
                   1486:                    sc->sc_dev.dv_xname, zyd_rf_name(type));
                   1487:                return EINVAL;
                   1488:        }
                   1489:        return 0;
                   1490: }
                   1491:
                   1492: const char *
                   1493: zyd_rf_name(uint8_t type)
                   1494: {
                   1495:        static const char * const zyd_rfs[] = {
                   1496:                "unknown", "unknown", "UW2451",   "UCHIP",     "AL2230",
                   1497:                "AL7230B", "THETA",   "AL2210",   "MAXIM_NEW", "GCT",
                   1498:                "PV2000",  "RALINK",  "INTERSIL", "RFMD",      "MAXIM_NEW2",
                   1499:                "PHILIPS"
                   1500:        };
                   1501:        return zyd_rfs[(type > 15) ? 0 : type];
                   1502: }
                   1503:
                   1504: int
                   1505: zyd_hw_init(struct zyd_softc *sc)
                   1506: {
                   1507:        struct zyd_rf *rf = &sc->sc_rf;
                   1508:        const struct zyd_phy_pair *phyp;
                   1509:        int error;
                   1510:
                   1511:        /* specify that the plug and play is finished */
                   1512:        (void)zyd_write32(sc, ZYD_MAC_AFTER_PNP, 1);
                   1513:
                   1514:        (void)zyd_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->fwbase);
                   1515:        DPRINTF(("firmware base address=0x%04x\n", sc->fwbase));
                   1516:
                   1517:        /* retrieve firmware revision number */
                   1518:        (void)zyd_read16(sc, sc->fwbase + ZYD_FW_FIRMWARE_REV, &sc->fw_rev);
                   1519:
                   1520:        (void)zyd_write32(sc, ZYD_CR_GPI_EN, 0);
                   1521:        (void)zyd_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
                   1522:
                   1523:        /* disable interrupts */
                   1524:        (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
                   1525:
                   1526:        /* PHY init */
                   1527:        zyd_lock_phy(sc);
                   1528:        phyp = (sc->mac_rev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
                   1529:        for (; phyp->reg != 0; phyp++) {
                   1530:                if ((error = zyd_write16(sc, phyp->reg, phyp->val)) != 0)
                   1531:                        goto fail;
                   1532:        }
                   1533:        zyd_unlock_phy(sc);
                   1534:
                   1535:        /* HMAC init */
                   1536:        zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020);
                   1537:        zyd_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
                   1538:
                   1539:        if (sc->mac_rev == ZYD_ZD1211) {
                   1540:                zyd_write32(sc, ZYD_MAC_RETRY, 0x00000002);
                   1541:        } else {
                   1542:                zyd_write32(sc, ZYD_MAC_RETRY, 0x02020202);
                   1543:                zyd_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
                   1544:                zyd_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
                   1545:                zyd_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
                   1546:                zyd_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
                   1547:                zyd_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
                   1548:                zyd_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
                   1549:                zyd_write32(sc, ZYD_MACB_TXOP, 0x01800824);
                   1550:        }
                   1551:
                   1552:        zyd_write32(sc, ZYD_MAC_SNIFFER, 0x00000000);
                   1553:        zyd_write32(sc, ZYD_MAC_RXFILTER, 0x00000000);
                   1554:        zyd_write32(sc, ZYD_MAC_GHTBL, 0x00000000);
                   1555:        zyd_write32(sc, ZYD_MAC_GHTBH, 0x80000000);
                   1556:        zyd_write32(sc, ZYD_MAC_MISC, 0x000000a4);
                   1557:        zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
                   1558:        zyd_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401);
                   1559:        zyd_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
                   1560:        zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080);
                   1561:        zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
                   1562:        zyd_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
                   1563:        zyd_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032);
                   1564:        zyd_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
                   1565:        zyd_write32(sc, ZYD_CR_PS_CTRL, 0x10000000);
                   1566:        zyd_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
                   1567:        zyd_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
                   1568:        zyd_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
                   1569:
                   1570:        /* RF chip init */
                   1571:        zyd_lock_phy(sc);
                   1572:        error = (*rf->init)(rf);
                   1573:        zyd_unlock_phy(sc);
                   1574:        if (error != 0) {
                   1575:                printf("%s: radio initialization failed\n",
                   1576:                    sc->sc_dev.dv_xname);
                   1577:                goto fail;
                   1578:        }
                   1579:
                   1580:        /* init beacon interval to 100ms */
                   1581:        if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
                   1582:                goto fail;
                   1583:
                   1584: fail:  return error;
                   1585: }
                   1586:
                   1587: int
                   1588: zyd_read_eeprom(struct zyd_softc *sc)
                   1589: {
                   1590:        struct ieee80211com *ic = &sc->sc_ic;
                   1591:        uint32_t tmp;
                   1592:        uint16_t val;
                   1593:        int i;
                   1594:
                   1595:        /* read MAC address */
                   1596:        (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp);
                   1597:        ic->ic_myaddr[0] = tmp & 0xff;
                   1598:        ic->ic_myaddr[1] = tmp >>  8;
                   1599:        ic->ic_myaddr[2] = tmp >> 16;
                   1600:        ic->ic_myaddr[3] = tmp >> 24;
                   1601:        (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp);
                   1602:        ic->ic_myaddr[4] = tmp & 0xff;
                   1603:        ic->ic_myaddr[5] = tmp >>  8;
                   1604:
                   1605:        (void)zyd_read32(sc, ZYD_EEPROM_POD, &tmp);
                   1606:        sc->rf_rev = tmp & 0x0f;
                   1607:        sc->pa_rev = (tmp >> 16) & 0x0f;
                   1608:
                   1609:        /* read regulatory domain (currently unused) */
                   1610:        (void)zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp);
                   1611:        sc->regdomain = tmp >> 16;
                   1612:        DPRINTF(("regulatory domain %x\n", sc->regdomain));
                   1613:
                   1614:        /* read Tx power calibration tables */
                   1615:        for (i = 0; i < 7; i++) {
                   1616:                (void)zyd_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val);
                   1617:                sc->pwr_cal[i * 2] = val >> 8;
                   1618:                sc->pwr_cal[i * 2 + 1] = val & 0xff;
                   1619:
                   1620:                (void)zyd_read16(sc, ZYD_EEPROM_PWR_INT + i, &val);
                   1621:                sc->pwr_int[i * 2] = val >> 8;
                   1622:                sc->pwr_int[i * 2 + 1] = val & 0xff;
                   1623:
                   1624:                (void)zyd_read16(sc, ZYD_EEPROM_36M_CAL + i, &val);
                   1625:                sc->ofdm36_cal[i * 2] = val >> 8;
                   1626:                sc->ofdm36_cal[i * 2 + 1] = val & 0xff;
                   1627:
                   1628:                (void)zyd_read16(sc, ZYD_EEPROM_48M_CAL + i, &val);
                   1629:                sc->ofdm48_cal[i * 2] = val >> 8;
                   1630:                sc->ofdm48_cal[i * 2 + 1] = val & 0xff;
                   1631:
                   1632:                (void)zyd_read16(sc, ZYD_EEPROM_54M_CAL + i, &val);
                   1633:                sc->ofdm54_cal[i * 2] = val >> 8;
                   1634:                sc->ofdm54_cal[i * 2 + 1] = val & 0xff;
                   1635:        }
                   1636:        return 0;
                   1637: }
                   1638:
                   1639: int
                   1640: zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
                   1641: {
                   1642:        uint32_t tmp;
                   1643:
                   1644:        tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
                   1645:        (void)zyd_write32(sc, ZYD_MAC_MACADRL, tmp);
                   1646:
                   1647:        tmp = addr[5] << 8 | addr[4];
                   1648:        (void)zyd_write32(sc, ZYD_MAC_MACADRH, tmp);
                   1649:
                   1650:        return 0;
                   1651: }
                   1652:
                   1653: int
                   1654: zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
                   1655: {
                   1656:        uint32_t tmp;
                   1657:
                   1658:        tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
                   1659:        (void)zyd_write32(sc, ZYD_MAC_BSSADRL, tmp);
                   1660:
                   1661:        tmp = addr[5] << 8 | addr[4];
                   1662:        (void)zyd_write32(sc, ZYD_MAC_BSSADRH, tmp);
                   1663:
                   1664:        return 0;
                   1665: }
                   1666:
                   1667: int
                   1668: zyd_switch_radio(struct zyd_softc *sc, int on)
                   1669: {
                   1670:        struct zyd_rf *rf = &sc->sc_rf;
                   1671:        int error;
                   1672:
                   1673:        zyd_lock_phy(sc);
                   1674:        error = (*rf->switch_radio)(rf, on);
                   1675:        zyd_unlock_phy(sc);
                   1676:
                   1677:        return error;
                   1678: }
                   1679:
                   1680: void
                   1681: zyd_set_led(struct zyd_softc *sc, int which, int on)
                   1682: {
                   1683:        uint32_t tmp;
                   1684:
                   1685:        (void)zyd_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
                   1686:        tmp &= ~which;
                   1687:        if (on)
                   1688:                tmp |= which;
                   1689:        (void)zyd_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
                   1690: }
                   1691:
                   1692: int
                   1693: zyd_set_rxfilter(struct zyd_softc *sc)
                   1694: {
                   1695:        uint32_t rxfilter;
                   1696:
                   1697:        switch (sc->sc_ic.ic_opmode) {
                   1698:        case IEEE80211_M_STA:
                   1699:                rxfilter = ZYD_FILTER_BSS;
                   1700:                break;
                   1701:        case IEEE80211_M_IBSS:
                   1702:        case IEEE80211_M_HOSTAP:
                   1703:                rxfilter = ZYD_FILTER_HOSTAP;
                   1704:                break;
                   1705:        case IEEE80211_M_MONITOR:
                   1706:                rxfilter = ZYD_FILTER_MONITOR;
                   1707:                break;
                   1708:        default:
                   1709:                /* should not get there */
                   1710:                return EINVAL;
                   1711:        }
                   1712:        return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
                   1713: }
                   1714:
                   1715: void
                   1716: zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
                   1717: {
                   1718:        struct ieee80211com *ic = &sc->sc_ic;
                   1719:        struct zyd_rf *rf = &sc->sc_rf;
                   1720:        u_int chan;
                   1721:
                   1722:        chan = ieee80211_chan2ieee(ic, c);
                   1723:        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                   1724:                return;
                   1725:
                   1726:        zyd_lock_phy(sc);
                   1727:
                   1728:        (*rf->set_channel)(rf, chan);
                   1729:
                   1730:        /* update Tx power */
                   1731:        (void)zyd_write32(sc, ZYD_CR31, sc->pwr_int[chan - 1]);
                   1732:        (void)zyd_write32(sc, ZYD_CR68, sc->pwr_cal[chan - 1]);
                   1733:
                   1734:        if (sc->mac_rev == ZYD_ZD1211B) {
                   1735:                (void)zyd_write32(sc, ZYD_CR67, sc->ofdm36_cal[chan - 1]);
                   1736:                (void)zyd_write32(sc, ZYD_CR66, sc->ofdm48_cal[chan - 1]);
                   1737:                (void)zyd_write32(sc, ZYD_CR65, sc->ofdm54_cal[chan - 1]);
                   1738:
                   1739:                (void)zyd_write32(sc, ZYD_CR69, 0x28);
                   1740:                (void)zyd_write32(sc, ZYD_CR69, 0x2a);
                   1741:        }
                   1742:
                   1743:        zyd_unlock_phy(sc);
                   1744: }
                   1745:
                   1746: int
                   1747: zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
                   1748: {
                   1749:        /* XXX this is probably broken.. */
                   1750:        (void)zyd_write32(sc, ZYD_CR_ATIM_WND_PERIOD, bintval - 2);
                   1751:        (void)zyd_write32(sc, ZYD_CR_PRE_TBTT,        bintval - 1);
                   1752:        (void)zyd_write32(sc, ZYD_CR_BCN_INTERVAL,    bintval);
                   1753:
                   1754:        return 0;
                   1755: }
                   1756:
                   1757: uint8_t
                   1758: zyd_plcp_signal(int rate)
                   1759: {
                   1760:        switch (rate) {
                   1761:        /* CCK rates (returned values are device-dependent) */
                   1762:        case 2:         return 0x0;
                   1763:        case 4:         return 0x1;
                   1764:        case 11:        return 0x2;
                   1765:        case 22:        return 0x3;
                   1766:
                   1767:        /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
                   1768:        case 12:        return 0xb;
                   1769:        case 18:        return 0xf;
                   1770:        case 24:        return 0xa;
                   1771:        case 36:        return 0xe;
                   1772:        case 48:        return 0x9;
                   1773:        case 72:        return 0xd;
                   1774:        case 96:        return 0x8;
                   1775:        case 108:       return 0xc;
                   1776:
                   1777:        /* unsupported rates (should not get there) */
                   1778:        default:        return 0xff;
                   1779:        }
                   1780: }
                   1781:
                   1782: void
                   1783: zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   1784: {
                   1785:        struct zyd_softc *sc = (struct zyd_softc *)priv;
                   1786:        const struct zyd_cmd *cmd;
                   1787:        uint32_t len;
                   1788:
                   1789:        if (status != USBD_NORMAL_COMPLETION) {
                   1790:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   1791:                        return;
                   1792:
                   1793:                if (status == USBD_STALLED) {
                   1794:                        usbd_clear_endpoint_stall_async(
                   1795:                            sc->zyd_ep[ZYD_ENDPT_IIN]);
                   1796:                }
                   1797:                return;
                   1798:        }
                   1799:
                   1800:        cmd = (const struct zyd_cmd *)sc->ibuf;
                   1801:
                   1802:        if (letoh16(cmd->code) == ZYD_NOTIF_RETRYSTATUS) {
                   1803:                struct zyd_notif_retry *retry =
                   1804:                    (struct zyd_notif_retry *)cmd->data;
                   1805:                struct ieee80211com *ic = &sc->sc_ic;
                   1806:                struct ifnet *ifp = &ic->ic_if;
                   1807:                struct ieee80211_node *ni;
                   1808:
                   1809:                DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
                   1810:                    letoh16(retry->rate), ether_sprintf(retry->macaddr),
                   1811:                    letoh16(retry->count) & 0xff, letoh16(retry->count)));
                   1812:
                   1813:                /*
                   1814:                 * Find the node to which the packet was sent and update its
                   1815:                 * retry statistics.  In BSS mode, this node is the AP we're
                   1816:                 * associated to so no lookup is actually needed.
                   1817:                 */
                   1818:                if (ic->ic_opmode != IEEE80211_M_STA) {
                   1819:                        ni = ieee80211_find_node(ic, retry->macaddr);
                   1820:                        if (ni == NULL)
                   1821:                                return; /* just ignore */
                   1822:                } else
                   1823:                        ni = ic->ic_bss;
                   1824:
                   1825:                ((struct zyd_node *)ni)->amn.amn_retrycnt++;
                   1826:
                   1827:                if (letoh16(retry->count) & 0x100)
                   1828:                        ifp->if_oerrors++;      /* too many retries */
                   1829:
                   1830:        } else if (letoh16(cmd->code) == ZYD_NOTIF_IORD) {
                   1831:                if (letoh16(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
                   1832:                        return; /* HMAC interrupt */
                   1833:
                   1834:                if (sc->odata == NULL)
                   1835:                        return; /* unexpected IORD notification */
                   1836:
                   1837:                /* copy answer into caller-supplied buffer */
                   1838:                usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
                   1839:                bcopy(cmd->data, sc->odata, sc->olen);
                   1840:
                   1841:                wakeup(sc);     /* wakeup caller */
                   1842:
                   1843:        } else {
                   1844:                printf("%s: unknown notification %x\n", sc->sc_dev.dv_xname,
                   1845:                    letoh16(cmd->code));
                   1846:        }
                   1847: }
                   1848:
                   1849: void
                   1850: zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
                   1851: {
                   1852:        struct ieee80211com *ic = &sc->sc_ic;
                   1853:        struct ifnet *ifp = &ic->ic_if;
                   1854:        struct ieee80211_node *ni;
                   1855:        struct ieee80211_frame *wh;
                   1856:        const struct zyd_plcphdr *plcp;
                   1857:        const struct zyd_rx_stat *stat;
                   1858:        struct mbuf *m;
                   1859:        int rlen, s;
                   1860:
                   1861:        if (len < ZYD_MIN_FRAGSZ) {
                   1862:                printf("%s: frame too short (length=%d)\n",
                   1863:                    sc->sc_dev.dv_xname, len);
                   1864:                ifp->if_ierrors++;
                   1865:                return;
                   1866:        }
                   1867:
                   1868:        plcp = (const struct zyd_plcphdr *)buf;
                   1869:        stat = (const struct zyd_rx_stat *)
                   1870:            (buf + len - sizeof (struct zyd_rx_stat));
                   1871:
                   1872:        if (stat->flags & ZYD_RX_ERROR) {
                   1873:                DPRINTF(("%s: RX status indicated error (%x)\n",
                   1874:                    sc->sc_dev.dv_xname, stat->flags));
                   1875:                ifp->if_ierrors++;
                   1876:                return;
                   1877:        }
                   1878:
                   1879:        /* compute actual frame length */
                   1880:        rlen = len - sizeof (struct zyd_plcphdr) -
                   1881:            sizeof (struct zyd_rx_stat) - IEEE80211_CRC_LEN;
                   1882:
                   1883:        /* allocate a mbuf to store the frame */
                   1884:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1885:        if (m == NULL) {
                   1886:                printf("%s: could not allocate rx mbuf\n",
                   1887:                    sc->sc_dev.dv_xname);
                   1888:                ifp->if_ierrors++;
                   1889:                return;
                   1890:        }
                   1891:        if (rlen > MHLEN) {
                   1892:                MCLGET(m, M_DONTWAIT);
                   1893:                if (!(m->m_flags & M_EXT)) {
                   1894:                        printf("%s: could not allocate rx mbuf cluster\n",
                   1895:                            sc->sc_dev.dv_xname);
                   1896:                        m_freem(m);
                   1897:                        ifp->if_ierrors++;
                   1898:                        return;
                   1899:                }
                   1900:        }
                   1901:        m->m_pkthdr.rcvif = ifp;
                   1902:        m->m_pkthdr.len = m->m_len = rlen;
                   1903:        bcopy((const uint8_t *)(plcp + 1), mtod(m, uint8_t *), rlen);
                   1904:
                   1905: #if NBPFILTER > 0
                   1906:        if (sc->sc_drvbpf != NULL) {
                   1907:                struct mbuf mb;
                   1908:                struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
                   1909:                static const uint8_t rates[] = {
                   1910:                        /* reverse function of zyd_plcp_signal() */
                   1911:                        2, 4, 11, 22, 0, 0, 0, 0,
                   1912:                        96, 48, 24, 12, 108, 72, 36, 18
                   1913:                };
                   1914:
                   1915:                tap->wr_flags = 0;
                   1916:                tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   1917:                tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   1918:                tap->wr_rssi = stat->rssi;
                   1919:                tap->wr_rate = rates[plcp->signal & 0xf];
                   1920:
                   1921:                mb.m_data = (caddr_t)tap;
                   1922:                mb.m_len = sc->sc_rxtap_len;
                   1923:                mb.m_next = m;
                   1924:                mb.m_nextpkt = NULL;
                   1925:                mb.m_type = 0;
                   1926:                mb.m_flags = 0;
                   1927:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
                   1928:        }
                   1929: #endif
                   1930:
                   1931:        s = splnet();
                   1932:        wh = mtod(m, struct ieee80211_frame *);
                   1933:        ni = ieee80211_find_rxnode(ic, wh);
                   1934:        ieee80211_input(ifp, m, ni, stat->rssi, 0);
                   1935:
                   1936:        /* node is no longer needed */
                   1937:        ieee80211_release_node(ic, ni);
                   1938:
                   1939:        splx(s);
                   1940: }
                   1941:
                   1942: void
                   1943: zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   1944: {
                   1945:        struct zyd_rx_data *data = priv;
                   1946:        struct zyd_softc *sc = data->sc;
                   1947:        struct ieee80211com *ic = &sc->sc_ic;
                   1948:        struct ifnet *ifp = &ic->ic_if;
                   1949:        const struct zyd_rx_desc *desc;
                   1950:        int len;
                   1951:
                   1952:        if (status != USBD_NORMAL_COMPLETION) {
                   1953:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   1954:                        return;
                   1955:
                   1956:                if (status == USBD_STALLED)
                   1957:                        usbd_clear_endpoint_stall(sc->zyd_ep[ZYD_ENDPT_BIN]);
                   1958:
                   1959:                goto skip;
                   1960:        }
                   1961:        usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
                   1962:
                   1963:        if (len < ZYD_MIN_RXBUFSZ) {
                   1964:                printf("%s: xfer too short (length=%d)\n",
                   1965:                    sc->sc_dev.dv_xname, len);
                   1966:                ifp->if_ierrors++;
                   1967:                goto skip;
                   1968:        }
                   1969:
                   1970:        desc = (const struct zyd_rx_desc *)
                   1971:            (data->buf + len - sizeof (struct zyd_rx_desc));
                   1972:
                   1973:        if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) {
                   1974:                const uint8_t *p = data->buf, *end = p + len;
                   1975:                int i;
                   1976:
                   1977:                DPRINTFN(3, ("received multi-frame transfer\n"));
                   1978:
                   1979:                for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
                   1980:                        const uint16_t len = UGETW(desc->len[i]);
                   1981:
                   1982:                        if (len == 0 || p + len > end)
                   1983:                                break;
                   1984:
                   1985:                        zyd_rx_data(sc, p, len);
                   1986:                        /* next frame is aligned on a 32-bit boundary */
                   1987:                        p += (len + 3) & ~3;
                   1988:                }
                   1989:        } else {
                   1990:                DPRINTFN(3, ("received single-frame transfer\n"));
                   1991:
                   1992:                zyd_rx_data(sc, data->buf, len);
                   1993:        }
                   1994:
                   1995: skip:  /* setup a new transfer */
                   1996:        usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL,
                   1997:            ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
                   1998:            USBD_NO_TIMEOUT, zyd_rxeof);
                   1999:        (void)usbd_transfer(xfer);
                   2000: }
                   2001:
                   2002: void
                   2003: zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   2004: {
                   2005:        struct zyd_tx_data *data = priv;
                   2006:        struct zyd_softc *sc = data->sc;
                   2007:        struct ieee80211com *ic = &sc->sc_ic;
                   2008:        struct ifnet *ifp = &ic->ic_if;
                   2009:        int s;
                   2010:
                   2011:        if (status != USBD_NORMAL_COMPLETION) {
                   2012:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   2013:                        return;
                   2014:
                   2015:                printf("%s: could not transmit buffer: %s\n",
                   2016:                    sc->sc_dev.dv_xname, usbd_errstr(status));
                   2017:
                   2018:                if (status == USBD_STALLED) {
                   2019:                        usbd_clear_endpoint_stall_async(
                   2020:                            sc->zyd_ep[ZYD_ENDPT_BOUT]);
                   2021:                }
                   2022:                ifp->if_oerrors++;
                   2023:                return;
                   2024:        }
                   2025:
                   2026:        s = splnet();
                   2027:
                   2028:        /* update rate control statistics */
                   2029:        ((struct zyd_node *)data->ni)->amn.amn_txcnt++;
                   2030:
                   2031:        ieee80211_release_node(ic, data->ni);
                   2032:        data->ni = NULL;
                   2033:
                   2034:        sc->tx_queued--;
                   2035:        ifp->if_opackets++;
                   2036:
                   2037:        sc->tx_timer = 0;
                   2038:        ifp->if_flags &= ~IFF_OACTIVE;
                   2039:        zyd_start(ifp);
                   2040:
                   2041:        splx(s);
                   2042: }
                   2043:
                   2044: int
                   2045: zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                   2046: {
                   2047:        struct ieee80211com *ic = &sc->sc_ic;
                   2048:        struct ifnet *ifp = &ic->ic_if;
                   2049:        struct zyd_tx_desc *desc;
                   2050:        struct zyd_tx_data *data;
                   2051:        struct ieee80211_frame *wh;
                   2052:        int xferlen, totlen, rate;
                   2053:        uint16_t pktlen;
                   2054:        usbd_status error;
                   2055:
                   2056:        wh = mtod(m0, struct ieee80211_frame *);
                   2057:
                   2058:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   2059:                m0 = ieee80211_wep_crypt(ifp, m0, 1);
                   2060:                if (m0 == NULL)
                   2061:                        return ENOBUFS;
                   2062:
                   2063:                /* packet header may have moved, reset our local pointer */
                   2064:                wh = mtod(m0, struct ieee80211_frame *);
                   2065:        }
                   2066:
                   2067:        /* pickup a rate */
                   2068:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
                   2069:            ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
                   2070:             IEEE80211_FC0_TYPE_MGT)) {
                   2071:                /* mgmt/multicast frames are sent at the lowest avail. rate */
                   2072:                rate = ni->ni_rates.rs_rates[0];
                   2073:        } else if (ic->ic_fixed_rate != -1) {
                   2074:                rate = ic->ic_sup_rates[ic->ic_curmode].
                   2075:                    rs_rates[ic->ic_fixed_rate];
                   2076:        } else
                   2077:                rate = ni->ni_rates.rs_rates[ni->ni_txrate];
                   2078:        rate &= IEEE80211_RATE_VAL;
                   2079:        if (rate == 0)  /* XXX should not happen */
                   2080:                rate = 2;
                   2081:
                   2082:        data = &sc->tx_data[0];
                   2083:        desc = (struct zyd_tx_desc *)data->buf;
                   2084:
                   2085:        data->ni = ni;
                   2086:
                   2087:        xferlen = sizeof (struct zyd_tx_desc) + m0->m_pkthdr.len;
                   2088:        totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
                   2089:
                   2090:        /* fill Tx descriptor */
                   2091:        desc->len = htole16(totlen);
                   2092:
                   2093:        desc->flags = ZYD_TX_FLAG_BACKOFF;
                   2094:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
                   2095:                /* multicast frames are not sent at OFDM rates in 802.11b/g */
                   2096:                if (totlen > ic->ic_rtsthreshold) {
                   2097:                        desc->flags |= ZYD_TX_FLAG_RTS;
                   2098:                } else if (ZYD_RATE_IS_OFDM(rate) &&
                   2099:                    (ic->ic_flags & IEEE80211_F_USEPROT)) {
                   2100:                        if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
                   2101:                                desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
                   2102:                        else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
                   2103:                                desc->flags |= ZYD_TX_FLAG_RTS;
                   2104:                }
                   2105:        } else
                   2106:                desc->flags |= ZYD_TX_FLAG_MULTICAST;
                   2107:
                   2108:        if ((wh->i_fc[0] &
                   2109:            (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
                   2110:            (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
                   2111:                desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
                   2112:
                   2113:        desc->phy = zyd_plcp_signal(rate);
                   2114:        if (ZYD_RATE_IS_OFDM(rate)) {
                   2115:                desc->phy |= ZYD_TX_PHY_OFDM;
                   2116:                if (ic->ic_curmode == IEEE80211_MODE_11A)
                   2117:                        desc->phy |= ZYD_TX_PHY_5GHZ;
                   2118:        } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
                   2119:                desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
                   2120:
                   2121:        /* actual transmit length (XXX why +10?) */
                   2122:        pktlen = sizeof (struct zyd_tx_desc) + 10;
                   2123:        if (sc->mac_rev == ZYD_ZD1211)
                   2124:                pktlen += totlen;
                   2125:        desc->pktlen = htole16(pktlen);
                   2126:
                   2127:        desc->plcp_length = (16 * totlen + rate - 1) / rate;
                   2128:        desc->plcp_service = 0;
                   2129:        if (rate == 22) {
                   2130:                const int remainder = (16 * totlen) % 22;
                   2131:                if (remainder != 0 && remainder < 7)
                   2132:                        desc->plcp_service |= ZYD_PLCP_LENGEXT;
                   2133:        }
                   2134:
                   2135: #if NBPFILTER > 0
                   2136:        if (sc->sc_drvbpf != NULL) {
                   2137:                struct mbuf mb;
                   2138:                struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
                   2139:
                   2140:                tap->wt_flags = 0;
                   2141:                tap->wt_rate = rate;
                   2142:                tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
                   2143:                tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
                   2144:
                   2145:                mb.m_data = (caddr_t)tap;
                   2146:                mb.m_len = sc->sc_txtap_len;
                   2147:                mb.m_next = m0;
                   2148:                mb.m_nextpkt = NULL;
                   2149:                mb.m_type = 0;
                   2150:                mb.m_flags = 0;
                   2151:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
                   2152:        }
                   2153: #endif
                   2154:
                   2155:        m_copydata(m0, 0, m0->m_pkthdr.len,
                   2156:            data->buf + sizeof (struct zyd_tx_desc));
                   2157:
                   2158:        DPRINTFN(10, ("%s: sending data frame len=%u rate=%u xferlen=%u\n",
                   2159:            sc->sc_dev.dv_xname, m0->m_pkthdr.len, rate, xferlen));
                   2160:
                   2161:        m_freem(m0);    /* mbuf no longer needed */
                   2162:
                   2163:        usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data,
                   2164:            data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
                   2165:            ZYD_TX_TIMEOUT, zyd_txeof);
                   2166:        error = usbd_transfer(data->xfer);
                   2167:        if (error != USBD_IN_PROGRESS && error != 0) {
                   2168:                ifp->if_oerrors++;
                   2169:                return EIO;
                   2170:        }
                   2171:        sc->tx_queued++;
                   2172:
                   2173:        return 0;
                   2174: }
                   2175:
                   2176: void
                   2177: zyd_start(struct ifnet *ifp)
                   2178: {
                   2179:        struct zyd_softc *sc = ifp->if_softc;
                   2180:        struct ieee80211com *ic = &sc->sc_ic;
                   2181:        struct ieee80211_node *ni;
                   2182:        struct mbuf *m0;
                   2183:
                   2184:        /*
                   2185:         * net80211 may still try to send management frames even if the
                   2186:         * IFF_RUNNING flag is not set...
                   2187:         */
                   2188:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   2189:                return;
                   2190:
                   2191:        for (;;) {
                   2192:                IF_POLL(&ic->ic_mgtq, m0);
                   2193:                if (m0 != NULL) {
                   2194:                        if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
                   2195:                                ifp->if_flags |= IFF_OACTIVE;
                   2196:                                break;
                   2197:                        }
                   2198:                        IF_DEQUEUE(&ic->ic_mgtq, m0);
                   2199:
                   2200:                        ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
                   2201:                        m0->m_pkthdr.rcvif = NULL;
                   2202: #if NBPFILTER > 0
                   2203:                        if (ic->ic_rawbpf != NULL)
                   2204:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   2205: #endif
                   2206:                        if (zyd_tx_data(sc, m0, ni) != 0)
                   2207:                                break;
                   2208:                } else {
                   2209:                        if (ic->ic_state != IEEE80211_S_RUN)
                   2210:                                break;
                   2211:                        IFQ_POLL(&ifp->if_snd, m0);
                   2212:                        if (m0 == NULL)
                   2213:                                break;
                   2214:                        if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
                   2215:                                ifp->if_flags |= IFF_OACTIVE;
                   2216:                                break;
                   2217:                        }
                   2218:                        IFQ_DEQUEUE(&ifp->if_snd, m0);
                   2219: #if NBPFILTER > 0
                   2220:                        if (ifp->if_bpf != NULL)
                   2221:                                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   2222: #endif
                   2223:                        if ((m0 = ieee80211_encap(ifp, m0, &ni)) == NULL) {
                   2224:                                ifp->if_oerrors++;
                   2225:                                continue;
                   2226:                        }
                   2227: #if NBPFILTER > 0
                   2228:                        if (ic->ic_rawbpf != NULL)
                   2229:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   2230: #endif
                   2231:                        if (zyd_tx_data(sc, m0, ni) != 0) {
                   2232:                                if (ni != NULL)
                   2233:                                        ieee80211_release_node(ic, ni);
                   2234:                                ifp->if_oerrors++;
                   2235:                                break;
                   2236:                        }
                   2237:                }
                   2238:
                   2239:                sc->tx_timer = 5;
                   2240:                ifp->if_timer = 1;
                   2241:        }
                   2242: }
                   2243:
                   2244: void
                   2245: zyd_watchdog(struct ifnet *ifp)
                   2246: {
                   2247:        struct zyd_softc *sc = ifp->if_softc;
                   2248:
                   2249:        ifp->if_timer = 0;
                   2250:
                   2251:        if (sc->tx_timer > 0) {
                   2252:                if (--sc->tx_timer == 0) {
                   2253:                        printf("%s: device timeout\n", sc->sc_dev.dv_xname);
                   2254:                        /* zyd_init(ifp); XXX needs a process context ? */
                   2255:                        ifp->if_oerrors++;
                   2256:                        return;
                   2257:                }
                   2258:                ifp->if_timer = 1;
                   2259:        }
                   2260:
                   2261:        ieee80211_watchdog(ifp);
                   2262: }
                   2263:
                   2264: int
                   2265: zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                   2266: {
                   2267:        struct zyd_softc *sc = ifp->if_softc;
                   2268:        struct ieee80211com *ic = &sc->sc_ic;
                   2269:        struct ifaddr *ifa;
                   2270:        struct ifreq *ifr;
                   2271:        int s, error = 0;
                   2272:
                   2273:        s = splnet();
                   2274:
                   2275:        switch (cmd) {
                   2276:        case SIOCSIFADDR:
                   2277:                ifa = (struct ifaddr *)data;
                   2278:                ifp->if_flags |= IFF_UP;
                   2279: #ifdef INET
                   2280:                if (ifa->ifa_addr->sa_family == AF_INET)
                   2281:                        arp_ifinit(&ic->ic_ac, ifa);
                   2282: #endif
                   2283:                /* FALLTHROUGH */
                   2284:        case SIOCSIFFLAGS:
                   2285:                if (ifp->if_flags & IFF_UP) {
                   2286:                        if (!(ifp->if_flags & IFF_RUNNING))
                   2287:                                zyd_init(ifp);
                   2288:                } else {
                   2289:                        if (ifp->if_flags & IFF_RUNNING)
                   2290:                                zyd_stop(ifp, 1);
                   2291:                }
                   2292:                break;
                   2293:
                   2294:        case SIOCADDMULTI:
                   2295:        case SIOCDELMULTI:
                   2296:                ifr = (struct ifreq *)data;
                   2297:                error = (cmd == SIOCADDMULTI) ?
                   2298:                    ether_addmulti(ifr, &ic->ic_ac) :
                   2299:                    ether_delmulti(ifr, &ic->ic_ac);
                   2300:                if (error == ENETRESET)
                   2301:                        error = 0;
                   2302:                break;
                   2303:
                   2304:        case SIOCS80211CHANNEL:
                   2305:                /*
                   2306:                 * This allows for fast channel switching in monitor mode
                   2307:                 * (used by kismet). In IBSS mode, we must explicitly reset
                   2308:                 * the interface to generate a new beacon frame.
                   2309:                 */
                   2310:                error = ieee80211_ioctl(ifp, cmd, data);
                   2311:                if (error == ENETRESET &&
                   2312:                    ic->ic_opmode == IEEE80211_M_MONITOR) {
                   2313:                        zyd_set_chan(sc, ic->ic_ibss_chan);
                   2314:                        error = 0;
                   2315:                }
                   2316:                break;
                   2317:
                   2318:        default:
                   2319:                error = ieee80211_ioctl(ifp, cmd, data);
                   2320:        }
                   2321:
                   2322:        if (error == ENETRESET) {
                   2323:                if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) ==
                   2324:                    (IFF_RUNNING | IFF_UP))
                   2325:                        zyd_init(ifp);
                   2326:                error = 0;
                   2327:        }
                   2328:
                   2329:        splx(s);
                   2330:
                   2331:        return error;
                   2332: }
                   2333:
                   2334: int
                   2335: zyd_init(struct ifnet *ifp)
                   2336: {
                   2337:        struct zyd_softc *sc = ifp->if_softc;
                   2338:        struct ieee80211com *ic = &sc->sc_ic;
                   2339:        int i, error;
                   2340:
                   2341:        zyd_stop(ifp, 0);
                   2342:
                   2343:        IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
                   2344:        DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
                   2345:        error = zyd_set_macaddr(sc, ic->ic_myaddr);
                   2346:        if (error != 0)
                   2347:                return error;
                   2348:
                   2349:        /* we'll do software WEP decryption for now */
                   2350:        DPRINTF(("setting encryption type\n"));
                   2351:        error = zyd_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
                   2352:        if (error != 0)
                   2353:                return error;
                   2354:
                   2355:        /* promiscuous mode */
                   2356:        (void)zyd_write32(sc, ZYD_MAC_SNIFFER,
                   2357:            (ic->ic_opmode == IEEE80211_M_MONITOR) ? 1 : 0);
                   2358:
                   2359:        (void)zyd_set_rxfilter(sc);
                   2360:
                   2361:        /* switch radio transmitter ON */
                   2362:        (void)zyd_switch_radio(sc, 1);
                   2363:
                   2364:        /* set basic rates */
                   2365:        if (ic->ic_curmode == IEEE80211_MODE_11B)
                   2366:                (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003);
                   2367:        else if (ic->ic_curmode == IEEE80211_MODE_11A)
                   2368:                (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500);
                   2369:        else    /* assumes 802.11b/g */
                   2370:                (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f);
                   2371:
                   2372:        /* set mandatory rates */
                   2373:        if (ic->ic_curmode == IEEE80211_MODE_11B)
                   2374:                (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f);
                   2375:        else if (ic->ic_curmode == IEEE80211_MODE_11A)
                   2376:                (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500);
                   2377:        else    /* assumes 802.11b/g */
                   2378:                (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
                   2379:
                   2380:        /* set default BSS channel */
                   2381:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                   2382:        zyd_set_chan(sc, ic->ic_bss->ni_chan);
                   2383:
                   2384:        /* enable interrupts */
                   2385:        (void)zyd_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
                   2386:
                   2387:        /*
                   2388:         * Allocate Tx and Rx xfer queues.
                   2389:         */
                   2390:        if ((error = zyd_alloc_tx_list(sc)) != 0) {
                   2391:                printf("%s: could not allocate Tx list\n",
                   2392:                    sc->sc_dev.dv_xname);
                   2393:                goto fail;
                   2394:        }
                   2395:        if ((error = zyd_alloc_rx_list(sc)) != 0) {
                   2396:                printf("%s: could not allocate Rx list\n",
                   2397:                    sc->sc_dev.dv_xname);
                   2398:                goto fail;
                   2399:        }
                   2400:
                   2401:        /*
                   2402:         * Start up the receive pipe.
                   2403:         */
                   2404:        for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
                   2405:                struct zyd_rx_data *data = &sc->rx_data[i];
                   2406:
                   2407:                usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data,
                   2408:                    NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
                   2409:                    USBD_NO_TIMEOUT, zyd_rxeof);
                   2410:                error = usbd_transfer(data->xfer);
                   2411:                if (error != USBD_IN_PROGRESS && error != 0) {
                   2412:                        printf("%s: could not queue Rx transfer\n",
                   2413:                            sc->sc_dev.dv_xname);
                   2414:                        goto fail;
                   2415:                }
                   2416:        }
                   2417:
                   2418:        ifp->if_flags &= ~IFF_OACTIVE;
                   2419:        ifp->if_flags |= IFF_RUNNING;
                   2420:
                   2421:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
                   2422:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   2423:        else
                   2424:                ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   2425:
                   2426:        return 0;
                   2427:
                   2428: fail:  zyd_stop(ifp, 1);
                   2429:        return error;
                   2430: }
                   2431:
                   2432: void
                   2433: zyd_stop(struct ifnet *ifp, int disable)
                   2434: {
                   2435:        struct zyd_softc *sc = ifp->if_softc;
                   2436:        struct ieee80211com *ic = &sc->sc_ic;
                   2437:
                   2438:        sc->tx_timer = 0;
                   2439:        ifp->if_timer = 0;
                   2440:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2441:
                   2442:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);  /* free all nodes */
                   2443:
                   2444:        /* switch radio transmitter OFF */
                   2445:        (void)zyd_switch_radio(sc, 0);
                   2446:
                   2447:        /* disable Rx */
                   2448:        (void)zyd_write32(sc, ZYD_MAC_RXFILTER, 0);
                   2449:
                   2450:        /* disable interrupts */
                   2451:        (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
                   2452:
                   2453:        usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BIN]);
                   2454:        usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BOUT]);
                   2455:
                   2456:        zyd_free_rx_list(sc);
                   2457:        zyd_free_tx_list(sc);
                   2458: }
                   2459:
                   2460: int
                   2461: zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size)
                   2462: {
                   2463:        usb_device_request_t req;
                   2464:        uint16_t addr;
                   2465:        uint8_t stat;
                   2466:
                   2467:        DPRINTF(("firmware size=%d\n", size));
                   2468:
                   2469:        req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
                   2470:        req.bRequest = ZYD_DOWNLOADREQ;
                   2471:        USETW(req.wIndex, 0);
                   2472:
                   2473:        addr = ZYD_FIRMWARE_START_ADDR;
                   2474:        while (size > 0) {
                   2475:                const int mlen = min(size, 4096);
                   2476:
                   2477:                DPRINTF(("loading firmware block: len=%d, addr=0x%x\n", mlen,
                   2478:                    addr));
                   2479:
                   2480:                USETW(req.wValue, addr);
                   2481:                USETW(req.wLength, mlen);
                   2482:                if (usbd_do_request(sc->sc_udev, &req, fw) != 0)
                   2483:                        return EIO;
                   2484:
                   2485:                addr += mlen / 2;
                   2486:                fw   += mlen;
                   2487:                size -= mlen;
                   2488:        }
                   2489:
                   2490:        /* check whether the upload succeeded */
                   2491:        req.bmRequestType = UT_READ_VENDOR_DEVICE;
                   2492:        req.bRequest = ZYD_DOWNLOADSTS;
                   2493:        USETW(req.wValue, 0);
                   2494:        USETW(req.wIndex, 0);
                   2495:        USETW(req.wLength, sizeof stat);
                   2496:        if (usbd_do_request(sc->sc_udev, &req, &stat) != 0)
                   2497:                return EIO;
                   2498:
                   2499:        return (stat & 0x80) ? EIO : 0;
                   2500: }
                   2501:
                   2502: void
                   2503: zyd_iter_func(void *arg, struct ieee80211_node *ni)
                   2504: {
                   2505:        struct zyd_softc *sc = arg;
                   2506:        struct zyd_node *zn = (struct zyd_node *)ni;
                   2507:
                   2508:        ieee80211_amrr_choose(&sc->amrr, ni, &zn->amn);
                   2509: }
                   2510:
                   2511: void
                   2512: zyd_amrr_timeout(void *arg)
                   2513: {
                   2514:        struct zyd_softc *sc = arg;
                   2515:        struct ieee80211com *ic = &sc->sc_ic;
                   2516:        int s;
                   2517:
                   2518:        s = splnet();
                   2519:        if (ic->ic_opmode == IEEE80211_M_STA)
                   2520:                zyd_iter_func(sc, ic->ic_bss);
                   2521:        else
                   2522:                ieee80211_iterate_nodes(ic, zyd_iter_func, sc);
                   2523:        splx(s);
                   2524:
                   2525:        timeout_add(&sc->amrr_to, hz);
                   2526: }
                   2527:
                   2528: void
                   2529: zyd_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
                   2530: {
                   2531:        struct zyd_softc *sc = ic->ic_softc;
                   2532:        int i;
                   2533:
                   2534:        ieee80211_amrr_node_init(&sc->amrr, &((struct zyd_node *)ni)->amn);
                   2535:
                   2536:        /* set rate to some reasonable initial value */
                   2537:        for (i = ni->ni_rates.rs_nrates - 1;
                   2538:             i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
                   2539:             i--);
                   2540:        ni->ni_txrate = i;
                   2541: }
                   2542:
                   2543: int
                   2544: zyd_activate(struct device *self, enum devact act)
                   2545: {
                   2546:        switch (act) {
                   2547:        case DVACT_ACTIVATE:
                   2548:                break;
                   2549:
                   2550:        case DVACT_DEACTIVATE:
                   2551:                break;
                   2552:        }
                   2553:        return 0;
                   2554: }

CVSweb