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

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

1.1       nbrk        1: /*     $OpenBSD: if_atu.c,v 1.86 2007/07/18 18:10:31 damien Exp $ */
                      2: /*
                      3:  * Copyright (c) 2003, 2004
                      4:  *     Daan Vreeken <Danovitsch@Vitsch.net>.  All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by Daan Vreeken.
                     17:  * 4. Neither the name of the author nor the names of any co-contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD
                     25:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     26:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     27:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     28:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     29:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     30:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     31:  * THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: /*
                     35:  * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a  USB WLAN driver
                     36:  * version 0.5 - 2004-08-03
                     37:  *
                     38:  * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net>
                     39:  *  http://vitsch.net/bsd/atuwi
                     40:  *
                     41:  * Contributed to by :
                     42:  *  Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul,
                     43:  *  Suihong Liang, Arjan van Leeuwen, Stuart Walsh
                     44:  *
                     45:  * Ported to OpenBSD by Theo de Raadt and David Gwynne.
                     46:  */
                     47:
                     48: #include "bpfilter.h"
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/sockio.h>
                     52: #include <sys/mbuf.h>
                     53: #include <sys/kernel.h>
                     54: #include <sys/socket.h>
                     55: #include <sys/systm.h>
                     56: #include <sys/malloc.h>
                     57: #include <sys/kthread.h>
                     58: #include <sys/queue.h>
                     59: #include <sys/device.h>
                     60:
                     61: #include <machine/bus.h>
                     62:
                     63: #include <dev/usb/usb.h>
                     64: #include <dev/usb/usbdi.h>
                     65: #include <dev/usb/usbdi_util.h>
                     66: #include <dev/usb/usbdivar.h>
                     67:
                     68: #include <dev/usb/usbdevs.h>
                     69:
                     70: #if NBPFILTER > 0
                     71: #include <net/bpf.h>
                     72: #endif
                     73:
                     74: #include <net/if.h>
                     75: #include <net/if_dl.h>
                     76: #include <net/if_media.h>
                     77:
                     78: #ifdef INET
                     79: #include <netinet/in.h>
                     80: #include <netinet/if_ether.h>
                     81: #endif
                     82:
                     83: #include <net80211/ieee80211_var.h>
                     84: #include <net80211/ieee80211_radiotap.h>
                     85:
                     86: #ifdef USB_DEBUG
                     87: #define ATU_DEBUG
                     88: #endif
                     89:
                     90: #include <dev/usb/if_atureg.h>
                     91:
                     92: #ifdef ATU_DEBUG
                     93: #define DPRINTF(x)     do { if (atudebug) printf x; } while (0)
                     94: #define DPRINTFN(n,x)  do { if (atudebug>(n)) printf x; } while (0)
                     95: int atudebug = 1;
                     96: #else
                     97: #define DPRINTF(x)
                     98: #define DPRINTFN(n,x)
                     99: #endif
                    100:
                    101: int atu_match(struct device *, void *, void *);
                    102: void atu_attach(struct device *, struct device *, void *);
                    103: int atu_detach(struct device *, int);
                    104: int atu_activate(struct device *, enum devact);
                    105:
                    106: struct cfdriver atu_cd = {
                    107:        NULL, "atu", DV_IFNET
                    108: };
                    109:
                    110: const struct cfattach atu_ca = {
                    111:        sizeof(struct atu_softc),
                    112:        atu_match,
                    113:        atu_attach,
                    114:        atu_detach,
                    115:        atu_activate,
                    116: };
                    117:
                    118: /*
                    119:  * Various supported device vendors/products/radio type.
                    120:  */
                    121: struct atu_type atu_devs[] = {
                    122:        { USB_VENDOR_3COM,      USB_PRODUCT_3COM_3CRSHEW696,
                    123:          RadioRFMD,            ATU_NO_QUIRK },
                    124:        { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_BWU613,
                    125:          RadioRFMD,            ATU_NO_QUIRK },
                    126:        { USB_VENDOR_ACCTON,    USB_PRODUCT_ACCTON_2664W,
                    127:          AT76C503_rfmd_acc,    ATU_NO_QUIRK },
                    128:        { USB_VENDOR_ACERP,     USB_PRODUCT_ACERP_AWL300,
                    129:          RadioIntersil,        ATU_NO_QUIRK },
                    130:        { USB_VENDOR_ACERP,     USB_PRODUCT_ACERP_AWL400,
                    131:          RadioRFMD,            ATU_NO_QUIRK },
                    132:        { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1,
                    133:          RadioRFMD,            ATU_NO_QUIRK },
                    134:        { USB_VENDOR_ADDTRON,   USB_PRODUCT_ADDTRON_AWU120,
                    135:          RadioIntersil,        ATU_NO_QUIRK },
                    136:        { USB_VENDOR_AINCOMM,   USB_PRODUCT_AINCOMM_AWU2000B,
                    137:          RadioRFMD2958,        ATU_NO_QUIRK },
                    138:        { USB_VENDOR_ASKEY,     USB_PRODUCT_ASKEY_VOYAGER1010,
                    139:          RadioIntersil,        ATU_NO_QUIRK },
                    140:        { USB_VENDOR_ASKEY,     USB_PRODUCT_ASKEY_WLL013I,
                    141:          RadioIntersil,        ATU_NO_QUIRK },
                    142:        { USB_VENDOR_ASKEY,     USB_PRODUCT_ASKEY_WLL013,
                    143:          RadioRFMD,            ATU_NO_QUIRK },
                    144:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C503I1,
                    145:          RadioIntersil,        ATU_NO_QUIRK },
                    146:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C503I2,
                    147:          AT76C503_i3863,       ATU_NO_QUIRK },
                    148:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C503RFMD,
                    149:          RadioRFMD,            ATU_NO_QUIRK },
                    150:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C505RFMD,
                    151:          AT76C505_rfmd,        ATU_NO_QUIRK },
                    152:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C505RFMD2958,
                    153:          RadioRFMD2958,        ATU_NO_QUIRK },
                    154:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */
                    155:          RadioRFMD2958_SMC,    ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
                    156:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */
                    157:          RadioRFMD2958_SMC,    ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
                    158:        { USB_VENDOR_ATMEL,     USB_PRODUCT_ATMEL_WN210,
                    159:          RadioRFMD,            ATU_NO_QUIRK },
                    160:        { USB_VENDOR_BELKIN,    USB_PRODUCT_BELKIN_F5D6050,
                    161:          RadioRFMD,            ATU_NO_QUIRK },
                    162:        { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U,
                    163:          RadioIntersil,        ATU_NO_QUIRK },
                    164:        { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210,
                    165:          RadioIntersil,        ATU_NO_QUIRK },
                    166:        { USB_VENDOR_COMPAQ,    USB_PRODUCT_COMPAQ_IPAQWLAN,
                    167:          RadioRFMD,            ATU_NO_QUIRK },
                    168:        { USB_VENDOR_COREGA,    USB_PRODUCT_COREGA_WLUSB_11_STICK,
                    169:          RadioRFMD2958,        ATU_NO_QUIRK },
                    170:        { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G,
                    171:          RadioRFMD2958,        ATU_NO_QUIRK },
                    172:        { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U,
                    173:          RadioRFMD,            ATU_NO_QUIRK },
                    174:        { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U,
                    175:          RadioRFMD2958,        ATU_NO_QUIRK },
                    176:        { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153,
                    177:          RadioRFMD,            ATU_NO_QUIRK },
                    178:        { USB_VENDOR_DLINK,     USB_PRODUCT_DLINK_DWL120E,
                    179:          RadioRFMD,            ATU_NO_QUIRK },
                    180:        { USB_VENDOR_GIGABYTE,  USB_PRODUCT_GIGABYTE_GNWLBM101,
                    181:          RadioRFMD,            ATU_NO_QUIRK },
                    182:        { USB_VENDOR_GIGASET,   USB_PRODUCT_GIGASET_WLAN, /* quirk? */
                    183:          RadioRFMD2958_SMC,    ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
                    184:        { USB_VENDOR_HP,        USB_PRODUCT_HP_HN210W,
                    185:          RadioIntersil,        ATU_NO_QUIRK },
                    186:        { USB_VENDOR_INTEL,     USB_PRODUCT_INTEL_AP310,
                    187:          RadioIntersil,        ATU_NO_QUIRK },
                    188:        { USB_VENDOR_IODATA,    USB_PRODUCT_IODATA_USBWNB11A,
                    189:          RadioIntersil,        ATU_NO_QUIRK },
                    190:        { USB_VENDOR_LEXAR,     USB_PRODUCT_LEXAR_2662WAR,
                    191:          RadioRFMD,            ATU_NO_QUIRK },
                    192:        { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_WUSB11,
                    193:          RadioIntersil,        ATU_NO_QUIRK },
                    194:        { USB_VENDOR_LINKSYS2,  USB_PRODUCT_LINKSYS2_WUSB11,
                    195:          RadioRFMD,            ATU_NO_QUIRK },
                    196:        { USB_VENDOR_LINKSYS2,  USB_PRODUCT_LINKSYS2_NWU11B,
                    197:          RadioRFMD,            ATU_NO_QUIRK },
                    198:        { USB_VENDOR_LINKSYS3,  USB_PRODUCT_LINKSYS3_WUSB11V28,
                    199:          RadioRFMD2958,        ATU_NO_QUIRK },
                    200:        { USB_VENDOR_MSI,       USB_PRODUCT_MSI_WLAN,
                    201:          RadioRFMD2958,        ATU_NO_QUIRK },
                    202:        { USB_VENDOR_NETGEAR2,  USB_PRODUCT_NETGEAR2_MA101,
                    203:          RadioIntersil,        ATU_NO_QUIRK },
                    204:        { USB_VENDOR_NETGEAR2,  USB_PRODUCT_NETGEAR2_MA101B,
                    205:          RadioRFMD,            ATU_NO_QUIRK },
                    206:        { USB_VENDOR_OQO,       USB_PRODUCT_OQO_WIFI01,
                    207:          RadioRFMD2958_SMC,    ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
                    208:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_GW_US11S,
                    209:          RadioRFMD,            ATU_NO_QUIRK },
                    210:        { USB_VENDOR_SAMSUNG,   USB_PRODUCT_SAMSUNG_SWL2100W,
                    211:          AT76C503_i3863,       ATU_NO_QUIRK },
                    212:        { USB_VENDOR_SIEMENS2,  USB_PRODUCT_SIEMENS2_WLL013,
                    213:          RadioRFMD,            ATU_NO_QUIRK },
                    214:        { USB_VENDOR_SMC3,      USB_PRODUCT_SMC3_2662WV1,
                    215:          RadioIntersil,        ATU_NO_QUIRK },
                    216:        { USB_VENDOR_SMC3,      USB_PRODUCT_SMC3_2662WV2,
                    217:          AT76C503_rfmd_acc,    ATU_NO_QUIRK },
                    218:        { USB_VENDOR_TEKRAM,    USB_PRODUCT_TEKRAM_U300C,
                    219:          RadioIntersil,        ATU_NO_QUIRK },
                    220:        { USB_VENDOR_ZCOM,      USB_PRODUCT_ZCOM_M4Y750,
                    221:          RadioIntersil,        ATU_NO_QUIRK },
                    222: };
                    223:
                    224: struct atu_radfirm {
                    225:        enum    atu_radio_type atur_type;
                    226:        char    *atur_internal;
                    227:        char    *atur_external;
                    228:        u_int8_t max_rssi;
                    229: } atu_radfirm[] = {
                    230:        { RadioRFMD,            "atu-rfmd-int",         "atu-rfmd-ext", 0 },
                    231:        { RadioRFMD2958,        "atu-rfmd2958-int",     "atu-rfmd2958-ext", 81 },
                    232:        { RadioRFMD2958_SMC,    "atu-rfmd2958smc-int",  "atu-rfmd2958smc-ext", 0 },
                    233:        { RadioIntersil,        "atu-intersil-int",     "atu-intersil-ext", 0 },
                    234:        {
                    235:                AT76C503_i3863,
                    236:                "atu-at76c503-i3863-int",
                    237:                "atu-at76c503-i3863-ext",
                    238:                0
                    239:        },
                    240:        {
                    241:                AT76C503_rfmd_acc,
                    242:                "atu-at76c503-rfmd-acc-int",
                    243:                "atu-at76c503-rfmd-acc-ext",
                    244:                0
                    245:        },
                    246:        {
                    247:                AT76C505_rfmd,
                    248:                "atu-at76c505-rfmd-int",
                    249:                "atu-at76c505-rfmd-ext",
                    250:                0
                    251:        }
                    252: };
                    253:
                    254: int    atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
                    255: void   atu_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    256: void   atu_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    257: void   atu_start(struct ifnet *);
                    258: int    atu_ioctl(struct ifnet *, u_long, caddr_t);
                    259: int    atu_init(struct ifnet *);
                    260: void   atu_stop(struct ifnet *, int);
                    261: void   atu_watchdog(struct ifnet *);
                    262: usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type,
                    263:            u_int8_t request, u_int16_t value, u_int16_t index,
                    264:            u_int16_t length, u_int8_t *data);
                    265: int    atu_send_command(struct atu_softc *sc, u_int8_t *command, int size);
                    266: int    atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd,
                    267:            u_int8_t *status);
                    268: int    atu_wait_completion(struct atu_softc *sc, u_int8_t cmd,
                    269:            u_int8_t *status);
                    270: int    atu_send_mib(struct atu_softc *sc, u_int8_t type,
                    271:            u_int8_t size, u_int8_t index, void *data);
                    272: int    atu_get_mib(struct atu_softc *sc, u_int8_t type,
                    273:            u_int8_t size, u_int8_t index, u_int8_t *buf);
                    274: #if 0
                    275: int    atu_start_ibss(struct atu_softc *sc);
                    276: #endif
                    277: int    atu_start_scan(struct atu_softc *sc);
                    278: int    atu_switch_radio(struct atu_softc *sc, int state);
                    279: int    atu_initial_config(struct atu_softc *sc);
                    280: int    atu_join(struct atu_softc *sc, struct ieee80211_node *node);
                    281: int8_t atu_get_dfu_state(struct atu_softc *sc);
                    282: u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode);
                    283: void   atu_internal_firmware(void *);
                    284: void   atu_external_firmware(void *);
                    285: int    atu_get_card_config(struct atu_softc *sc);
                    286: int    atu_media_change(struct ifnet *ifp);
                    287: void   atu_media_status(struct ifnet *ifp, struct ifmediareq *req);
                    288: int    atu_tx_list_init(struct atu_softc *);
                    289: int    atu_rx_list_init(struct atu_softc *);
                    290: void   atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
                    291:            int listlen);
                    292:
                    293: void atu_task(void *);
                    294: int atu_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    295: int atu_tx_start(struct atu_softc *, struct ieee80211_node *,
                    296:     struct atu_chain *, struct mbuf *);
                    297: void atu_complete_attach(struct atu_softc *);
                    298: u_int8_t atu_calculate_padding(int);
                    299:
                    300: usbd_status
                    301: atu_usb_request(struct atu_softc *sc, u_int8_t type,
                    302:     u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length,
                    303:     u_int8_t *data)
                    304: {
                    305:        usb_device_request_t    req;
                    306:        usbd_xfer_handle        xfer;
                    307:        usbd_status             err;
                    308:        int                     total_len = 0, s;
                    309:
                    310:        req.bmRequestType = type;
                    311:        req.bRequest = request;
                    312:        USETW(req.wValue, value);
                    313:        USETW(req.wIndex, index);
                    314:        USETW(req.wLength, length);
                    315:
                    316: #ifdef ATU_DEBUG
                    317:        if (atudebug) {
                    318:                if ((data == NULL) || (type & UT_READ)) {
                    319:                        DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
                    320:                            "len=%02x\n", sc->atu_dev.dv_xname, request,
                    321:                            value, index, length));
                    322:                } else {
                    323:                        DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
                    324:                            "len=%02x [%8D]\n", sc->atu_dev.dv_xname,
                    325:                            request, value, index, length, data, " "));
                    326:                }
                    327:        }
                    328: #endif /* ATU_DEBUG */
                    329:
                    330:        s = splnet();
                    331:
                    332:        xfer = usbd_alloc_xfer(sc->atu_udev);
                    333:        usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data,
                    334:            length, USBD_SHORT_XFER_OK, 0);
                    335:
                    336:        err = usbd_sync_transfer(xfer);
                    337:
                    338:        usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
                    339:
                    340: #ifdef ATU_DEBUG
                    341:        if (atudebug) {
                    342:                if (type & UT_READ) {
                    343:                        DPRINTFN(20, ("%s: transfered 0x%x bytes in\n",
                    344:                            sc->atu_dev.dv_xname, total_len));
                    345:                        DPRINTFN(20, ("%s: dump [%10D]\n",
                    346:                            sc->atu_dev.dv_xname, data, " "));
                    347:                } else {
                    348:                        if (total_len != length)
                    349:                                DPRINTF(("%s: ARG! wrote only %x bytes\n",
                    350:                                    sc->atu_dev.dv_xname, total_len));
                    351:                }
                    352:        }
                    353: #endif /* ATU_DEBUG */
                    354:
                    355:        usbd_free_xfer(xfer);
                    356:
                    357:        splx(s);
                    358:        return(err);
                    359: }
                    360:
                    361: int
                    362: atu_send_command(struct atu_softc *sc, u_int8_t *command, int size)
                    363: {
                    364:        return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
                    365:            0x0000, size, command);
                    366: }
                    367:
                    368: int
                    369: atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
                    370: {
                    371:        /*
                    372:         * all other drivers (including Windoze) request 40 bytes of status
                    373:         * and get a short-xfer of just 6 bytes. we can save 34 bytes of
                    374:         * buffer if we just request those 6 bytes in the first place :)
                    375:         */
                    376:        /*
                    377:        return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
                    378:            0x0000, 40, status);
                    379:        */
                    380:        return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
                    381:            0x0000, 6, status);
                    382: }
                    383:
                    384: int
                    385: atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
                    386: {
                    387:        int                     idle_count = 0, err;
                    388:        u_int8_t                statusreq[6];
                    389:
                    390:        DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n",
                    391:            sc->atu_dev.dv_xname, cmd));
                    392:
                    393:        while (1) {
                    394:                err = atu_get_cmd_status(sc, cmd, statusreq);
                    395:                if (err)
                    396:                        return err;
                    397:
                    398: #ifdef ATU_DEBUG
                    399:                if (atudebug) {
                    400:                        DPRINTFN(20, ("%s: status=%s cmd=%02x\n",
                    401:                            sc->atu_dev.dv_xname,
                    402:                        ether_sprintf(statusreq), cmd));
                    403:                }
                    404: #endif /* ATU_DEBUG */
                    405:
                    406:                /*
                    407:                 * during normal operations waiting on STATUS_IDLE
                    408:                 * will never happen more than once
                    409:                 */
                    410:                if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) {
                    411:                        DPRINTF(("%s: AAARRGGG!!! FIX ME!\n",
                    412:                            sc->atu_dev.dv_xname));
                    413:                        return 0;
                    414:                }
                    415:
                    416:                if ((statusreq[5] != STATUS_IN_PROGRESS) &&
                    417:                    (statusreq[5] != STATUS_IDLE)) {
                    418:                        if (status != NULL)
                    419:                                *status = statusreq[5];
                    420:                        return 0;
                    421:                }
                    422:                usbd_delay_ms(sc->atu_udev, 25);
                    423:        }
                    424: }
                    425:
                    426: int
                    427: atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
                    428:     u_int8_t index, void *data)
                    429: {
                    430:        int                             err;
                    431:        struct atu_cmd_set_mib          request;
                    432:
                    433:        /*
                    434:         * We don't construct a MIB packet first and then memcpy it into an
                    435:         * Atmel-command-packet, we just construct it the right way at once :)
                    436:         */
                    437:
                    438:        memset(&request, 0, sizeof(request));
                    439:
                    440:        request.AtCmd = CMD_SET_MIB;
                    441:        USETW(request.AtSize, size + 4);
                    442:
                    443:        request.MIBType = type;
                    444:        request.MIBSize = size;
                    445:        request.MIBIndex = index;
                    446:        request.MIBReserved = 0;
                    447:
                    448:        /*
                    449:         * For 1 and 2 byte requests we assume a direct value,
                    450:         * everything bigger than 2 bytes we assume a pointer to the data
                    451:         */
                    452:        switch (size) {
                    453:        case 0:
                    454:                break;
                    455:        case 1:
                    456:                request.data[0]=(long)data & 0x000000ff;
                    457:                break;
                    458:        case 2:
                    459:                request.data[0]=(long)data & 0x000000ff;
                    460:                request.data[1]=(long)data >> 8;
                    461:                break;
                    462:        default:
                    463:                memcpy(request.data, data, size);
                    464:                break;
                    465:        }
                    466:
                    467:        err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
                    468:            0x0000, size+8, (uByte *)&request);
                    469:        if (err)
                    470:                return (err);
                    471:
                    472:        DPRINTFN(15, ("%s: sendmib : waitcompletion...\n",
                    473:            sc->atu_dev.dv_xname));
                    474:        return atu_wait_completion(sc, CMD_SET_MIB, NULL);
                    475: }
                    476:
                    477: int
                    478: atu_get_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
                    479:     u_int8_t index, u_int8_t *buf)
                    480: {
                    481:
                    482:        /* linux/at76c503.c - 478 */
                    483:        return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033,
                    484:            type << 8, index, size, buf);
                    485: }
                    486:
                    487: #if 0
                    488: int
                    489: atu_start_ibss(struct atu_softc *sc)
                    490: {
                    491:        int                             err;
                    492:        struct atu_cmd_start_ibss       Request;
                    493:
                    494:        Request.Cmd = CMD_START_IBSS;
                    495:        Request.Reserved = 0;
                    496:        Request.Size = sizeof(Request) - 4;
                    497:
                    498:        memset(Request.BSSID, 0x00, sizeof(Request.BSSID));
                    499:        memset(Request.SSID, 0x00, sizeof(Request.SSID));
                    500:        memcpy(Request.SSID, sc->atu_ssid, sc->atu_ssidlen);
                    501:        Request.SSIDSize = sc->atu_ssidlen;
                    502:        if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
                    503:                Request.Channel = (u_int8_t)sc->atu_desired_channel;
                    504:        else
                    505:                Request.Channel = ATU_DEFAULT_CHANNEL;
                    506:        Request.BSSType = AD_HOC_MODE;
                    507:        memset(Request.Res, 0x00, sizeof(Request.Res));
                    508:
                    509:        /* Write config to adapter */
                    510:        err = atu_send_command(sc, (u_int8_t *)&Request, sizeof(Request));
                    511:        if (err) {
                    512:                DPRINTF(("%s: start ibss failed!\n",
                    513:                    sc->atu_dev.dv_xname));
                    514:                return err;
                    515:        }
                    516:
                    517:        /* Wait for the adapter to do its thing */
                    518:        err = atu_wait_completion(sc, CMD_START_IBSS, NULL);
                    519:        if (err) {
                    520:                DPRINTF(("%s: error waiting for start_ibss\n",
                    521:                    sc->atu_dev.dv_xname));
                    522:                return err;
                    523:        }
                    524:
                    525:        /* Get the current BSSID */
                    526:        err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid);
                    527:        if (err) {
                    528:                DPRINTF(("%s: could not get BSSID!\n",
                    529:                    sc->atu_dev.dv_xname));
                    530:                return err;
                    531:        }
                    532:
                    533:        DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
                    534:            sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
                    535:        return 0;
                    536: }
                    537: #endif
                    538:
                    539: int
                    540: atu_start_scan(struct atu_softc *sc)
                    541: {
                    542:        struct ieee80211com             *ic = &sc->sc_ic;
                    543:        struct atu_cmd_do_scan          Scan;
                    544:        usbd_status                     err;
                    545:        int                             Cnt;
                    546:
                    547:        memset(&Scan, 0, sizeof(Scan));
                    548:
                    549:        Scan.Cmd = CMD_START_SCAN;
                    550:        Scan.Reserved = 0;
                    551:        USETW(Scan.Size, sizeof(Scan) - 4);
                    552:
                    553:        /* use the broadcast BSSID (in active scan) */
                    554:        for (Cnt=0; Cnt<6; Cnt++)
                    555:                Scan.BSSID[Cnt] = 0xff;
                    556:
                    557:        memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen);
                    558:        Scan.SSID_Len = ic->ic_des_esslen;
                    559:
                    560:        /* default values for scan */
                    561:        Scan.ScanType = ATU_SCAN_ACTIVE;
                    562:        if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
                    563:                Scan.Channel = (u_int8_t)sc->atu_desired_channel;
                    564:        else
                    565:                Scan.Channel = sc->atu_channel;
                    566:
                    567:        /* we like scans to be quick :) */
                    568:        /* the time we wait before sending probe's */
                    569:        USETW(Scan.ProbeDelay, 0);
                    570:        /* the time we stay on one channel */
                    571:        USETW(Scan.MinChannelTime, 100);
                    572:        USETW(Scan.MaxChannelTime, 200);
                    573:        /* whether or not we scan all channels */
                    574:        Scan.InternationalScan = 0xc1;
                    575:
                    576: #ifdef ATU_DEBUG
                    577:        if (atudebug) {
                    578:                DPRINTFN(20, ("%s: scan cmd len=%02x\n",
                    579:                    sc->atu_dev.dv_xname, sizeof(Scan)));
                    580:                DPRINTFN(20, ("%s: scan cmd: %52D\n", sc->atu_dev.dv_xname,
                    581:                    (u_int8_t *)&Scan, " "));
                    582:        }
                    583: #endif /* ATU_DEBUG */
                    584:
                    585:        /* Write config to adapter */
                    586:        err = atu_send_command(sc, (u_int8_t *)&Scan, sizeof(Scan));
                    587:        if (err)
                    588:                return err;
                    589:
                    590:        /*
                    591:         * We don't wait for the command to finish... the mgmt-thread will do
                    592:         * that for us
                    593:         */
                    594:        /*
                    595:        err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
                    596:        if (err)
                    597:                return err;
                    598:        */
                    599:        return 0;
                    600: }
                    601:
                    602: int
                    603: atu_switch_radio(struct atu_softc *sc, int state)
                    604: {
                    605:        usbd_status             err;
                    606:        struct atu_cmd          CmdRadio;
                    607:
                    608:        if (sc->atu_radio == RadioIntersil) {
                    609:                /*
                    610:                 * Intersil doesn't seem to need/support switching the radio
                    611:                 * on/off
                    612:                 */
                    613:                return 0;
                    614:        }
                    615:
                    616:        memset(&CmdRadio, 0, sizeof(CmdRadio));
                    617:        CmdRadio.Cmd = CMD_RADIO_ON;
                    618:
                    619:        if (sc->atu_radio_on != state) {
                    620:                if (state == 0)
                    621:                        CmdRadio.Cmd = CMD_RADIO_OFF;
                    622:
                    623:                err = atu_send_command(sc, (u_int8_t *)&CmdRadio,
                    624:                    sizeof(CmdRadio));
                    625:                if (err)
                    626:                        return err;
                    627:
                    628:                err = atu_wait_completion(sc, CmdRadio.Cmd, NULL);
                    629:                if (err)
                    630:                        return err;
                    631:
                    632:                DPRINTFN(10, ("%s: radio turned %s\n",
                    633:                    sc->atu_dev.dv_xname, state ? "on" : "off"));
                    634:                sc->atu_radio_on = state;
                    635:        }
                    636:        return 0;
                    637: }
                    638:
                    639: int
                    640: atu_initial_config(struct atu_softc *sc)
                    641: {
                    642:        struct ieee80211com             *ic = &sc->sc_ic;
                    643:        u_int32_t                       i;
                    644:        usbd_status                     err;
                    645: /*     u_int8_t                        rates[4] = {0x82, 0x84, 0x8B, 0x96};*/
                    646:        u_int8_t                        rates[4] = {0x82, 0x04, 0x0B, 0x16};
                    647:        struct atu_cmd_card_config      cmd;
                    648:        u_int8_t                        reg_domain;
                    649:
                    650:        DPRINTFN(10, ("%s: sending mac-addr\n", sc->atu_dev.dv_xname));
                    651:        err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr);
                    652:        if (err) {
                    653:                DPRINTF(("%s: error setting mac-addr\n",
                    654:                    sc->atu_dev.dv_xname));
                    655:                return err;
                    656:        }
                    657:
                    658:        /*
                    659:        DPRINTF(("%s: sending reg-domain\n", sc->atu_dev.dv_xname));
                    660:        err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
                    661:        if (err) {
                    662:                DPRINTF(("%s: error setting mac-addr\n",
                    663:                    sc->atu_dev.dv_xname));
                    664:                return err;
                    665:        }
                    666:        */
                    667:
                    668:        memset(&cmd, 0, sizeof(cmd));
                    669:        cmd.Cmd = CMD_STARTUP;
                    670:        cmd.Reserved = 0;
                    671:        USETW(cmd.Size, sizeof(cmd) - 4);
                    672:
                    673:        if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
                    674:                cmd.Channel = (u_int8_t)sc->atu_desired_channel;
                    675:        else
                    676:                cmd.Channel = sc->atu_channel;
                    677:        cmd.AutoRateFallback = 1;
                    678:        memcpy(cmd.BasicRateSet, rates, 4);
                    679:
                    680:        /* ShortRetryLimit should be 7 according to 802.11 spec */
                    681:        cmd.ShortRetryLimit = 7;
                    682:        USETW(cmd.RTS_Threshold, 2347);
                    683:        USETW(cmd.FragThreshold, 2346);
                    684:
                    685:        /* Doesn't seem to work, but we'll set it to 1 anyway */
                    686:        cmd.PromiscuousMode = 1;
                    687:
                    688:        /* this goes into the beacon we transmit */
                    689:        cmd.PrivacyInvoked = (ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0;
                    690:
                    691:        cmd.ExcludeUnencrypted = 0;
                    692:        switch (ic->ic_nw_keys[ic->ic_wep_txkey].k_cipher) {
                    693:        case IEEE80211_CIPHER_WEP40:
                    694:                cmd.EncryptionType = ATU_WEP_40BITS;
                    695:                break;
                    696:        case IEEE80211_CIPHER_WEP104:
                    697:                cmd.EncryptionType = ATU_WEP_104BITS;
                    698:                break;
                    699:        default:
                    700:                cmd.EncryptionType = ATU_WEP_OFF;
                    701:                break;
                    702:        }
                    703:
                    704:        cmd.WEP_DefaultKeyID = ic->ic_wep_txkey;
                    705:        for (i = 0; i < IEEE80211_WEP_NKID; i++) {
                    706:                memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].k_key,
                    707:                    ic->ic_nw_keys[i].k_len);
                    708:        }
                    709:
                    710:        /* Setting the SSID here doesn't seem to do anything */
                    711:        memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen);
                    712:        cmd.SSID_Len = ic->ic_des_esslen;
                    713:
                    714:        cmd.ShortPreamble = 0;
                    715:        USETW(cmd.BeaconPeriod, 100);
                    716:        /* cmd.BeaconPeriod = 65535; */
                    717:
                    718:        /*
                    719:         * TODO:
                    720:         * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
                    721:         * we should do something usefull with this info. right now it's just
                    722:         * ignored
                    723:         */
                    724:        err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain);
                    725:        if (err) {
                    726:                DPRINTF(("%s: could not get regdomain!\n",
                    727:                    sc->atu_dev.dv_xname));
                    728:        } else {
                    729:                DPRINTF(("%s: we're in reg domain 0x%x according to the "
                    730:                    "adapter\n", sc->atu_dev.dv_xname, reg_domain));
                    731:        }
                    732:
                    733: #ifdef ATU_DEBUG
                    734:        if (atudebug) {
                    735:                DPRINTFN(20, ("%s: configlen=%02x\n", sc->atu_dev.dv_xname,
                    736:                    sizeof(cmd)));
                    737:                DPRINTFN(20, ("%s: configdata= %108D\n",
                    738:                    sc->atu_dev.dv_xname, (u_int8_t *)&cmd, " "));
                    739:        }
                    740: #endif /* ATU_DEBUG */
                    741:
                    742:        /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
                    743:
                    744:        err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd));
                    745:        if (err)
                    746:                return err;
                    747:        err = atu_wait_completion(sc, CMD_STARTUP, NULL);
                    748:        if (err)
                    749:                return err;
                    750:
                    751:        /* Turn on radio now */
                    752:        err = atu_switch_radio(sc, 1);
                    753:        if (err)
                    754:                return err;
                    755:
                    756:        /* preamble type = short */
                    757:        err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT));
                    758:        if (err)
                    759:                return err;
                    760:
                    761:        /* frag = 1536 */
                    762:        err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346));
                    763:        if (err)
                    764:                return err;
                    765:
                    766:        /* rts = 1536 */
                    767:        err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347));
                    768:        if (err)
                    769:                return err;
                    770:
                    771:        /* auto rate fallback = 1 */
                    772:        err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1));
                    773:        if (err)
                    774:                return err;
                    775:
                    776:        /* power mode = full on, no power saving */
                    777:        err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE,
                    778:            NR(POWER_MODE_ACTIVE));
                    779:        if (err)
                    780:                return err;
                    781:
                    782:        DPRINTFN(10, ("%s: completed initial config\n",
                    783:           sc->atu_dev.dv_xname));
                    784:        return 0;
                    785: }
                    786:
                    787: int
                    788: atu_join(struct atu_softc *sc, struct ieee80211_node *node)
                    789: {
                    790:        struct atu_cmd_join             join;
                    791:        u_int8_t                        status;
                    792:        usbd_status                     err;
                    793:
                    794:        memset(&join, 0, sizeof(join));
                    795:
                    796:        join.Cmd = CMD_JOIN;
                    797:        join.Reserved = 0x00;
                    798:        USETW(join.Size, sizeof(join) - 4);
                    799:
                    800:        DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
                    801:            sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
                    802:        DPRINTFN(15, ("%s: mode=%d\n", sc->atu_dev.dv_xname,
                    803:            sc->atu_mode));
                    804:        memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN);
                    805:        memcpy(join.essid, node->ni_essid, node->ni_esslen);
                    806:        join.essid_size = node->ni_esslen;
                    807:        if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS)
                    808:                join.bss_type = AD_HOC_MODE;
                    809:        else
                    810:                join.bss_type = INFRASTRUCTURE_MODE;
                    811:        join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
                    812:
                    813:        USETW(join.timeout, ATU_JOIN_TIMEOUT);
                    814:        join.reserved = 0x00;
                    815:
                    816:        DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
                    817:            sc->atu_dev.dv_xname, ether_sprintf(join.bssid)));
                    818:        err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join));
                    819:        if (err) {
                    820:                DPRINTF(("%s: ERROR trying to join IBSS\n",
                    821:                    sc->atu_dev.dv_xname));
                    822:                return err;
                    823:        }
                    824:        err = atu_wait_completion(sc, CMD_JOIN, &status);
                    825:        if (err) {
                    826:                DPRINTF(("%s: error joining BSS!\n",
                    827:                    sc->atu_dev.dv_xname));
                    828:                return err;
                    829:        }
                    830:        if (status != STATUS_COMPLETE) {
                    831:                DPRINTF(("%s: error joining... [status=%02x]\n",
                    832:                    sc->atu_dev.dv_xname, status));
                    833:                return status;
                    834:        } else {
                    835:                DPRINTFN(10, ("%s: joined BSS\n", sc->atu_dev.dv_xname));
                    836:        }
                    837:        return err;
                    838: }
                    839:
                    840: /*
                    841:  * Get the state of the DFU unit
                    842:  */
                    843: int8_t
                    844: atu_get_dfu_state(struct atu_softc *sc)
                    845: {
                    846:        u_int8_t        state;
                    847:
                    848:        if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state))
                    849:                return -1;
                    850:        return state;
                    851: }
                    852:
                    853: /*
                    854:  * Get MAC opmode
                    855:  */
                    856: u_int8_t
                    857: atu_get_opmode(struct atu_softc *sc, u_int8_t *mode)
                    858: {
                    859:
                    860:        return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001,
                    861:            0x0000, 1, mode);
                    862: }
                    863:
                    864: /*
                    865:  * Upload the internal firmware into the device
                    866:  */
                    867: void
                    868: atu_internal_firmware(void *arg)
                    869: {
                    870:        struct atu_softc *sc = arg;
                    871:        u_char  state, *ptr = NULL, *firm = NULL, status[6];
                    872:        int block_size, block = 0, err, i;
                    873:        size_t  bytes_left = 0;
                    874:        char    *name = "unknown-device";
                    875:
                    876:        /*
                    877:         * Uploading firmware is done with the DFU (Device Firmware Upgrade)
                    878:         * interface. See "Universal Serial Bus - Device Class Specification
                    879:         * for Device Firmware Upgrade" pdf for details of the protocol.
                    880:         * Maybe this could be moved to a seperate 'firmware driver' once more
                    881:         * device drivers need it... For now we'll just do it here.
                    882:         *
                    883:         * Just for your information, the Atmel's DFU descriptor looks like
                    884:         * this:
                    885:         *
                    886:         * 07           size
                    887:         * 21           type
                    888:         * 01           capabilities : only firmware download, need reset
                    889:         *                after download
                    890:         * 13 05        detach timeout : max 1299ms between DFU_DETACH and
                    891:         *                reset
                    892:         * 00 04        max bytes of firmware per transaction : 1024
                    893:         */
                    894:
                    895:        /* Choose the right firmware for the device */
                    896:        for (i = 0; i < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); i++)
                    897:                if (sc->atu_radio == atu_radfirm[i].atur_type)
                    898:                        name = atu_radfirm[i].atur_internal;
                    899:
                    900:        DPRINTF(("%s: loading firmware %s...\n",
                    901:            sc->atu_dev.dv_xname, name));
                    902:        err = loadfirmware(name, &firm, &bytes_left);
                    903:        if (err != 0) {
                    904:                printf("%s: %s loadfirmware error %d\n",
                    905:                    sc->atu_dev.dv_xname, name, err);
                    906:                return;
                    907:        }
                    908:
                    909:        ptr = firm;
                    910:        state = atu_get_dfu_state(sc);
                    911:
                    912:        while (block >= 0 && state > 0) {
                    913:                switch (state) {
                    914:                case DFUState_DnLoadSync:
                    915:                        /* get DFU status */
                    916:                        err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6,
                    917:                            status);
                    918:                        if (err) {
                    919:                                DPRINTF(("%s: dfu_getstatus failed!\n",
                    920:                                    sc->atu_dev.dv_xname));
                    921:                                free(firm, M_DEVBUF);
                    922:                                return;
                    923:                        }
                    924:                        /* success means state => DnLoadIdle */
                    925:                        state = DFUState_DnLoadIdle;
                    926:                        continue;
                    927:                        break;
                    928:
                    929:                case DFUState_DFUIdle:
                    930:                case DFUState_DnLoadIdle:
                    931:                        if (bytes_left>=DFU_MaxBlockSize)
                    932:                                block_size = DFU_MaxBlockSize;
                    933:                        else
                    934:                                block_size = bytes_left;
                    935:                        DPRINTFN(15, ("%s: firmware block %d\n",
                    936:                            sc->atu_dev.dv_xname, block));
                    937:
                    938:                        err = atu_usb_request(sc, DFU_DNLOAD, block++, 0,
                    939:                            block_size, ptr);
                    940:                        if (err) {
                    941:                                DPRINTF(("%s: dfu_dnload failed\n",
                    942:                                    sc->atu_dev.dv_xname));
                    943:                                free(firm, M_DEVBUF);
                    944:                                return;
                    945:                        }
                    946:
                    947:                        ptr += block_size;
                    948:                        bytes_left -= block_size;
                    949:                        if (block_size == 0)
                    950:                                block = -1;
                    951:                        break;
                    952:
                    953:                default:
                    954:                        DPRINTFN(20, ("%s: sleeping for a while\n",
                    955:                            sc->atu_dev.dv_xname));
                    956:                        usbd_delay_ms(sc->atu_udev, 100);
                    957:                        break;
                    958:                }
                    959:
                    960:                state = atu_get_dfu_state(sc);
                    961:        }
                    962:        free(firm, M_DEVBUF);
                    963:
                    964:        if (state != DFUState_ManifestSync) {
                    965:                DPRINTF(("%s: state != manifestsync... eek!\n",
                    966:                    sc->atu_dev.dv_xname));
                    967:        }
                    968:
                    969:        err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status);
                    970:        if (err) {
                    971:                DPRINTF(("%s: dfu_getstatus failed!\n",
                    972:                    sc->atu_dev.dv_xname));
                    973:                return;
                    974:        }
                    975:
                    976:        DPRINTFN(15, ("%s: sending remap\n", sc->atu_dev.dv_xname));
                    977:        err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
                    978:        if ((err) && (!ISSET(sc->atu_quirk, ATU_QUIRK_NO_REMAP))) {
                    979:                DPRINTF(("%s: remap failed!\n", sc->atu_dev.dv_xname));
                    980:                return;
                    981:        }
                    982:
                    983:        /* after a lot of trying and measuring I found out the device needs
                    984:         * about 56 miliseconds after sending the remap command before
                    985:         * it's ready to communicate again. So we'll wait just a little bit
                    986:         * longer than that to be sure...
                    987:         */
                    988:        usbd_delay_ms(sc->atu_udev, 56+100);
                    989:
                    990:        printf("%s: reattaching after firmware upload\n",
                    991:            sc->atu_dev.dv_xname);
                    992:        usb_needs_reattach(sc->atu_udev);
                    993: }
                    994:
                    995: void
                    996: atu_external_firmware(void *arg)
                    997: {
                    998:        struct atu_softc *sc = arg;
                    999:        u_char  *ptr = NULL, *firm = NULL;
                   1000:        int     block_size, block = 0, err, i;
                   1001:        size_t  bytes_left = 0;
                   1002:        char    *name = "unknown-device";
                   1003:
                   1004:        for (i = 0; i < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); i++)
                   1005:                if (sc->atu_radio == atu_radfirm[i].atur_type)
                   1006:                        name = atu_radfirm[i].atur_external;
                   1007:
                   1008:        DPRINTF(("%s: loading external firmware %s\n",
                   1009:            sc->atu_dev.dv_xname, name));
                   1010:        err = loadfirmware(name, &firm, &bytes_left);
                   1011:        if (err != 0) {
                   1012:                printf("%s: %s loadfirmware error %d\n",
                   1013:                    sc->atu_dev.dv_xname, name, err);
                   1014:                return;
                   1015:        }
                   1016:        ptr = firm;
                   1017:
                   1018:        while (bytes_left) {
                   1019:                if (bytes_left > 1024)
                   1020:                        block_size = 1024;
                   1021:                else
                   1022:                        block_size = bytes_left;
                   1023:
                   1024:                DPRINTFN(15, ("%s: block:%d size:%d\n",
                   1025:                    sc->atu_dev.dv_xname, block, block_size));
                   1026:                err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e,
                   1027:                    0x0802, block, block_size, ptr);
                   1028:                if (err) {
                   1029:                        DPRINTF(("%s: could not load external firmware "
                   1030:                            "block\n", sc->atu_dev.dv_xname));
                   1031:                        free(firm, M_DEVBUF);
                   1032:                        return;
                   1033:                }
                   1034:
                   1035:                ptr += block_size;
                   1036:                block++;
                   1037:                bytes_left -= block_size;
                   1038:        }
                   1039:        free(firm, M_DEVBUF);
                   1040:
                   1041:        err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802,
                   1042:            block, 0, NULL);
                   1043:        if (err) {
                   1044:                DPRINTF(("%s: could not load last zero-length firmware "
                   1045:                    "block\n", sc->atu_dev.dv_xname));
                   1046:                return;
                   1047:        }
                   1048:
                   1049:        /*
                   1050:         * The SMC2662w V.4 seems to require some time to do its thing with
                   1051:         * the external firmware... 20 ms isn't enough, but 21 ms works 100
                   1052:         * times out of 100 tries. We'll wait a bit longer just to be sure
                   1053:         */
                   1054:        if (sc->atu_quirk & ATU_QUIRK_FW_DELAY)
                   1055:                usbd_delay_ms(sc->atu_udev, 21 + 100);
                   1056:
                   1057:        DPRINTFN(10, ("%s: external firmware upload done\n",
                   1058:            sc->atu_dev.dv_xname));
                   1059:        /* complete configuration after the firmwares have been uploaded */
                   1060:        atu_complete_attach(sc);
                   1061: }
                   1062:
                   1063: int
                   1064: atu_get_card_config(struct atu_softc *sc)
                   1065: {
                   1066:        struct ieee80211com             *ic = &sc->sc_ic;
                   1067:        struct atu_rfmd_conf            rfmd_conf;
                   1068:        struct atu_intersil_conf        intersil_conf;
                   1069:        int                             err;
                   1070:
                   1071:        switch (sc->atu_radio) {
                   1072:
                   1073:        case RadioRFMD:
                   1074:        case RadioRFMD2958:
                   1075:        case RadioRFMD2958_SMC:
                   1076:        case AT76C503_rfmd_acc:
                   1077:        case AT76C505_rfmd:
                   1078:                err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
                   1079:                    0x0a02, 0x0000, sizeof(rfmd_conf),
                   1080:                    (u_int8_t *)&rfmd_conf);
                   1081:                if (err) {
                   1082:                        DPRINTF(("%s: could not get rfmd config!\n",
                   1083:                            sc->atu_dev.dv_xname));
                   1084:                        return err;
                   1085:                }
                   1086:                memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN);
                   1087:                break;
                   1088:
                   1089:        case RadioIntersil:
                   1090:        case AT76C503_i3863:
                   1091:                err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
                   1092:                    0x0902, 0x0000, sizeof(intersil_conf),
                   1093:                    (u_int8_t *)&intersil_conf);
                   1094:                if (err) {
                   1095:                        DPRINTF(("%s: could not get intersil config!\n",
                   1096:                            sc->atu_dev.dv_xname));
                   1097:                        return err;
                   1098:                }
                   1099:                memcpy(ic->ic_myaddr, intersil_conf.MACAddr,
                   1100:                    IEEE80211_ADDR_LEN);
                   1101:                break;
                   1102:        }
                   1103:        return 0;
                   1104: }
                   1105:
                   1106: /*
                   1107:  * Probe for an AT76c503 chip.
                   1108:  */
                   1109: int
                   1110: atu_match(struct device *parent, void *match, void *aux)
                   1111: {
                   1112:        struct usb_attach_arg   *uaa = aux;
                   1113:        int                     i;
                   1114:
                   1115:        if (!uaa->iface)
                   1116:                return(UMATCH_NONE);
                   1117:
                   1118:        for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) {
                   1119:                struct atu_type *t = &atu_devs[i];
                   1120:
                   1121:                if (uaa->vendor == t->atu_vid &&
                   1122:                    uaa->product == t->atu_pid) {
                   1123:                        return(UMATCH_VENDOR_PRODUCT);
                   1124:                }
                   1125:        }
                   1126:        return(UMATCH_NONE);
                   1127: }
                   1128:
                   1129: int
                   1130: atu_media_change(struct ifnet *ifp)
                   1131: {
                   1132: #ifdef ATU_DEBUG
                   1133:        struct atu_softc        *sc = ifp->if_softc;
                   1134: #endif /* ATU_DEBUG */
                   1135:        int                     err;
                   1136:
                   1137:        DPRINTFN(10, ("%s: atu_media_change\n", sc->atu_dev.dv_xname));
                   1138:
                   1139:        err = ieee80211_media_change(ifp);
                   1140:        if (err == ENETRESET) {
                   1141:                if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
                   1142:                    (IFF_RUNNING|IFF_UP))
                   1143:                        atu_init(ifp);
                   1144:                err = 0;
                   1145:        }
                   1146:
                   1147:        return (err);
                   1148: }
                   1149:
                   1150: void
                   1151: atu_media_status(struct ifnet *ifp, struct ifmediareq *req)
                   1152: {
                   1153: #ifdef ATU_DEBUG
                   1154:        struct atu_softc        *sc = ifp->if_softc;
                   1155: #endif /* ATU_DEBUG */
                   1156:
                   1157:        DPRINTFN(10, ("%s: atu_media_status\n", sc->atu_dev.dv_xname));
                   1158:
                   1159:        ieee80211_media_status(ifp, req);
                   1160: }
                   1161:
                   1162: void
                   1163: atu_task(void *arg)
                   1164: {
                   1165:        struct atu_softc        *sc = (struct atu_softc *)arg;
                   1166:        struct ieee80211com     *ic = &sc->sc_ic;
                   1167:        struct ifnet            *ifp = &ic->ic_if;
                   1168:        usbd_status             err;
                   1169:        int                     s;
                   1170:
                   1171:        DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname));
                   1172:
                   1173:        if (sc->sc_state != ATU_S_OK)
                   1174:                return;
                   1175:
                   1176:        switch (sc->sc_cmd) {
                   1177:        case ATU_C_SCAN:
                   1178:
                   1179:                err = atu_start_scan(sc);
                   1180:                if (err) {
                   1181:                        DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n",
                   1182:                            sc->atu_dev.dv_xname));
                   1183:                        return;
                   1184:                }
                   1185:
                   1186:                err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
                   1187:                if (err) {
                   1188:                        DPRINTF(("%s: atu_init: error waiting for scan\n",
                   1189:                            sc->atu_dev.dv_xname));
                   1190:                        return;
                   1191:                }
                   1192:
                   1193:                DPRINTF(("%s: ==========================> END OF SCAN!\n",
                   1194:                    sc->atu_dev.dv_xname));
                   1195:
                   1196:                s = splnet();
                   1197:                /* ieee80211_next_scan(ifp); */
                   1198:                ieee80211_end_scan(ifp);
                   1199:                splx(s);
                   1200:
                   1201:                DPRINTF(("%s: ----------------------======> END OF SCAN2!\n",
                   1202:                    sc->atu_dev.dv_xname));
                   1203:                break;
                   1204:
                   1205:        case ATU_C_JOIN:
                   1206:                atu_join(sc, ic->ic_bss);
                   1207:        }
                   1208: }
                   1209:
                   1210: int
                   1211: atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   1212: {
                   1213:        struct ifnet            *ifp = &ic->ic_if;
                   1214:        struct atu_softc        *sc = ifp->if_softc;
                   1215:        enum ieee80211_state    ostate = ic->ic_state;
                   1216:
                   1217:        DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", sc->atu_dev.dv_xname,
                   1218:            ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
                   1219:
                   1220:        switch (nstate) {
                   1221:        case IEEE80211_S_SCAN:
                   1222:                memcpy(ic->ic_chan_scan, ic->ic_chan_active,
                   1223:                    sizeof(ic->ic_chan_active));
                   1224:                ieee80211_free_allnodes(ic);
                   1225:
                   1226:                /* tell the event thread that we want a scan */
                   1227:                sc->sc_cmd = ATU_C_SCAN;
                   1228:                usb_add_task(sc->atu_udev, &sc->sc_task);
                   1229:
                   1230:                /* handle this ourselves */
                   1231:                ic->ic_state = nstate;
                   1232:                return (0);
                   1233:
                   1234:        case IEEE80211_S_AUTH:
                   1235:        case IEEE80211_S_RUN:
                   1236:                if (ostate == IEEE80211_S_SCAN) {
                   1237:                        sc->sc_cmd = ATU_C_JOIN;
                   1238:                        usb_add_task(sc->atu_udev, &sc->sc_task);
                   1239:                }
                   1240:                break;
                   1241:        default:
                   1242:                /* nothing to do */
                   1243:                break;
                   1244:        }
                   1245:
                   1246:        return (*sc->sc_newstate)(ic, nstate, arg);
                   1247: }
                   1248:
                   1249: /*
                   1250:  * Attach the interface. Allocate softc structures, do
                   1251:  * setup and ethernet/BPF attach.
                   1252:  */
                   1253: void
                   1254: atu_attach(struct device *parent, struct device *self, void *aux)
                   1255: {
                   1256:        struct atu_softc                *sc = (struct atu_softc *)self;
                   1257:        struct usb_attach_arg           *uaa = aux;
                   1258:        char                            *devinfop;
                   1259:        usbd_status                     err;
                   1260:        usbd_device_handle              dev = uaa->device;
                   1261:        u_int8_t                        mode, channel;
                   1262:        int i;
                   1263:
                   1264:        sc->sc_state = ATU_S_UNCONFIG;
                   1265:
                   1266:        devinfop = usbd_devinfo_alloc(dev, 0);
                   1267:        printf("\n%s: %s", sc->atu_dev.dv_xname, devinfop);
                   1268:        usbd_devinfo_free(devinfop);
                   1269:
                   1270:        err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1);
                   1271:        if (err) {
                   1272:                printf("%s: setting config no failed\n",
                   1273:                    sc->atu_dev.dv_xname);
                   1274:                return;
                   1275:        }
                   1276:
                   1277:        err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface);
                   1278:        if (err) {
                   1279:                printf("%s: getting interface handle failed\n",
                   1280:                    sc->atu_dev.dv_xname);
                   1281:                return;
                   1282:        }
                   1283:
                   1284:        sc->atu_unit = self->dv_unit;
                   1285:        sc->atu_udev = dev;
                   1286:
                   1287:        /*
                   1288:         * look up the radio_type for the device
                   1289:         * basically does the same as USB_MATCH
                   1290:         */
                   1291:        for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) {
                   1292:                struct atu_type *t = &atu_devs[i];
                   1293:
                   1294:                if (uaa->vendor == t->atu_vid &&
                   1295:                    uaa->product == t->atu_pid) {
                   1296:                        sc->atu_radio = t->atu_radio;
                   1297:                        sc->atu_quirk = t->atu_quirk;
                   1298:                }
                   1299:        }
                   1300:
                   1301:        /*
                   1302:         * Check in the interface descriptor if we're in DFU mode
                   1303:         * If we're in DFU mode, we upload the external firmware
                   1304:         * If we're not, the PC must have rebooted without power-cycling
                   1305:         * the device.. I've tried this out, a reboot only requeres the
                   1306:         * external firmware to be reloaded :)
                   1307:         *
                   1308:         * Hmm. The at76c505a doesn't report a DFU descriptor when it's
                   1309:         * in DFU mode... Let's just try to get the opmode
                   1310:         */
                   1311:        err = atu_get_opmode(sc, &mode);
                   1312:        DPRINTFN(20, ("%s: opmode: %d\n", sc->atu_dev.dv_xname, mode));
                   1313:        if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) {
                   1314:                DPRINTF(("%s: starting internal firmware download\n",
                   1315:                    sc->atu_dev.dv_xname));
                   1316:
                   1317:                printf("\n");
                   1318:
                   1319:                if (rootvp == NULL)
                   1320:                        mountroothook_establish(atu_internal_firmware, sc);
                   1321:                else
                   1322:                        atu_internal_firmware(sc);
                   1323:                /*
                   1324:                 * atu_internal_firmware will cause a reset of the device
                   1325:                 * so we don't want to do any more configuration after this
                   1326:                 * point.
                   1327:                 */
                   1328:                return;
                   1329:        }
                   1330:
                   1331:        uaa->iface = sc->atu_iface;
                   1332:
                   1333:        if (mode != MODE_NETCARD) {
                   1334:                DPRINTFN(15, ("%s: device needs external firmware\n",
                   1335:                    sc->atu_dev.dv_xname));
                   1336:
                   1337:                if (mode != MODE_NOFLASHNETCARD) {
                   1338:                        DPRINTF(("%s: EEK! unexpected opmode=%d\n",
                   1339:                            sc->atu_dev.dv_xname, mode));
                   1340:                }
                   1341:
                   1342:                /*
                   1343:                 * There is no difference in opmode before and after external
                   1344:                 * firmware upload with the SMC2662 V.4 . So instead we'll try
                   1345:                 * to read the channel number. If we succeed, external
                   1346:                 * firmwaremust have been already uploaded...
                   1347:                 */
                   1348:                if (sc->atu_radio != RadioIntersil) {
                   1349:                        err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel);
                   1350:                        if (!err) {
                   1351:                                DPRINTF(("%s: external firmware has already"
                   1352:                                    " been downloaded\n",
                   1353:                                    sc->atu_dev.dv_xname));
                   1354:                                atu_complete_attach(sc);
                   1355:                                return;
                   1356:                        }
                   1357:                }
                   1358:
                   1359:                if (rootvp == NULL)
                   1360:                        mountroothook_establish(atu_external_firmware, sc);
                   1361:                else
                   1362:                        atu_external_firmware(sc);
                   1363:
                   1364:                /*
                   1365:                 * atu_external_firmware will call atu_complete_attach after
                   1366:                 * it's finished so we can just return.
                   1367:                 */
                   1368:        } else {
                   1369:                /* all the firmwares are in place, so complete the attach */
                   1370:                atu_complete_attach(sc);
                   1371:        }
                   1372: }
                   1373:
                   1374: void
                   1375: atu_complete_attach(struct atu_softc *sc)
                   1376: {
                   1377:        struct ieee80211com             *ic = &sc->sc_ic;
                   1378:        struct ifnet                    *ifp = &ic->ic_if;
                   1379:        usb_interface_descriptor_t      *id;
                   1380:        usb_endpoint_descriptor_t       *ed;
                   1381:        usbd_status                     err;
                   1382:        int                             i;
                   1383: #ifdef ATU_DEBUG
                   1384:        struct atu_fw                   fw;
                   1385: #endif
                   1386:
                   1387:        id = usbd_get_interface_descriptor(sc->atu_iface);
                   1388:
                   1389:        /* Find endpoints. */
                   1390:        for (i = 0; i < id->bNumEndpoints; i++) {
                   1391:                ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
                   1392:                if (!ed) {
                   1393:                        DPRINTF(("%s: num_endp:%d\n", sc->atu_dev.dv_xname,
                   1394:                            sc->atu_iface->idesc->bNumEndpoints));
                   1395:                        DPRINTF(("%s: couldn't get ep %d\n",
                   1396:                            sc->atu_dev.dv_xname, i));
                   1397:                        return;
                   1398:                }
                   1399:                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                   1400:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                   1401:                        sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress;
                   1402:                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                   1403:                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                   1404:                        sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress;
                   1405:                }
                   1406:        }
                   1407:
                   1408:        /* read device config & get MAC address */
                   1409:        err = atu_get_card_config(sc);
                   1410:        if (err) {
                   1411:                printf("\n%s: could not get card cfg!\n",
                   1412:                    sc->atu_dev.dv_xname);
                   1413:                return;
                   1414:        }
                   1415:
                   1416: #ifdef ATU_DEBUG
                   1417:        /* DEBUG : try to get firmware version */
                   1418:        err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0,
                   1419:            (u_int8_t *)&fw);
                   1420:        if (!err) {
                   1421:                DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
                   1422:                    "build:%d\n", sc->atu_dev.dv_xname, fw.major, fw.minor,
                   1423:                    fw.patch, fw.build));
                   1424:        } else {
                   1425:                DPRINTF(("%s: get firmware version failed\n",
                   1426:                    sc->atu_dev.dv_xname));
                   1427:        }
                   1428: #endif /* ATU_DEBUG */
                   1429:
                   1430:        /* Show the world our MAC address */
                   1431:        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
                   1432:
                   1433:        sc->atu_cdata.atu_tx_inuse = 0;
                   1434:
                   1435:        bzero(sc->atu_bssid, ETHER_ADDR_LEN);
                   1436:        sc->atu_channel = ATU_DEFAULT_CHANNEL;
                   1437:        sc->atu_desired_channel = IEEE80211_CHAN_ANY;
                   1438:        sc->atu_mode = INFRASTRUCTURE_MODE;
                   1439:
                   1440:        ic->ic_softc = sc;
                   1441:        ic->ic_phytype = IEEE80211_T_DS;
                   1442:        ic->ic_opmode = IEEE80211_M_STA;
                   1443:        ic->ic_state = IEEE80211_S_INIT;
                   1444:        ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL;
                   1445:        ic->ic_max_rssi = atu_radfirm[sc->atu_radio].max_rssi;
                   1446:
                   1447:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                   1448:
                   1449:        for (i = 1; i <= 14; i++) {
                   1450:                ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B |
                   1451:                    IEEE80211_CHAN_PASSIVE;
                   1452:                ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
                   1453:                    ic->ic_channels[i].ic_flags);
                   1454:        }
                   1455:
                   1456:        ic->ic_ibss_chan = &ic->ic_channels[0];
                   1457:
                   1458:        ifp->if_softc = sc;
                   1459:        memcpy(ifp->if_xname, sc->atu_dev.dv_xname, IFNAMSIZ);
                   1460:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                   1461:        ifp->if_start = atu_start;
                   1462:        ifp->if_ioctl = atu_ioctl;
                   1463:        ifp->if_watchdog = atu_watchdog;
                   1464:        ifp->if_mtu = ATU_DEFAULT_MTU;
                   1465:        IFQ_SET_READY(&ifp->if_snd);
                   1466:
                   1467:        /* Call MI attach routine. */
                   1468:        if_attach(ifp);
                   1469:        ieee80211_ifattach(ifp);
                   1470:
                   1471:        sc->sc_newstate = ic->ic_newstate;
                   1472:        ic->ic_newstate = atu_newstate;
                   1473:
                   1474:        /* setup ifmedia interface */
                   1475:        ieee80211_media_init(ifp, atu_media_change, atu_media_status);
                   1476:
                   1477:        usb_init_task(&sc->sc_task, atu_task, sc);
                   1478:
                   1479: #if NBPFILTER > 0
                   1480:        bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
                   1481:            sizeof(struct ieee80211_frame) + 64);
                   1482:
                   1483:        bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu));
                   1484:        sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
                   1485:        sc->sc_rxtap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT);
                   1486:
                   1487:        bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu));
                   1488:        sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
                   1489:        sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT);
                   1490: #endif
                   1491:
                   1492:        sc->sc_state = ATU_S_OK;
                   1493: }
                   1494:
                   1495: int
                   1496: atu_detach(struct device *self, int flags)
                   1497: {
                   1498:        struct atu_softc        *sc = (struct atu_softc *)self;
                   1499:        struct ifnet            *ifp = &sc->sc_ic.ic_if;
                   1500:
                   1501:        DPRINTFN(10, ("%s: atu_detach state=%d\n", sc->atu_dev.dv_xname,
                   1502:            sc->sc_state));
                   1503:
                   1504:        if (sc->sc_state != ATU_S_UNCONFIG) {
                   1505:                atu_stop(ifp, 1);
                   1506:                ieee80211_ifdetach(ifp);
                   1507:                if_detach(ifp);
                   1508:
                   1509:                if (sc->atu_ep[ATU_ENDPT_TX] != NULL)
                   1510:                        usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
                   1511:                if (sc->atu_ep[ATU_ENDPT_RX] != NULL)
                   1512:                        usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
                   1513:
                   1514:                usb_rem_task(sc->atu_udev, &sc->sc_task);
                   1515:        }
                   1516:
                   1517:        return(0);
                   1518: }
                   1519:
                   1520: int
                   1521: atu_activate(struct device *self, enum devact act)
                   1522: {
                   1523:        struct atu_softc *sc = (struct atu_softc *)self;
                   1524:
                   1525:        switch (act) {
                   1526:        case DVACT_ACTIVATE:
                   1527:                break;
                   1528:        case DVACT_DEACTIVATE:
                   1529:                if (sc->sc_state != ATU_S_UNCONFIG)
                   1530:                        sc->sc_state = ATU_S_DEAD;
                   1531:                break;
                   1532:        }
                   1533:        return (0);
                   1534: }
                   1535:
                   1536: /*
                   1537:  * Initialize an RX descriptor and attach an MBUF cluster.
                   1538:  */
                   1539: int
                   1540: atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
                   1541: {
                   1542:        struct mbuf             *m_new = NULL;
                   1543:
                   1544:        if (m == NULL) {
                   1545:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
                   1546:                if (m_new == NULL) {
                   1547:                        DPRINTF(("%s: no memory for rx list\n",
                   1548:                            sc->atu_dev.dv_xname));
                   1549:                        return(ENOBUFS);
                   1550:                }
                   1551:
                   1552:                MCLGET(m_new, M_DONTWAIT);
                   1553:                if (!(m_new->m_flags & M_EXT)) {
                   1554:                        DPRINTF(("%s: no memory for rx list\n",
                   1555:                            sc->atu_dev.dv_xname));
                   1556:                        m_freem(m_new);
                   1557:                        return(ENOBUFS);
                   1558:                }
                   1559:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                   1560:        } else {
                   1561:                m_new = m;
                   1562:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                   1563:                m_new->m_data = m_new->m_ext.ext_buf;
                   1564:        }
                   1565:        c->atu_mbuf = m_new;
                   1566:        return(0);
                   1567: }
                   1568:
                   1569: int
                   1570: atu_rx_list_init(struct atu_softc *sc)
                   1571: {
                   1572:        struct atu_cdata        *cd = &sc->atu_cdata;
                   1573:        struct atu_chain        *c;
                   1574:        int                     i;
                   1575:
                   1576:        DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
                   1577:            sc->atu_dev.dv_xname));
                   1578:
                   1579:        for (i = 0; i < ATU_RX_LIST_CNT; i++) {
                   1580:                c = &cd->atu_rx_chain[i];
                   1581:                c->atu_sc = sc;
                   1582:                c->atu_idx = i;
                   1583:                if (c->atu_xfer == NULL) {
                   1584:                        c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
                   1585:                        if (c->atu_xfer == NULL)
                   1586:                                return (ENOBUFS);
                   1587:                        c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
                   1588:                            ATU_RX_BUFSZ);
                   1589:                        if (c->atu_buf == NULL) /* XXX free xfer */
                   1590:                                return (ENOBUFS);
                   1591:                        if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
                   1592:                                return(ENOBUFS);
                   1593:                }
                   1594:        }
                   1595:        return (0);
                   1596: }
                   1597:
                   1598: int
                   1599: atu_tx_list_init(struct atu_softc *sc)
                   1600: {
                   1601:        struct atu_cdata        *cd = &sc->atu_cdata;
                   1602:        struct atu_chain        *c;
                   1603:        int                     i;
                   1604:
                   1605:        DPRINTFN(15, ("%s: atu_tx_list_init\n",
                   1606:            sc->atu_dev.dv_xname));
                   1607:
                   1608:        SLIST_INIT(&cd->atu_tx_free);
                   1609:        sc->atu_cdata.atu_tx_inuse = 0;
                   1610:
                   1611:        for (i = 0; i < ATU_TX_LIST_CNT; i++) {
                   1612:                c = &cd->atu_tx_chain[i];
                   1613:                c->atu_sc = sc;
                   1614:                c->atu_idx = i;
                   1615:                if (c->atu_xfer == NULL) {
                   1616:                        c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
                   1617:                        if (c->atu_xfer == NULL)
                   1618:                                return(ENOBUFS);
                   1619:                        c->atu_mbuf = NULL;
                   1620:                        c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
                   1621:                            ATU_TX_BUFSZ);
                   1622:                        if (c->atu_buf == NULL)
                   1623:                                return(ENOBUFS); /* XXX free xfer */
                   1624:                        SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list);
                   1625:                }
                   1626:        }
                   1627:        return(0);
                   1628: }
                   1629:
                   1630: void
                   1631: atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
                   1632:     int listlen)
                   1633: {
                   1634:        int                     i;
                   1635:
                   1636:        /* Free resources. */
                   1637:        for (i = 0; i < listlen; i++) {
                   1638:                if (ch[i].atu_buf != NULL)
                   1639:                        ch[i].atu_buf = NULL;
                   1640:                if (ch[i].atu_mbuf != NULL) {
                   1641:                        m_freem(ch[i].atu_mbuf);
                   1642:                        ch[i].atu_mbuf = NULL;
                   1643:                }
                   1644:                if (ch[i].atu_xfer != NULL) {
                   1645:                        usbd_free_xfer(ch[i].atu_xfer);
                   1646:                        ch[i].atu_xfer = NULL;
                   1647:                }
                   1648:        }
                   1649: }
                   1650:
                   1651: /*
                   1652:  * A frame has been uploaded: pass the resulting mbuf chain up to
                   1653:  * the higher level protocols.
                   1654:  */
                   1655: void
                   1656: atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   1657: {
                   1658:        struct atu_chain        *c = (struct atu_chain *)priv;
                   1659:        struct atu_softc        *sc = c->atu_sc;
                   1660:        struct ieee80211com     *ic = &sc->sc_ic;
                   1661:        struct ifnet            *ifp = &ic->ic_if;
                   1662:        struct atu_rx_hdr       *h;
                   1663:        struct ieee80211_frame  *wh;
                   1664:        struct ieee80211_node   *ni;
                   1665:        struct mbuf             *m;
                   1666:        u_int32_t               len;
                   1667:        int                     s;
                   1668:
                   1669:        DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname));
                   1670:
                   1671:        if (sc->sc_state != ATU_S_OK)
                   1672:                return;
                   1673:
                   1674:        if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
                   1675:                goto done;
                   1676:
                   1677:        if (status != USBD_NORMAL_COMPLETION) {
                   1678:                DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
                   1679:                    sc->atu_dev.dv_xname));
                   1680:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                   1681:                        return;
                   1682:                }
                   1683: #if 0
                   1684:                if (status == USBD_IOERROR) {
                   1685:                        DPRINTF(("%s: rx: EEK! lost device?\n",
                   1686:                            sc->atu_dev.dv_xname));
                   1687:
                   1688:                        /*
                   1689:                         * My experience with USBD_IOERROR is that trying to
                   1690:                         * restart the transfer will always fail and we'll
                   1691:                         * keep on looping restarting transfers untill someone
                   1692:                         * pulls the plug of the device.
                   1693:                         * So we don't restart the transfer, but just let it
                   1694:                         * die... If someone knows of a situation where we can
                   1695:                         * recover from USBD_IOERROR, let me know.
                   1696:                         */
                   1697:                        splx(s);
                   1698:                        return;
                   1699:                }
                   1700: #endif /* 0 */
                   1701:
                   1702:                if (usbd_ratecheck(&sc->atu_rx_notice)) {
                   1703:                        DPRINTF(("%s: usb error on rx: %s\n",
                   1704:                            sc->atu_dev.dv_xname, usbd_errstr(status)));
                   1705:                }
                   1706:                if (status == USBD_STALLED)
                   1707:                        usbd_clear_endpoint_stall_async(
                   1708:                            sc->atu_ep[ATU_ENDPT_RX]);
                   1709:                goto done;
                   1710:        }
                   1711:
                   1712:        usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
                   1713:
                   1714:        if (len <= 1) {
                   1715:                DPRINTF(("%s: atu_rxeof: too short\n",
                   1716:                    sc->atu_dev.dv_xname));
                   1717:                goto done;
                   1718:        }
                   1719:
                   1720:        h = (struct atu_rx_hdr *)c->atu_buf;
                   1721:        len = UGETW(h->length) - 4; /* XXX magic number */
                   1722:
                   1723:        m = c->atu_mbuf;
                   1724:        memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len);
                   1725:        m->m_pkthdr.rcvif = ifp;
                   1726:        m->m_pkthdr.len = m->m_len = len;
                   1727:
                   1728:        wh = mtod(m, struct ieee80211_frame *);
                   1729:        ni = ieee80211_find_rxnode(ic, wh);
                   1730:
                   1731:        ifp->if_ipackets++;
                   1732:
                   1733:        s = splnet();
                   1734:
                   1735:        if (atu_newbuf(sc, c, NULL) == ENOBUFS) {
                   1736:                ifp->if_ierrors++;
                   1737:                goto done1; /* XXX if we can't allocate, why restart it? */
                   1738:        }
                   1739:
                   1740: #if NBPFILTER > 0
                   1741:        if (sc->sc_radiobpf != NULL) {
                   1742:                struct mbuf mb;
                   1743:                struct atu_rx_radiotap_header *rr = &sc->sc_rxtap;
                   1744:
                   1745:                rr->rr_flags = 0;
                   1746:                rr->rr_chan_freq =
                   1747:                    htole16(ic->ic_bss->ni_chan->ic_freq);
                   1748:                rr->rr_chan_flags =
                   1749:                    htole16(ic->ic_bss->ni_chan->ic_flags);
                   1750:                rr->rr_rssi = h->rssi;
                   1751:                rr->rr_max_rssi = ic->ic_max_rssi;
                   1752:
                   1753:                mb.m_data = (caddr_t)rr;
                   1754:                mb.m_len = sizeof(sc->sc_txtapu);
                   1755:                mb.m_next = m;
                   1756:                mb.m_nextpkt = NULL;
                   1757:                mb.m_type = 0;
                   1758:                mb.m_flags = 0;
                   1759:                bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
                   1760:        }
                   1761: #endif /* NPBFILTER > 0 */
                   1762:
                   1763:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   1764:                /*
                   1765:                 * WEP is decrypted by hardware. Clear WEP bit
                   1766:                 * header for ieee80211_input().
                   1767:                 */
                   1768:                wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
                   1769:        }
                   1770:
                   1771:        ieee80211_input(ifp, m, ni, h->rssi, UGETDW(h->rx_time));
                   1772:
                   1773:        ieee80211_release_node(ic, ni);
                   1774: done1:
                   1775:        splx(s);
                   1776: done:
                   1777:        /* Setup new transfer. */
                   1778:        usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf,
                   1779:            ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
                   1780:                atu_rxeof);
                   1781:        usbd_transfer(c->atu_xfer);
                   1782: }
                   1783:
                   1784: /*
                   1785:  * A frame was downloaded to the chip. It's safe for us to clean up
                   1786:  * the list buffers.
                   1787:  */
                   1788: void
                   1789: atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   1790: {
                   1791:        struct atu_chain        *c = (struct atu_chain *)priv;
                   1792:        struct atu_softc        *sc = c->atu_sc;
                   1793:        struct ifnet            *ifp = &sc->sc_ic.ic_if;
                   1794:        usbd_status             err;
                   1795:        int                     s;
                   1796:
                   1797:        DPRINTFN(25, ("%s: atu_txeof status=%d\n", sc->atu_dev.dv_xname,
                   1798:            status));
                   1799:
                   1800:        if (c->atu_mbuf != NULL) {
                   1801:                m_freem(c->atu_mbuf);
                   1802:                c->atu_mbuf = NULL;
                   1803:        }
                   1804:
                   1805:        if (status != USBD_NORMAL_COMPLETION) {
                   1806:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                   1807:                        return;
                   1808:
                   1809:                DPRINTF(("%s: usb error on tx: %s\n", sc->atu_dev.dv_xname,
                   1810:                    usbd_errstr(status)));
                   1811:                if (status == USBD_STALLED)
                   1812:                        usbd_clear_endpoint_stall_async(sc->atu_ep[ATU_ENDPT_TX]);
                   1813:                return;
                   1814:        }
                   1815:
                   1816:        usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err);
                   1817:
                   1818:        if (err)
                   1819:                ifp->if_oerrors++;
                   1820:        else
                   1821:                ifp->if_opackets++;
                   1822:
                   1823:        s = splnet();
                   1824:        SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list);
                   1825:        sc->atu_cdata.atu_tx_inuse--;
                   1826:        if (sc->atu_cdata.atu_tx_inuse == 0)
                   1827:                ifp->if_timer = 0;
                   1828:        ifp->if_flags &= ~IFF_OACTIVE;
                   1829:        splx(s);
                   1830:
                   1831:        atu_start(ifp);
                   1832: }
                   1833:
                   1834: u_int8_t
                   1835: atu_calculate_padding(int size)
                   1836: {
                   1837:        size %= 64;
                   1838:
                   1839:        if (size < 50)
                   1840:                return (50 - size);
                   1841:        if (size >=61)
                   1842:                return (64 + 50 - size);
                   1843:        return (0);
                   1844: }
                   1845:
                   1846: int
                   1847: atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
                   1848:     struct atu_chain *c, struct mbuf *m)
                   1849: {
                   1850:        int                     len;
                   1851:        struct atu_tx_hdr       *h;
                   1852:        usbd_status             err;
                   1853:        u_int8_t                pad;
                   1854: #if NBPFILTER > 0
                   1855:        struct ieee80211com *ic = &sc->sc_ic;
                   1856: #endif
                   1857:
                   1858:        DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname));
                   1859:
                   1860:        /* Don't try to send when we're shutting down the driver */
                   1861:        if (sc->sc_state != ATU_S_OK) {
                   1862:                m_freem(m);
                   1863:                return(EIO);
                   1864:        }
                   1865:
                   1866: #if NBPFILTER > 0
                   1867:        if (sc->sc_radiobpf != NULL) {
                   1868:                struct mbuf mb;
                   1869:                struct atu_tx_radiotap_header *rt = &sc->sc_txtap;
                   1870:
                   1871:                rt->rt_flags = 0;
                   1872:                rt->rt_chan_freq =
                   1873:                    htole16(ic->ic_bss->ni_chan->ic_freq);
                   1874:                rt->rt_chan_flags =
                   1875:                    htole16(ic->ic_bss->ni_chan->ic_flags);
                   1876:
                   1877:                mb.m_data = (caddr_t)rt;
                   1878:                mb.m_len = sizeof(sc->sc_txtapu);
                   1879:                mb.m_next = m;
                   1880:                mb.m_nextpkt = NULL;
                   1881:                mb.m_type = 0;
                   1882:                mb.m_flags = 0;
                   1883:                bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
                   1884:        }
                   1885: #endif
                   1886:
                   1887:        /*
                   1888:         * Copy the mbuf data into a contiguous buffer, leaving
                   1889:         * enough room for the atmel headers
                   1890:         */
                   1891:        len = m->m_pkthdr.len;
                   1892:
                   1893:        m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN);
                   1894:
                   1895:        h = (struct atu_tx_hdr *)c->atu_buf;
                   1896:        memset(h, 0, ATU_TX_HDRLEN);
                   1897:        USETW(h->length, len);
                   1898:        h->tx_rate = 4; /* XXX rate = auto */
                   1899:        len += ATU_TX_HDRLEN;
                   1900:
                   1901:        pad = atu_calculate_padding(len);
                   1902:        len += pad;
                   1903:        h->padding = pad;
                   1904:
                   1905:        c->atu_length = len;
                   1906:        c->atu_mbuf = m;
                   1907:
                   1908:        usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX],
                   1909:            c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT,
                   1910:            atu_txeof);
                   1911:
                   1912:        /* Let's get this thing into the air! */
                   1913:        c->atu_in_xfer = 1;
                   1914:        err = usbd_transfer(c->atu_xfer);
                   1915:        if (err != USBD_IN_PROGRESS) {
                   1916:                DPRINTFN(25, ("%s: atu_tx_start: err=%d\n",
                   1917:                    sc->atu_dev.dv_xname, err));
                   1918:                c->atu_mbuf = NULL;
                   1919:                m_freem(m);
                   1920:                return(EIO);
                   1921:        }
                   1922:
                   1923:        return (0);
                   1924: }
                   1925:
                   1926: void
                   1927: atu_start(struct ifnet *ifp)
                   1928: {
                   1929:        struct atu_softc        *sc = ifp->if_softc;
                   1930:        struct ieee80211com     *ic = &sc->sc_ic;
                   1931:        struct atu_cdata        *cd = &sc->atu_cdata;
                   1932:        struct ieee80211_node   *ni;
                   1933:        struct ieee80211_frame  *wh;
                   1934:        struct atu_chain        *c;
                   1935:        struct mbuf             *m = NULL;
                   1936:        int                     s;
                   1937:
                   1938:        DPRINTFN(25, ("%s: atu_start: enter\n", sc->atu_dev.dv_xname));
                   1939:
                   1940:        if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
                   1941:                DPRINTFN(30, ("%s: atu_start: not running or up\n",
                   1942:                    sc->atu_dev.dv_xname));
                   1943:                return;
                   1944:        }
                   1945:
                   1946:        if (ifp->if_flags & IFF_OACTIVE) {
                   1947:                DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n",
                   1948:                    sc->atu_dev.dv_xname));
                   1949:                return;
                   1950:        }
                   1951:
                   1952:        for (;;) {
                   1953:                /* grab a TX buffer */
                   1954:                s = splnet();
                   1955:                c = SLIST_FIRST(&cd->atu_tx_free);
                   1956:                if (c != NULL) {
                   1957:                        SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list);
                   1958:                        cd->atu_tx_inuse++;
                   1959:                        if (cd->atu_tx_inuse == ATU_TX_LIST_CNT)
                   1960:                                ifp->if_flags |= IFF_OACTIVE;
                   1961:                }
                   1962:                splx(s);
                   1963:                if (c == NULL) {
                   1964:                        DPRINTFN(10, ("%s: out of tx xfers\n",
                   1965:                            sc->atu_dev.dv_xname));
                   1966:                        ifp->if_flags |= IFF_OACTIVE;
                   1967:                        break;
                   1968:                }
                   1969:
                   1970:                /*
                   1971:                 * Poll the management queue for frames, it has priority over
                   1972:                 * normal data frames.
                   1973:                 */
                   1974:                IF_DEQUEUE(&ic->ic_mgtq, m);
                   1975:                if (m == NULL) {
                   1976:                        DPRINTFN(10, ("%s: atu_start: data packet\n",
                   1977:                            sc->atu_dev.dv_xname));
                   1978:                        if (ic->ic_state != IEEE80211_S_RUN) {
                   1979:                                DPRINTFN(25, ("%s: no data till running\n",
                   1980:                                    sc->atu_dev.dv_xname));
                   1981:                                /* put the xfer back on the list */
                   1982:                                s = splnet();
                   1983:                                SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
                   1984:                                    atu_list);
                   1985:                                cd->atu_tx_inuse--;
                   1986:                                splx(s);
                   1987:                                break;
                   1988:                        }
                   1989:
                   1990:                        IFQ_DEQUEUE(&ifp->if_snd, m);
                   1991:                        if (m == NULL) {
                   1992:                                DPRINTFN(25, ("%s: nothing to send\n",
                   1993:                                    sc->atu_dev.dv_xname));
                   1994:                                s = splnet();
                   1995:                                SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
                   1996:                                    atu_list);
                   1997:                                cd->atu_tx_inuse--;
                   1998:                                splx(s);
                   1999:                                break;
                   2000:                        }
                   2001:
                   2002: #if NBPFILTER > 0
                   2003:                        if (ifp->if_bpf)
                   2004:                                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
                   2005: #endif
                   2006:
                   2007:                        m = ieee80211_encap(ifp, m, &ni);
                   2008:                        if (m == NULL)
                   2009:                                goto bad;
                   2010:                        wh = mtod(m, struct ieee80211_frame *);
                   2011:
                   2012: #if NBPFILTER > 0
                   2013:                        if (ic->ic_rawbpf != NULL)
                   2014:                                bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
                   2015: #endif
                   2016:                } else {
                   2017:                        DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
                   2018:                            sc->atu_dev.dv_xname));
                   2019:
                   2020:                        /*
                   2021:                         * Hack!  The referenced node pointer is in the
                   2022:                         * rcvif field of the packet header.  This is
                   2023:                         * placed there by ieee80211_mgmt_output because
                   2024:                         * we need to hold the reference with the frame
                   2025:                         * and there's no other way (other than packet
                   2026:                         * tags which we consider too expensive to use)
                   2027:                         * to pass it along.
                   2028:                         */
                   2029:                        ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
                   2030:                        m->m_pkthdr.rcvif = NULL;
                   2031:
                   2032:                        wh = mtod(m, struct ieee80211_frame *);
                   2033:                        /* sc->sc_stats.ast_tx_mgmt++; */
                   2034:                }
                   2035:
                   2036:                if (atu_tx_start(sc, ni, c, m)) {
                   2037: bad:
                   2038:                        s = splnet();
                   2039:                        SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
                   2040:                            atu_list);
                   2041:                        cd->atu_tx_inuse--;
                   2042:                        splx(s);
                   2043:                        /* ifp_if_oerrors++; */
                   2044:                        if (ni != NULL)
                   2045:                                ieee80211_release_node(ic, ni);
                   2046:                        continue;
                   2047:                }
                   2048:                ifp->if_timer = 5;
                   2049:        }
                   2050: }
                   2051:
                   2052: int
                   2053: atu_init(struct ifnet *ifp)
                   2054: {
                   2055:        struct atu_softc        *sc = ifp->if_softc;
                   2056:        struct ieee80211com     *ic = &sc->sc_ic;
                   2057:        struct atu_chain        *c;
                   2058:        usbd_status             err;
                   2059:        int                     i, s;
                   2060:
                   2061:        s = splnet();
                   2062:
                   2063:        DPRINTFN(10, ("%s: atu_init\n", sc->atu_dev.dv_xname));
                   2064:
                   2065:        if (ifp->if_flags & IFF_RUNNING) {
                   2066:                splx(s);
                   2067:                return(0);
                   2068:        }
                   2069:
                   2070:        /* Init TX ring */
                   2071:        if (atu_tx_list_init(sc))
                   2072:                printf("%s: tx list init failed\n", sc->atu_dev.dv_xname);
                   2073:
                   2074:        /* Init RX ring */
                   2075:        if (atu_rx_list_init(sc))
                   2076:                printf("%s: rx list init failed\n", sc->atu_dev.dv_xname);
                   2077:
                   2078:        /* Load the multicast filter. */
                   2079:        /*atu_setmulti(sc); */
                   2080:
                   2081:        /* Open RX and TX pipes. */
                   2082:        err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX],
                   2083:            USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]);
                   2084:        if (err) {
                   2085:                DPRINTF(("%s: open rx pipe failed: %s\n",
                   2086:                    sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2087:                splx(s);
                   2088:                return(EIO);
                   2089:        }
                   2090:
                   2091:        err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX],
                   2092:            USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]);
                   2093:        if (err) {
                   2094:                DPRINTF(("%s: open tx pipe failed: %s\n",
                   2095:                    sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2096:                splx(s);
                   2097:                return(EIO);
                   2098:        }
                   2099:
                   2100:        /* Start up the receive pipe. */
                   2101:        for (i = 0; i < ATU_RX_LIST_CNT; i++) {
                   2102:                c = &sc->atu_cdata.atu_rx_chain[i];
                   2103:
                   2104:                usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c,
                   2105:                    c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
                   2106:                    USBD_NO_TIMEOUT, atu_rxeof);
                   2107:                usbd_transfer(c->atu_xfer);
                   2108:        }
                   2109:
                   2110:        DPRINTFN(10, ("%s: starting up using MAC=%s\n",
                   2111:            sc->atu_dev.dv_xname, ether_sprintf(ic->ic_myaddr)));
                   2112:
                   2113:        /* Do initial setup */
                   2114:        err = atu_initial_config(sc);
                   2115:        if (err) {
                   2116:                DPRINTF(("%s: initial config failed!\n",
                   2117:                    sc->atu_dev.dv_xname));
                   2118:                splx(s);
                   2119:                return(EIO);
                   2120:        }
                   2121:        DPRINTFN(10, ("%s: initialised transceiver\n",
                   2122:            sc->atu_dev.dv_xname));
                   2123:
                   2124:        /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
                   2125:
                   2126:        /* If we want promiscuous mode, set the allframes bit. */
                   2127:        /*
                   2128:        if (ifp->if_flags & IFF_PROMISC)
                   2129:                sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
                   2130:        */
                   2131:
                   2132:        ifp->if_flags |= IFF_RUNNING;
                   2133:        ifp->if_flags &= ~IFF_OACTIVE;
                   2134:        splx(s);
                   2135:
                   2136:        /* XXX the following HAS to be replaced */
                   2137:        s = splnet();
                   2138:        err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   2139:        if (err)
                   2140:                DPRINTFN(1, ("%s: atu_init: error calling "
                   2141:                    "ieee80211_net_state", sc->atu_dev.dv_xname));
                   2142:        splx(s);
                   2143:
                   2144:        return 0;
                   2145: }
                   2146:
                   2147: int
                   2148: atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
                   2149: {
                   2150:        struct atu_softc        *sc = ifp->if_softc;
                   2151:        struct ifaddr           *ifa;
                   2152:        int                     err = 0, s;
                   2153:
                   2154:        s = splnet();
                   2155:        switch (command) {
                   2156:        case SIOCSIFADDR:
                   2157:                DPRINTFN(15, ("%s: SIOCSIFADDR\n", sc->atu_dev.dv_xname));
                   2158:
                   2159:                ifa = (struct ifaddr *)data;
                   2160:                ifp->if_flags |= IFF_UP;
                   2161:                atu_init(ifp);
                   2162:
                   2163:                switch (ifa->ifa_addr->sa_family) {
                   2164: #ifdef INET
                   2165:                case AF_INET:
                   2166:                        arp_ifinit(&sc->sc_ic.ic_ac, ifa);
                   2167:                        break;
                   2168: #endif /* INET */
                   2169:                }
                   2170:                break;
                   2171:
                   2172:        case SIOCSIFFLAGS:
                   2173:                DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", sc->atu_dev.dv_xname));
                   2174:
                   2175:                if (ifp->if_flags & IFF_UP) {
                   2176:                        if (ifp->if_flags & IFF_RUNNING &&
                   2177:                            ifp->if_flags & IFF_PROMISC &&
                   2178:                            !(sc->atu_if_flags & IFF_PROMISC)) {
                   2179: /* enable promisc */
                   2180: #if 0
                   2181:                                sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
                   2182:                                atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
                   2183:                                    sc->atu_rxfilt);
                   2184: #endif
                   2185:                        } else if (ifp->if_flags & IFF_RUNNING &&
                   2186:                            !(ifp->if_flags & IFF_PROMISC) &&
                   2187:                            sc->atu_if_flags & IFF_PROMISC) {
                   2188: /* disable promisc */
                   2189: #if 0
                   2190:                                sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC;
                   2191:                                atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
                   2192:                                    sc->atu_rxfilt);
                   2193: #endif
                   2194:                        } else if (!(ifp->if_flags & IFF_RUNNING))
                   2195:                                atu_init(ifp);
                   2196:
                   2197:                        DPRINTFN(15, ("%s: ioctl calling atu_init()\n",
                   2198:                            sc->atu_dev.dv_xname));
                   2199:                        atu_init(ifp);
                   2200:                        err = atu_switch_radio(sc, 1);
                   2201:                } else {
                   2202:                        if (ifp->if_flags & IFF_RUNNING)
                   2203:                                atu_stop(ifp, 0);
                   2204:                        err = atu_switch_radio(sc, 0);
                   2205:                }
                   2206:                sc->atu_if_flags = ifp->if_flags;
                   2207:                err = 0;
                   2208:                break;
                   2209:
                   2210:        case SIOCADDMULTI:
                   2211:                DPRINTFN(15, ("%s: SIOCADDMULTI\n", sc->atu_dev.dv_xname));
                   2212:                /* TODO: implement */
                   2213:                err = 0;
                   2214:                break;
                   2215:
                   2216:        case SIOCDELMULTI:
                   2217:                DPRINTFN(15, ("%s: SIOCDELMULTI\n", sc->atu_dev.dv_xname));
                   2218:                /* TODO: implement */
                   2219:                err = 0;
                   2220:                break;
                   2221:
                   2222:        default:
                   2223:                DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
                   2224:                    sc->atu_dev.dv_xname, command));
                   2225:                err = ieee80211_ioctl(ifp, command, data);
                   2226:                break;
                   2227:        }
                   2228:
                   2229:        if (err == ENETRESET) {
                   2230:                if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
                   2231:                    (IFF_RUNNING|IFF_UP)) {
                   2232:                        DPRINTF(("%s: atu_ioctl(): netreset\n",
                   2233:                            sc->atu_dev.dv_xname));
                   2234:                        atu_init(ifp);
                   2235:                }
                   2236:                err = 0;
                   2237:        }
                   2238:
                   2239:        splx(s);
                   2240:        return (err);
                   2241: }
                   2242:
                   2243: void
                   2244: atu_watchdog(struct ifnet *ifp)
                   2245: {
                   2246:        struct atu_softc        *sc = ifp->if_softc;
                   2247:        struct atu_chain        *c;
                   2248:        usbd_status             stat;
                   2249:        int                     cnt, s;
                   2250:
                   2251:        DPRINTF(("%s: atu_watchdog\n", sc->atu_dev.dv_xname));
                   2252:
                   2253:        ifp->if_timer = 0;
                   2254:
                   2255:        if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
                   2256:                return;
                   2257:
                   2258:        if (sc->sc_state != ATU_S_OK)
                   2259:                return;
                   2260:
                   2261:        sc = ifp->if_softc;
                   2262:        s = splnet();
                   2263:        ifp->if_oerrors++;
                   2264:        DPRINTF(("%s: watchdog timeout\n", sc->atu_dev.dv_xname));
                   2265:
                   2266:        /*
                   2267:         * TODO:
                   2268:         * we should change this since we have multiple TX transfers...
                   2269:         */
                   2270:        for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) {
                   2271:                c = &sc->atu_cdata.atu_tx_chain[cnt];
                   2272:                if (c->atu_in_xfer) {
                   2273:                        usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL,
                   2274:                            &stat);
                   2275:                        atu_txeof(c->atu_xfer, c, stat);
                   2276:                }
                   2277:        }
                   2278:
                   2279:        if (!IFQ_IS_EMPTY(&ifp->if_snd))
                   2280:                atu_start(ifp);
                   2281:        splx(s);
                   2282:
                   2283:        ieee80211_watchdog(ifp);
                   2284: }
                   2285:
                   2286: /*
                   2287:  * Stop the adapter and free any mbufs allocated to the
                   2288:  * RX and TX lists.
                   2289:  */
                   2290: void
                   2291: atu_stop(struct ifnet *ifp, int disable)
                   2292: {
                   2293:        struct atu_softc        *sc = ifp->if_softc;
                   2294:        struct atu_cdata        *cd;
                   2295:        usbd_status             err;
                   2296:        int s;
                   2297:
                   2298:        s = splnet();
                   2299:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2300:        ifp->if_timer = 0;
                   2301:
                   2302:        /* Stop transfers. */
                   2303:        if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
                   2304:                err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
                   2305:                if (err) {
                   2306:                        DPRINTF(("%s: abort rx pipe failed: %s\n",
                   2307:                            sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2308:                }
                   2309:                err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]);
                   2310:                if (err) {
                   2311:                        DPRINTF(("%s: close rx pipe failed: %s\n",
                   2312:                            sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2313:                }
                   2314:                sc->atu_ep[ATU_ENDPT_RX] = NULL;
                   2315:        }
                   2316:
                   2317:        if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
                   2318:                err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
                   2319:                if (err) {
                   2320:                        DPRINTF(("%s: abort tx pipe failed: %s\n",
                   2321:                            sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2322:                }
                   2323:                err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]);
                   2324:                if (err) {
                   2325:                        DPRINTF(("%s: close tx pipe failed: %s\n",
                   2326:                            sc->atu_dev.dv_xname, usbd_errstr(err)));
                   2327:                }
                   2328:                sc->atu_ep[ATU_ENDPT_TX] = NULL;
                   2329:        }
                   2330:
                   2331:        /* Free RX/TX/MGMT list resources. */
                   2332:        cd = &sc->atu_cdata;
                   2333:        atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT);
                   2334:        atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT);
                   2335:
                   2336:        /* Let's be nice and turn off the radio before we leave */
                   2337:        atu_switch_radio(sc, 0);
                   2338:
                   2339:        splx(s);
                   2340: }

CVSweb