root/dev/usb/if_atu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. atu_usb_request
  2. atu_send_command
  3. atu_get_cmd_status
  4. atu_wait_completion
  5. atu_send_mib
  6. atu_get_mib
  7. atu_start_ibss
  8. atu_start_scan
  9. atu_switch_radio
  10. atu_initial_config
  11. atu_join
  12. atu_get_dfu_state
  13. atu_get_opmode
  14. atu_internal_firmware
  15. atu_external_firmware
  16. atu_get_card_config
  17. atu_match
  18. atu_media_change
  19. atu_media_status
  20. atu_task
  21. atu_newstate
  22. atu_attach
  23. atu_complete_attach
  24. atu_detach
  25. atu_activate
  26. atu_newbuf
  27. atu_rx_list_init
  28. atu_tx_list_init
  29. atu_xfer_list_free
  30. atu_rxeof
  31. atu_txeof
  32. atu_calculate_padding
  33. atu_tx_start
  34. atu_start
  35. atu_init
  36. atu_ioctl
  37. atu_watchdog
  38. atu_stop

    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 }

/* [<][>][^][v][top][bottom][index][help] */