The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/wlan/if_upgt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */
    2 /*      $FreeBSD$ */
    3 
    4 /*
    5  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include "opt_wlan.h"
   21 
   22 #include <sys/param.h>
   23 #include <sys/systm.h>
   24 #include <sys/kernel.h>
   25 #include <sys/endian.h>
   26 #include <sys/firmware.h>
   27 #include <sys/linker.h>
   28 #include <sys/mbuf.h>
   29 #include <sys/malloc.h>
   30 #include <sys/module.h>
   31 #include <sys/socket.h>
   32 #include <sys/sockio.h>
   33 #include <sys/sysctl.h>
   34 
   35 #include <net/if.h>
   36 #include <net/if_var.h>
   37 #include <net/if_arp.h>
   38 #include <net/ethernet.h>
   39 #include <net/if_dl.h>
   40 #include <net/if_media.h>
   41 #include <net/if_types.h>
   42 
   43 #include <sys/bus.h>
   44 
   45 #include <net80211/ieee80211_var.h>
   46 #include <net80211/ieee80211_phy.h>
   47 #include <net80211/ieee80211_radiotap.h>
   48 #include <net80211/ieee80211_regdomain.h>
   49 
   50 #include <net/bpf.h>
   51 
   52 #include <dev/usb/usb.h>
   53 #include <dev/usb/usbdi.h>
   54 #include "usbdevs.h"
   55 
   56 #include <dev/usb/wlan/if_upgtvar.h>
   57 
   58 /*
   59  * Driver for the USB PrismGT devices.
   60  *
   61  * For now just USB 2.0 devices with the GW3887 chipset are supported.
   62  * The driver has been written based on the firmware version 2.13.1.0_LM87.
   63  *
   64  * TODO's:
   65  * - MONITOR mode test.
   66  * - Add HOSTAP mode.
   67  * - Add IBSS mode.
   68  * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets).
   69  *
   70  * Parts of this driver has been influenced by reading the p54u driver
   71  * written by Jean-Baptiste Note <jean-baptiste.note@m4x.org> and
   72  * Sebastien Bourdeauducq <lekernel@prism54.org>.
   73  */
   74 
   75 static SYSCTL_NODE(_hw, OID_AUTO, upgt, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
   76     "USB PrismGT GW3887 driver parameters");
   77 
   78 #ifdef UPGT_DEBUG
   79 int upgt_debug = 0;
   80 SYSCTL_INT(_hw_upgt, OID_AUTO, debug, CTLFLAG_RWTUN, &upgt_debug,
   81             0, "control debugging printfs");
   82 enum {
   83         UPGT_DEBUG_XMIT         = 0x00000001,   /* basic xmit operation */
   84         UPGT_DEBUG_RECV         = 0x00000002,   /* basic recv operation */
   85         UPGT_DEBUG_RESET        = 0x00000004,   /* reset processing */
   86         UPGT_DEBUG_INTR         = 0x00000008,   /* INTR */
   87         UPGT_DEBUG_TX_PROC      = 0x00000010,   /* tx ISR proc */
   88         UPGT_DEBUG_RX_PROC      = 0x00000020,   /* rx ISR proc */
   89         UPGT_DEBUG_STATE        = 0x00000040,   /* 802.11 state transitions */
   90         UPGT_DEBUG_STAT         = 0x00000080,   /* statistic */
   91         UPGT_DEBUG_FW           = 0x00000100,   /* firmware */
   92         UPGT_DEBUG_ANY          = 0xffffffff
   93 };
   94 #define DPRINTF(sc, m, fmt, ...) do {                           \
   95         if (sc->sc_debug & (m))                                 \
   96                 printf(fmt, __VA_ARGS__);                       \
   97 } while (0)
   98 #else
   99 #define DPRINTF(sc, m, fmt, ...) do {                           \
  100         (void) sc;                                              \
  101 } while (0)
  102 #endif
  103 
  104 /*
  105  * Prototypes.
  106  */
  107 static device_probe_t upgt_match;
  108 static device_attach_t upgt_attach;
  109 static device_detach_t upgt_detach;
  110 static int      upgt_alloc_tx(struct upgt_softc *);
  111 static int      upgt_alloc_rx(struct upgt_softc *);
  112 static int      upgt_device_reset(struct upgt_softc *);
  113 static void     upgt_bulk_tx(struct upgt_softc *, struct upgt_data *);
  114 static int      upgt_fw_verify(struct upgt_softc *);
  115 static int      upgt_mem_init(struct upgt_softc *);
  116 static int      upgt_fw_load(struct upgt_softc *);
  117 static int      upgt_fw_copy(const uint8_t *, char *, int);
  118 static uint32_t upgt_crc32_le(const void *, size_t);
  119 static struct mbuf *
  120                 upgt_rxeof(struct usb_xfer *, struct upgt_data *, int *);
  121 static struct mbuf *
  122                 upgt_rx(struct upgt_softc *, uint8_t *, int, int *);
  123 static void     upgt_txeof(struct usb_xfer *, struct upgt_data *);
  124 static int      upgt_eeprom_read(struct upgt_softc *);
  125 static int      upgt_eeprom_parse(struct upgt_softc *);
  126 static void     upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *);
  127 static void     upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int);
  128 static void     upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
  129 static void     upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
  130 static uint32_t upgt_chksum_le(const uint32_t *, size_t);
  131 static void     upgt_tx_done(struct upgt_softc *, uint8_t *);
  132 static void     upgt_init(struct upgt_softc *);
  133 static void     upgt_parent(struct ieee80211com *);
  134 static int      upgt_transmit(struct ieee80211com *, struct mbuf *);
  135 static void     upgt_start(struct upgt_softc *);
  136 static int      upgt_raw_xmit(struct ieee80211_node *, struct mbuf *,
  137                     const struct ieee80211_bpf_params *);
  138 static void     upgt_scan_start(struct ieee80211com *);
  139 static void     upgt_scan_end(struct ieee80211com *);
  140 static void     upgt_set_channel(struct ieee80211com *);
  141 static struct ieee80211vap *upgt_vap_create(struct ieee80211com *,
  142                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
  143                     const uint8_t [IEEE80211_ADDR_LEN],
  144                     const uint8_t [IEEE80211_ADDR_LEN]);
  145 static void     upgt_vap_delete(struct ieee80211vap *);
  146 static void     upgt_update_mcast(struct ieee80211com *);
  147 static uint8_t  upgt_rx_rate(struct upgt_softc *, const int);
  148 static void     upgt_set_multi(void *);
  149 static void     upgt_stop(struct upgt_softc *);
  150 static void     upgt_setup_rates(struct ieee80211vap *, struct ieee80211com *);
  151 static int      upgt_set_macfilter(struct upgt_softc *, uint8_t);
  152 static int      upgt_newstate(struct ieee80211vap *, enum ieee80211_state, int);
  153 static void     upgt_set_chan(struct upgt_softc *, struct ieee80211_channel *);
  154 static void     upgt_set_led(struct upgt_softc *, int);
  155 static void     upgt_set_led_blink(void *);
  156 static void     upgt_get_stats(struct upgt_softc *);
  157 static void     upgt_mem_free(struct upgt_softc *, uint32_t);
  158 static uint32_t upgt_mem_alloc(struct upgt_softc *);
  159 static void     upgt_free_tx(struct upgt_softc *);
  160 static void     upgt_free_rx(struct upgt_softc *);
  161 static void     upgt_watchdog(void *);
  162 static void     upgt_abort_xfers(struct upgt_softc *);
  163 static void     upgt_abort_xfers_locked(struct upgt_softc *);
  164 static void     upgt_sysctl_node(struct upgt_softc *);
  165 static struct upgt_data *
  166                 upgt_getbuf(struct upgt_softc *);
  167 static struct upgt_data *
  168                 upgt_gettxbuf(struct upgt_softc *);
  169 static int      upgt_tx_start(struct upgt_softc *, struct mbuf *,
  170                     struct ieee80211_node *, struct upgt_data *);
  171 
  172 static const char *upgt_fwname = "upgt-gw3887";
  173 
  174 static const STRUCT_USB_HOST_ID upgt_devs[] = {
  175 #define UPGT_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
  176         /* version 2 devices */
  177         UPGT_DEV(ACCTON,        PRISM_GT),
  178         UPGT_DEV(BELKIN,        F5D7050),
  179         UPGT_DEV(CISCOLINKSYS,  WUSB54AG),
  180         UPGT_DEV(CONCEPTRONIC,  PRISM_GT),
  181         UPGT_DEV(DELL,          PRISM_GT_1),
  182         UPGT_DEV(DELL,          PRISM_GT_2),
  183         UPGT_DEV(FSC,           E5400),
  184         UPGT_DEV(GLOBESPAN,     PRISM_GT_1),
  185         UPGT_DEV(GLOBESPAN,     PRISM_GT_2),
  186         UPGT_DEV(NETGEAR,       WG111V1_2),
  187         UPGT_DEV(INTERSIL,      PRISM_GT),
  188         UPGT_DEV(SMC,           2862WG),
  189         UPGT_DEV(USR,           USR5422),
  190         UPGT_DEV(WISTRONNEWEB,  UR045G),
  191         UPGT_DEV(XYRATEX,       PRISM_GT_1),
  192         UPGT_DEV(XYRATEX,       PRISM_GT_2),
  193         UPGT_DEV(ZCOM,          XG703A),
  194         UPGT_DEV(ZCOM,          XM142)
  195 };
  196 
  197 static usb_callback_t upgt_bulk_rx_callback;
  198 static usb_callback_t upgt_bulk_tx_callback;
  199 
  200 static const struct usb_config upgt_config[UPGT_N_XFERS] = {
  201         [UPGT_BULK_TX] = {
  202                 .type = UE_BULK,
  203                 .endpoint = UE_ADDR_ANY,
  204                 .direction = UE_DIR_OUT,
  205                 .bufsize = MCLBYTES * UPGT_TX_MAXCOUNT,
  206                 .flags = {
  207                         .force_short_xfer = 1,
  208                         .pipe_bof = 1
  209                 },
  210                 .callback = upgt_bulk_tx_callback,
  211                 .timeout = UPGT_USB_TIMEOUT,    /* ms */
  212         },
  213         [UPGT_BULK_RX] = {
  214                 .type = UE_BULK,
  215                 .endpoint = UE_ADDR_ANY,
  216                 .direction = UE_DIR_IN,
  217                 .bufsize = MCLBYTES * UPGT_RX_MAXCOUNT,
  218                 .flags = {
  219                         .pipe_bof = 1,
  220                         .short_xfer_ok = 1
  221                 },
  222                 .callback = upgt_bulk_rx_callback,
  223         },
  224 };
  225 
  226 static int
  227 upgt_match(device_t dev)
  228 {
  229         struct usb_attach_arg *uaa = device_get_ivars(dev);
  230 
  231         if (uaa->usb_mode != USB_MODE_HOST)
  232                 return (ENXIO);
  233         if (uaa->info.bConfigIndex != UPGT_CONFIG_INDEX)
  234                 return (ENXIO);
  235         if (uaa->info.bIfaceIndex != UPGT_IFACE_INDEX)
  236                 return (ENXIO);
  237 
  238         return (usbd_lookup_id_by_uaa(upgt_devs, sizeof(upgt_devs), uaa));
  239 }
  240 
  241 static int
  242 upgt_attach(device_t dev)
  243 {
  244         struct upgt_softc *sc = device_get_softc(dev);
  245         struct ieee80211com *ic = &sc->sc_ic;
  246         struct usb_attach_arg *uaa = device_get_ivars(dev);
  247         uint8_t bands[IEEE80211_MODE_BYTES];
  248         uint8_t iface_index = UPGT_IFACE_INDEX;
  249         int error;
  250 
  251         sc->sc_dev = dev;
  252         sc->sc_udev = uaa->device;
  253 #ifdef UPGT_DEBUG
  254         sc->sc_debug = upgt_debug;
  255 #endif
  256         device_set_usb_desc(dev);
  257 
  258         mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
  259             MTX_DEF);
  260         callout_init(&sc->sc_led_ch, 0);
  261         callout_init(&sc->sc_watchdog_ch, 0);
  262         mbufq_init(&sc->sc_snd, ifqmaxlen);
  263 
  264         error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
  265             upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx);
  266         if (error) {
  267                 device_printf(dev, "could not allocate USB transfers, "
  268                     "err=%s\n", usbd_errstr(error));
  269                 goto fail1;
  270         }
  271 
  272         sc->sc_rx_dma_buf = usbd_xfer_get_frame_buffer(
  273             sc->sc_xfer[UPGT_BULK_RX], 0);
  274         sc->sc_tx_dma_buf = usbd_xfer_get_frame_buffer(
  275             sc->sc_xfer[UPGT_BULK_TX], 0);
  276 
  277         /* Setup TX and RX buffers */
  278         error = upgt_alloc_tx(sc);
  279         if (error)
  280                 goto fail2;
  281         error = upgt_alloc_rx(sc);
  282         if (error)
  283                 goto fail3;
  284 
  285         /* Initialize the device.  */
  286         error = upgt_device_reset(sc);
  287         if (error)
  288                 goto fail4;
  289         /* Verify the firmware.  */
  290         error = upgt_fw_verify(sc);
  291         if (error)
  292                 goto fail4;
  293         /* Calculate device memory space.  */
  294         if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
  295                 device_printf(dev,
  296                     "could not find memory space addresses on FW\n");
  297                 error = EIO;
  298                 goto fail4;
  299         }
  300         sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
  301         sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
  302 
  303         DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame start=0x%08x\n",
  304             sc->sc_memaddr_frame_start);
  305         DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame end=0x%08x\n",
  306             sc->sc_memaddr_frame_end);
  307         DPRINTF(sc, UPGT_DEBUG_FW, "memory address rx start=0x%08x\n",
  308             sc->sc_memaddr_rx_start);
  309 
  310         upgt_mem_init(sc);
  311 
  312         /* Load the firmware.  */
  313         error = upgt_fw_load(sc);
  314         if (error)
  315                 goto fail4;
  316 
  317         /* Read the whole EEPROM content and parse it.  */
  318         error = upgt_eeprom_read(sc);
  319         if (error)
  320                 goto fail4;
  321         error = upgt_eeprom_parse(sc);
  322         if (error)
  323                 goto fail4;
  324 
  325         /* all works related with the device have done here. */
  326         upgt_abort_xfers(sc);
  327 
  328         ic->ic_softc = sc;
  329         ic->ic_name = device_get_nameunit(dev);
  330         ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
  331         ic->ic_opmode = IEEE80211_M_STA;
  332         /* set device capabilities */
  333         ic->ic_caps =
  334                   IEEE80211_C_STA               /* station mode */
  335                 | IEEE80211_C_MONITOR           /* monitor mode */
  336                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
  337                 | IEEE80211_C_SHSLOT            /* short slot time supported */
  338                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
  339                 | IEEE80211_C_WPA               /* 802.11i */
  340                 ;
  341 
  342         memset(bands, 0, sizeof(bands));
  343         setbit(bands, IEEE80211_MODE_11B);
  344         setbit(bands, IEEE80211_MODE_11G);
  345         ieee80211_init_channels(ic, NULL, bands);
  346 
  347         ieee80211_ifattach(ic);
  348         ic->ic_raw_xmit = upgt_raw_xmit;
  349         ic->ic_scan_start = upgt_scan_start;
  350         ic->ic_scan_end = upgt_scan_end;
  351         ic->ic_set_channel = upgt_set_channel;
  352         ic->ic_vap_create = upgt_vap_create;
  353         ic->ic_vap_delete = upgt_vap_delete;
  354         ic->ic_update_mcast = upgt_update_mcast;
  355         ic->ic_transmit = upgt_transmit;
  356         ic->ic_parent = upgt_parent;
  357 
  358         ieee80211_radiotap_attach(ic,
  359             &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
  360                 UPGT_TX_RADIOTAP_PRESENT,
  361             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
  362                 UPGT_RX_RADIOTAP_PRESENT);
  363 
  364         upgt_sysctl_node(sc);
  365 
  366         if (bootverbose)
  367                 ieee80211_announce(ic);
  368 
  369         return (0);
  370 
  371 fail4:  upgt_free_rx(sc);
  372 fail3:  upgt_free_tx(sc);
  373 fail2:  usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
  374 fail1:  mtx_destroy(&sc->sc_mtx);
  375 
  376         return (error);
  377 }
  378 
  379 static void
  380 upgt_txeof(struct usb_xfer *xfer, struct upgt_data *data)
  381 {
  382 
  383         if (data->m) {
  384                 /* XXX status? */
  385                 ieee80211_tx_complete(data->ni, data->m, 0);
  386                 data->m = NULL;
  387                 data->ni = NULL;
  388         }
  389 }
  390 
  391 static void
  392 upgt_get_stats(struct upgt_softc *sc)
  393 {
  394         struct upgt_data *data_cmd;
  395         struct upgt_lmac_mem *mem;
  396         struct upgt_lmac_stats *stats;
  397 
  398         data_cmd = upgt_getbuf(sc);
  399         if (data_cmd == NULL) {
  400                 device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
  401                 return;
  402         }
  403 
  404         /*
  405          * Transmit the URB containing the CMD data.
  406          */
  407         memset(data_cmd->buf, 0, MCLBYTES);
  408 
  409         mem = (struct upgt_lmac_mem *)data_cmd->buf;
  410         mem->addr = htole32(sc->sc_memaddr_frame_start +
  411             UPGT_MEMSIZE_FRAME_HEAD);
  412 
  413         stats = (struct upgt_lmac_stats *)(mem + 1);
  414 
  415         stats->header1.flags = 0;
  416         stats->header1.type = UPGT_H1_TYPE_CTRL;
  417         stats->header1.len = htole16(
  418             sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header));
  419 
  420         stats->header2.reqid = htole32(sc->sc_memaddr_frame_start);
  421         stats->header2.type = htole16(UPGT_H2_TYPE_STATS);
  422         stats->header2.flags = 0;
  423 
  424         data_cmd->buflen = sizeof(*mem) + sizeof(*stats);
  425 
  426         mem->chksum = upgt_chksum_le((uint32_t *)stats,
  427             data_cmd->buflen - sizeof(*mem));
  428 
  429         upgt_bulk_tx(sc, data_cmd);
  430 }
  431 
  432 static void
  433 upgt_parent(struct ieee80211com *ic)
  434 {
  435         struct upgt_softc *sc = ic->ic_softc;
  436         int startall = 0;
  437 
  438         UPGT_LOCK(sc);
  439         if (sc->sc_flags & UPGT_FLAG_DETACHED) {
  440                 UPGT_UNLOCK(sc);
  441                 return;
  442         }
  443         if (ic->ic_nrunning > 0) {
  444                 if (sc->sc_flags & UPGT_FLAG_INITDONE) {
  445                         if (ic->ic_allmulti > 0 || ic->ic_promisc > 0)
  446                                 upgt_set_multi(sc);
  447                 } else {
  448                         upgt_init(sc);
  449                         startall = 1;
  450                 }
  451         } else if (sc->sc_flags & UPGT_FLAG_INITDONE)
  452                 upgt_stop(sc);
  453         UPGT_UNLOCK(sc);
  454         if (startall)
  455                 ieee80211_start_all(ic);
  456 }
  457 
  458 static void
  459 upgt_stop(struct upgt_softc *sc)
  460 {
  461 
  462         UPGT_ASSERT_LOCKED(sc);
  463 
  464         if (sc->sc_flags & UPGT_FLAG_INITDONE)
  465                 upgt_set_macfilter(sc, IEEE80211_S_INIT);
  466         upgt_abort_xfers_locked(sc);
  467         /* device down */
  468         sc->sc_tx_timer = 0;
  469         sc->sc_flags &= ~UPGT_FLAG_INITDONE;
  470 }
  471 
  472 static void
  473 upgt_set_led(struct upgt_softc *sc, int action)
  474 {
  475         struct upgt_data *data_cmd;
  476         struct upgt_lmac_mem *mem;
  477         struct upgt_lmac_led *led;
  478 
  479         data_cmd = upgt_getbuf(sc);
  480         if (data_cmd == NULL) {
  481                 device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
  482                 return;
  483         }
  484 
  485         /*
  486          * Transmit the URB containing the CMD data.
  487          */
  488         memset(data_cmd->buf, 0, MCLBYTES);
  489 
  490         mem = (struct upgt_lmac_mem *)data_cmd->buf;
  491         mem->addr = htole32(sc->sc_memaddr_frame_start +
  492             UPGT_MEMSIZE_FRAME_HEAD);
  493 
  494         led = (struct upgt_lmac_led *)(mem + 1);
  495 
  496         led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
  497         led->header1.type = UPGT_H1_TYPE_CTRL;
  498         led->header1.len = htole16(
  499             sizeof(struct upgt_lmac_led) -
  500             sizeof(struct upgt_lmac_header));
  501 
  502         led->header2.reqid = htole32(sc->sc_memaddr_frame_start);
  503         led->header2.type = htole16(UPGT_H2_TYPE_LED);
  504         led->header2.flags = 0;
  505 
  506         switch (action) {
  507         case UPGT_LED_OFF:
  508                 led->mode = htole16(UPGT_LED_MODE_SET);
  509                 led->action_fix = 0;
  510                 led->action_tmp = htole16(UPGT_LED_ACTION_OFF);
  511                 led->action_tmp_dur = 0;
  512                 break;
  513         case UPGT_LED_ON:
  514                 led->mode = htole16(UPGT_LED_MODE_SET);
  515                 led->action_fix = 0;
  516                 led->action_tmp = htole16(UPGT_LED_ACTION_ON);
  517                 led->action_tmp_dur = 0;
  518                 break;
  519         case UPGT_LED_BLINK:
  520                 if (sc->sc_state != IEEE80211_S_RUN) {
  521                         STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
  522                         return;
  523                 }
  524                 if (sc->sc_led_blink) {
  525                         /* previous blink was not finished */
  526                         STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
  527                         return;
  528                 }
  529                 led->mode = htole16(UPGT_LED_MODE_SET);
  530                 led->action_fix = htole16(UPGT_LED_ACTION_OFF);
  531                 led->action_tmp = htole16(UPGT_LED_ACTION_ON);
  532                 led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR);
  533                 /* lock blink */
  534                 sc->sc_led_blink = 1;
  535                 callout_reset(&sc->sc_led_ch, hz, upgt_set_led_blink, sc);
  536                 break;
  537         default:
  538                 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
  539                 return;
  540         }
  541 
  542         data_cmd->buflen = sizeof(*mem) + sizeof(*led);
  543 
  544         mem->chksum = upgt_chksum_le((uint32_t *)led,
  545             data_cmd->buflen - sizeof(*mem));
  546 
  547         upgt_bulk_tx(sc, data_cmd);
  548 }
  549 
  550 static void
  551 upgt_set_led_blink(void *arg)
  552 {
  553         struct upgt_softc *sc = arg;
  554 
  555         /* blink finished, we are ready for a next one */
  556         sc->sc_led_blink = 0;
  557 }
  558 
  559 static void
  560 upgt_init(struct upgt_softc *sc)
  561 {
  562 
  563         UPGT_ASSERT_LOCKED(sc);
  564 
  565         if (sc->sc_flags & UPGT_FLAG_INITDONE)
  566                 upgt_stop(sc);
  567 
  568         usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
  569 
  570         (void)upgt_set_macfilter(sc, IEEE80211_S_SCAN);
  571 
  572         sc->sc_flags |= UPGT_FLAG_INITDONE;
  573 
  574         callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
  575 }
  576 
  577 static int
  578 upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
  579 {
  580         struct ieee80211com *ic = &sc->sc_ic;
  581         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
  582         struct ieee80211_node *ni;
  583         struct upgt_data *data_cmd;
  584         struct upgt_lmac_mem *mem;
  585         struct upgt_lmac_filter *filter;
  586 
  587         UPGT_ASSERT_LOCKED(sc);
  588 
  589         data_cmd = upgt_getbuf(sc);
  590         if (data_cmd == NULL) {
  591                 device_printf(sc->sc_dev, "out of TX buffers.\n");
  592                 return (ENOBUFS);
  593         }
  594 
  595         /*
  596          * Transmit the URB containing the CMD data.
  597          */
  598         memset(data_cmd->buf, 0, MCLBYTES);
  599 
  600         mem = (struct upgt_lmac_mem *)data_cmd->buf;
  601         mem->addr = htole32(sc->sc_memaddr_frame_start +
  602             UPGT_MEMSIZE_FRAME_HEAD);
  603 
  604         filter = (struct upgt_lmac_filter *)(mem + 1);
  605 
  606         filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
  607         filter->header1.type = UPGT_H1_TYPE_CTRL;
  608         filter->header1.len = htole16(
  609             sizeof(struct upgt_lmac_filter) -
  610             sizeof(struct upgt_lmac_header));
  611 
  612         filter->header2.reqid = htole32(sc->sc_memaddr_frame_start);
  613         filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER);
  614         filter->header2.flags = 0;
  615 
  616         switch (state) {
  617         case IEEE80211_S_INIT:
  618                 DPRINTF(sc, UPGT_DEBUG_STATE, "%s: set MAC filter to INIT\n",
  619                     __func__);
  620                 filter->type = htole16(UPGT_FILTER_TYPE_RESET);
  621                 break;
  622         case IEEE80211_S_SCAN:
  623                 DPRINTF(sc, UPGT_DEBUG_STATE,
  624                     "set MAC filter to SCAN (bssid %s)\n",
  625                     ether_sprintf(ieee80211broadcastaddr));
  626                 filter->type = htole16(UPGT_FILTER_TYPE_NONE);
  627                 IEEE80211_ADDR_COPY(filter->dst,
  628                     vap ? vap->iv_myaddr : ic->ic_macaddr);
  629                 IEEE80211_ADDR_COPY(filter->src, ieee80211broadcastaddr);
  630                 filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
  631                 filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
  632                 filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
  633                 filter->rxhw = htole32(sc->sc_eeprom_hwrx);
  634                 filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
  635                 break;
  636         case IEEE80211_S_RUN:
  637                 ni = ieee80211_ref_node(vap->iv_bss);
  638                 /* XXX monitor mode isn't tested yet.  */
  639                 if (vap->iv_opmode == IEEE80211_M_MONITOR) {
  640                         filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
  641                         IEEE80211_ADDR_COPY(filter->dst,
  642                             vap ? vap->iv_myaddr : ic->ic_macaddr);
  643                         IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
  644                         filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1);
  645                         filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
  646                         filter->unknown2 = htole16(UPGT_FILTER_MONITOR_UNKNOWN2);
  647                         filter->rxhw = htole32(sc->sc_eeprom_hwrx);
  648                         filter->unknown3 = htole16(UPGT_FILTER_MONITOR_UNKNOWN3);
  649                 } else {
  650                         DPRINTF(sc, UPGT_DEBUG_STATE,
  651                             "set MAC filter to RUN (bssid %s)\n",
  652                             ether_sprintf(ni->ni_bssid));
  653                         filter->type = htole16(UPGT_FILTER_TYPE_STA);
  654                         IEEE80211_ADDR_COPY(filter->dst,
  655                             vap ? vap->iv_myaddr : ic->ic_macaddr);
  656                         IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
  657                         filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
  658                         filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
  659                         filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
  660                         filter->rxhw = htole32(sc->sc_eeprom_hwrx);
  661                         filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
  662                 }
  663                 ieee80211_free_node(ni);
  664                 break;
  665         default:
  666                 device_printf(sc->sc_dev,
  667                     "MAC filter does not know that state\n");
  668                 break;
  669         }
  670 
  671         data_cmd->buflen = sizeof(*mem) + sizeof(*filter);
  672 
  673         mem->chksum = upgt_chksum_le((uint32_t *)filter,
  674             data_cmd->buflen - sizeof(*mem));
  675 
  676         upgt_bulk_tx(sc, data_cmd);
  677 
  678         return (0);
  679 }
  680 
  681 static void
  682 upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
  683 {
  684         struct upgt_softc *sc = ic->ic_softc;
  685         const struct ieee80211_txparam *tp;
  686 
  687         /*
  688          * 0x01 = OFMD6   0x10 = DS1
  689          * 0x04 = OFDM9   0x11 = DS2
  690          * 0x06 = OFDM12  0x12 = DS5
  691          * 0x07 = OFDM18  0x13 = DS11
  692          * 0x08 = OFDM24
  693          * 0x09 = OFDM36
  694          * 0x0a = OFDM48
  695          * 0x0b = OFDM54
  696          */
  697         const uint8_t rateset_auto_11b[] =
  698             { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 };
  699         const uint8_t rateset_auto_11g[] =
  700             { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 };
  701         const uint8_t rateset_fix_11bg[] =
  702             { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07,
  703               0x08, 0x09, 0x0a, 0x0b };
  704 
  705         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
  706 
  707         /* XXX */
  708         if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) {
  709                 /*
  710                  * Automatic rate control is done by the device.
  711                  * We just pass the rateset from which the device
  712                  * will pickup a rate.
  713                  */
  714                 if (ic->ic_curmode == IEEE80211_MODE_11B)
  715                         memcpy(sc->sc_cur_rateset, rateset_auto_11b,
  716                             sizeof(sc->sc_cur_rateset));
  717                 if (ic->ic_curmode == IEEE80211_MODE_11G ||
  718                     ic->ic_curmode == IEEE80211_MODE_AUTO)
  719                         memcpy(sc->sc_cur_rateset, rateset_auto_11g,
  720                             sizeof(sc->sc_cur_rateset));
  721         } else {
  722                 /* set a fixed rate */
  723                 memset(sc->sc_cur_rateset, rateset_fix_11bg[tp->ucastrate],
  724                     sizeof(sc->sc_cur_rateset));
  725         }
  726 }
  727 
  728 static void
  729 upgt_set_multi(void *arg)
  730 {
  731 
  732         /* XXX don't know how to set a device.  Lack of docs. */
  733 }
  734 
  735 static int
  736 upgt_transmit(struct ieee80211com *ic, struct mbuf *m)   
  737 {
  738         struct upgt_softc *sc = ic->ic_softc;
  739         int error;
  740 
  741         UPGT_LOCK(sc);
  742         if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) {
  743                 UPGT_UNLOCK(sc);
  744                 return (ENXIO);
  745         }
  746         error = mbufq_enqueue(&sc->sc_snd, m);
  747         if (error) {
  748                 UPGT_UNLOCK(sc);
  749                 return (error);
  750         }
  751         upgt_start(sc);
  752         UPGT_UNLOCK(sc);
  753 
  754         return (0);
  755 }
  756 
  757 static void
  758 upgt_start(struct upgt_softc *sc)
  759 {
  760         struct upgt_data *data_tx;
  761         struct ieee80211_node *ni;
  762         struct mbuf *m;
  763 
  764         UPGT_ASSERT_LOCKED(sc);
  765 
  766         if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0)
  767                 return;
  768 
  769         while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
  770                 data_tx = upgt_gettxbuf(sc);
  771                 if (data_tx == NULL) {
  772                         mbufq_prepend(&sc->sc_snd, m);
  773                         break;
  774                 }
  775 
  776                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
  777                 m->m_pkthdr.rcvif = NULL;
  778 
  779                 if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
  780                         if_inc_counter(ni->ni_vap->iv_ifp,
  781                             IFCOUNTER_OERRORS, 1);
  782                         STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
  783                         UPGT_STAT_INC(sc, st_tx_inactive);
  784                         ieee80211_free_node(ni);
  785                         continue;
  786                 }
  787                 sc->sc_tx_timer = 5;
  788         }
  789 }
  790 
  791 static int
  792 upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
  793         const struct ieee80211_bpf_params *params)
  794 {
  795         struct ieee80211com *ic = ni->ni_ic;
  796         struct upgt_softc *sc = ic->ic_softc;
  797         struct upgt_data *data_tx = NULL;
  798 
  799         UPGT_LOCK(sc);
  800         /* prevent management frames from being sent if we're not ready */
  801         if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) {
  802                 m_freem(m);
  803                 UPGT_UNLOCK(sc);
  804                 return ENETDOWN;
  805         }
  806 
  807         data_tx = upgt_gettxbuf(sc);
  808         if (data_tx == NULL) {
  809                 m_freem(m);
  810                 UPGT_UNLOCK(sc);
  811                 return (ENOBUFS);
  812         }
  813 
  814         if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
  815                 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
  816                 UPGT_STAT_INC(sc, st_tx_inactive);
  817                 UPGT_UNLOCK(sc);
  818                 return (EIO);
  819         }
  820         UPGT_UNLOCK(sc);
  821 
  822         sc->sc_tx_timer = 5;
  823         return (0);
  824 }
  825 
  826 static void
  827 upgt_watchdog(void *arg)
  828 {
  829         struct upgt_softc *sc = arg;
  830         struct ieee80211com *ic = &sc->sc_ic;
  831 
  832         if (sc->sc_tx_timer > 0) {
  833                 if (--sc->sc_tx_timer == 0) {
  834                         device_printf(sc->sc_dev, "watchdog timeout\n");
  835                         /* upgt_init(sc); XXX needs a process context ? */
  836                         counter_u64_add(ic->ic_oerrors, 1);
  837                         return;
  838                 }
  839                 callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
  840         }
  841 }
  842 
  843 static uint32_t
  844 upgt_mem_alloc(struct upgt_softc *sc)
  845 {
  846         int i;
  847 
  848         for (i = 0; i < sc->sc_memory.pages; i++) {
  849                 if (sc->sc_memory.page[i].used == 0) {
  850                         sc->sc_memory.page[i].used = 1;
  851                         return (sc->sc_memory.page[i].addr);
  852                 }
  853         }
  854 
  855         return (0);
  856 }
  857 
  858 static void
  859 upgt_scan_start(struct ieee80211com *ic)
  860 {
  861         /* do nothing.  */
  862 }
  863 
  864 static void
  865 upgt_scan_end(struct ieee80211com *ic)
  866 {
  867         /* do nothing.  */
  868 }
  869 
  870 static void
  871 upgt_set_channel(struct ieee80211com *ic)
  872 {
  873         struct upgt_softc *sc = ic->ic_softc;
  874 
  875         UPGT_LOCK(sc);
  876         upgt_set_chan(sc, ic->ic_curchan);
  877         UPGT_UNLOCK(sc);
  878 }
  879 
  880 static void
  881 upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c)
  882 {
  883         struct ieee80211com *ic = &sc->sc_ic;
  884         struct upgt_data *data_cmd;
  885         struct upgt_lmac_mem *mem;
  886         struct upgt_lmac_channel *chan;
  887         int channel;
  888 
  889         UPGT_ASSERT_LOCKED(sc);
  890 
  891         channel = ieee80211_chan2ieee(ic, c);
  892         if (channel == 0 || channel == IEEE80211_CHAN_ANY) {
  893                 /* XXX should NEVER happen */
  894                 device_printf(sc->sc_dev,
  895                     "%s: invalid channel %x\n", __func__, channel);
  896                 return;
  897         }
  898 
  899         DPRINTF(sc, UPGT_DEBUG_STATE, "%s: channel %d\n", __func__, channel);
  900 
  901         data_cmd = upgt_getbuf(sc);
  902         if (data_cmd == NULL) {
  903                 device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
  904                 return;
  905         }
  906         /*
  907          * Transmit the URB containing the CMD data.
  908          */
  909         memset(data_cmd->buf, 0, MCLBYTES);
  910 
  911         mem = (struct upgt_lmac_mem *)data_cmd->buf;
  912         mem->addr = htole32(sc->sc_memaddr_frame_start +
  913             UPGT_MEMSIZE_FRAME_HEAD);
  914 
  915         chan = (struct upgt_lmac_channel *)(mem + 1);
  916 
  917         chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
  918         chan->header1.type = UPGT_H1_TYPE_CTRL;
  919         chan->header1.len = htole16(
  920             sizeof(struct upgt_lmac_channel) - sizeof(struct upgt_lmac_header));
  921 
  922         chan->header2.reqid = htole32(sc->sc_memaddr_frame_start);
  923         chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL);
  924         chan->header2.flags = 0;
  925 
  926         chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1);
  927         chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2);
  928         chan->freq6 = sc->sc_eeprom_freq6[channel];
  929         chan->settings = sc->sc_eeprom_freq6_settings;
  930         chan->unknown3 = UPGT_CHANNEL_UNKNOWN3;
  931 
  932         memcpy(chan->freq3_1, &sc->sc_eeprom_freq3[channel].data,
  933             sizeof(chan->freq3_1));
  934         memcpy(chan->freq4, &sc->sc_eeprom_freq4[channel],
  935             sizeof(sc->sc_eeprom_freq4[channel]));
  936         memcpy(chan->freq3_2, &sc->sc_eeprom_freq3[channel].data,
  937             sizeof(chan->freq3_2));
  938 
  939         data_cmd->buflen = sizeof(*mem) + sizeof(*chan);
  940 
  941         mem->chksum = upgt_chksum_le((uint32_t *)chan,
  942             data_cmd->buflen - sizeof(*mem));
  943 
  944         upgt_bulk_tx(sc, data_cmd);
  945 }
  946 
  947 static struct ieee80211vap *
  948 upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
  949     enum ieee80211_opmode opmode, int flags,
  950     const uint8_t bssid[IEEE80211_ADDR_LEN],
  951     const uint8_t mac[IEEE80211_ADDR_LEN])
  952 {
  953         struct upgt_vap *uvp;
  954         struct ieee80211vap *vap;
  955 
  956         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
  957                 return NULL;
  958         uvp = malloc(sizeof(struct upgt_vap), M_80211_VAP, M_WAITOK | M_ZERO);
  959         vap = &uvp->vap;
  960         /* enable s/w bmiss handling for sta mode */
  961 
  962         if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
  963             flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
  964                 /* out of memory */
  965                 free(uvp, M_80211_VAP);
  966                 return (NULL);
  967         }
  968 
  969         /* override state transition machine */
  970         uvp->newstate = vap->iv_newstate;
  971         vap->iv_newstate = upgt_newstate;
  972 
  973         /* setup device rates */
  974         upgt_setup_rates(vap, ic);
  975 
  976         /* complete setup */
  977         ieee80211_vap_attach(vap, ieee80211_media_change,
  978             ieee80211_media_status, mac);
  979         ic->ic_opmode = opmode;
  980         return vap;
  981 }
  982 
  983 static int
  984 upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
  985 {
  986         struct upgt_vap *uvp = UPGT_VAP(vap);
  987         struct ieee80211com *ic = vap->iv_ic;
  988         struct upgt_softc *sc = ic->ic_softc;
  989 
  990         /* do it in a process context */
  991         sc->sc_state = nstate;
  992 
  993         IEEE80211_UNLOCK(ic);
  994         UPGT_LOCK(sc);
  995         callout_stop(&sc->sc_led_ch);
  996         callout_stop(&sc->sc_watchdog_ch);
  997 
  998         switch (nstate) {
  999         case IEEE80211_S_INIT:
 1000                 /* do not accept any frames if the device is down */
 1001                 (void)upgt_set_macfilter(sc, sc->sc_state);
 1002                 upgt_set_led(sc, UPGT_LED_OFF);
 1003                 break;
 1004         case IEEE80211_S_SCAN:
 1005                 upgt_set_chan(sc, ic->ic_curchan);
 1006                 break;
 1007         case IEEE80211_S_AUTH:
 1008                 upgt_set_chan(sc, ic->ic_curchan);
 1009                 break;
 1010         case IEEE80211_S_ASSOC:
 1011                 break;
 1012         case IEEE80211_S_RUN:
 1013                 upgt_set_macfilter(sc, sc->sc_state);
 1014                 upgt_set_led(sc, UPGT_LED_ON);
 1015                 break;
 1016         default:
 1017                 break;
 1018         }
 1019         UPGT_UNLOCK(sc);
 1020         IEEE80211_LOCK(ic);
 1021         return (uvp->newstate(vap, nstate, arg));
 1022 }
 1023 
 1024 static void
 1025 upgt_vap_delete(struct ieee80211vap *vap)
 1026 {
 1027         struct upgt_vap *uvp = UPGT_VAP(vap);
 1028 
 1029         ieee80211_vap_detach(vap);
 1030         free(uvp, M_80211_VAP);
 1031 }
 1032 
 1033 static void
 1034 upgt_update_mcast(struct ieee80211com *ic)
 1035 {
 1036         struct upgt_softc *sc = ic->ic_softc;
 1037 
 1038         upgt_set_multi(sc);
 1039 }
 1040 
 1041 static int
 1042 upgt_eeprom_parse(struct upgt_softc *sc)
 1043 {
 1044         struct ieee80211com *ic = &sc->sc_ic;
 1045         struct upgt_eeprom_header *eeprom_header;
 1046         struct upgt_eeprom_option *eeprom_option;
 1047         uint16_t option_len;
 1048         uint16_t option_type;
 1049         uint16_t preamble_len;
 1050         int option_end = 0;
 1051 
 1052         /* calculate eeprom options start offset */
 1053         eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom;
 1054         preamble_len = le16toh(eeprom_header->preamble_len);
 1055         eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom +
 1056             (sizeof(struct upgt_eeprom_header) + preamble_len));
 1057 
 1058         while (!option_end) {
 1059                 /* sanity check */
 1060                 if (eeprom_option >= (struct upgt_eeprom_option *)
 1061                     (sc->sc_eeprom + UPGT_EEPROM_SIZE)) {
 1062                         return (EINVAL);
 1063                 }
 1064 
 1065                 /* the eeprom option length is stored in words */
 1066                 option_len =
 1067                     (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t);
 1068                 option_type =
 1069                     le16toh(eeprom_option->type);
 1070 
 1071                 /* sanity check */
 1072                 if (option_len == 0 || option_len >= UPGT_EEPROM_SIZE)
 1073                         return (EINVAL);
 1074 
 1075                 switch (option_type) {
 1076                 case UPGT_EEPROM_TYPE_NAME:
 1077                         DPRINTF(sc, UPGT_DEBUG_FW,
 1078                             "EEPROM name len=%d\n", option_len);
 1079                         break;
 1080                 case UPGT_EEPROM_TYPE_SERIAL:
 1081                         DPRINTF(sc, UPGT_DEBUG_FW,
 1082                             "EEPROM serial len=%d\n", option_len);
 1083                         break;
 1084                 case UPGT_EEPROM_TYPE_MAC:
 1085                         DPRINTF(sc, UPGT_DEBUG_FW,
 1086                             "EEPROM mac len=%d\n", option_len);
 1087 
 1088                         IEEE80211_ADDR_COPY(ic->ic_macaddr,
 1089                             eeprom_option->data);
 1090                         break;
 1091                 case UPGT_EEPROM_TYPE_HWRX:
 1092                         DPRINTF(sc, UPGT_DEBUG_FW,
 1093                             "EEPROM hwrx len=%d\n", option_len);
 1094 
 1095                         upgt_eeprom_parse_hwrx(sc, eeprom_option->data);
 1096                         break;
 1097                 case UPGT_EEPROM_TYPE_CHIP:
 1098                         DPRINTF(sc, UPGT_DEBUG_FW,
 1099                             "EEPROM chip len=%d\n", option_len);
 1100                         break;
 1101                 case UPGT_EEPROM_TYPE_FREQ3:
 1102                         DPRINTF(sc, UPGT_DEBUG_FW,
 1103                             "EEPROM freq3 len=%d\n", option_len);
 1104 
 1105                         upgt_eeprom_parse_freq3(sc, eeprom_option->data,
 1106                             option_len);
 1107                         break;
 1108                 case UPGT_EEPROM_TYPE_FREQ4:
 1109                         DPRINTF(sc, UPGT_DEBUG_FW,
 1110                             "EEPROM freq4 len=%d\n", option_len);
 1111 
 1112                         upgt_eeprom_parse_freq4(sc, eeprom_option->data,
 1113                             option_len);
 1114                         break;
 1115                 case UPGT_EEPROM_TYPE_FREQ5:
 1116                         DPRINTF(sc, UPGT_DEBUG_FW,
 1117                             "EEPROM freq5 len=%d\n", option_len);
 1118                         break;
 1119                 case UPGT_EEPROM_TYPE_FREQ6:
 1120                         DPRINTF(sc, UPGT_DEBUG_FW,
 1121                             "EEPROM freq6 len=%d\n", option_len);
 1122 
 1123                         upgt_eeprom_parse_freq6(sc, eeprom_option->data,
 1124                             option_len);
 1125                         break;
 1126                 case UPGT_EEPROM_TYPE_END:
 1127                         DPRINTF(sc, UPGT_DEBUG_FW,
 1128                             "EEPROM end len=%d\n", option_len);
 1129                         option_end = 1;
 1130                         break;
 1131                 case UPGT_EEPROM_TYPE_OFF:
 1132                         DPRINTF(sc, UPGT_DEBUG_FW,
 1133                             "%s: EEPROM off without end option\n", __func__);
 1134                         return (EIO);
 1135                 default:
 1136                         DPRINTF(sc, UPGT_DEBUG_FW,
 1137                             "EEPROM unknown type 0x%04x len=%d\n",
 1138                             option_type, option_len);
 1139                         break;
 1140                 }
 1141 
 1142                 /* jump to next EEPROM option */
 1143                 eeprom_option = (struct upgt_eeprom_option *)
 1144                     (eeprom_option->data + option_len);
 1145         }
 1146         return (0);
 1147 }
 1148 
 1149 static void
 1150 upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len)
 1151 {
 1152         struct upgt_eeprom_freq3_header *freq3_header;
 1153         struct upgt_lmac_freq3 *freq3;
 1154         int i;
 1155         int elements;
 1156         unsigned channel;
 1157 
 1158         freq3_header = (struct upgt_eeprom_freq3_header *)data;
 1159         freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1);
 1160 
 1161         elements = freq3_header->elements;
 1162 
 1163         DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d\n",
 1164             freq3_header->flags, elements);
 1165 
 1166         if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq3[0])))
 1167                 return;
 1168 
 1169         for (i = 0; i < elements; i++) {
 1170                 channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0);
 1171                 if (channel >= IEEE80211_CHAN_MAX)
 1172                         continue;
 1173 
 1174                 sc->sc_eeprom_freq3[channel] = freq3[i];
 1175 
 1176                 DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
 1177                     le16toh(sc->sc_eeprom_freq3[channel].freq), channel);
 1178         }
 1179 }
 1180 
 1181 void
 1182 upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len)
 1183 {
 1184         struct upgt_eeprom_freq4_header *freq4_header;
 1185         struct upgt_eeprom_freq4_1 *freq4_1;
 1186         struct upgt_eeprom_freq4_2 *freq4_2;
 1187         int i;
 1188         int j;
 1189         int elements;
 1190         int settings;
 1191         unsigned channel;
 1192 
 1193         freq4_header = (struct upgt_eeprom_freq4_header *)data;
 1194         freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1);
 1195         elements = freq4_header->elements;
 1196         settings = freq4_header->settings;
 1197 
 1198         /* we need this value later */
 1199         sc->sc_eeprom_freq6_settings = freq4_header->settings;
 1200 
 1201         DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d settings=%d\n",
 1202             freq4_header->flags, elements, settings);
 1203 
 1204         if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq4_1[0])))
 1205                 return;
 1206 
 1207         for (i = 0; i < elements; i++) {
 1208                 channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0);
 1209                 if (channel >= IEEE80211_CHAN_MAX)
 1210                         continue;
 1211 
 1212                 freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data;
 1213                 for (j = 0; j < settings; j++) {
 1214                         sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j];
 1215                         sc->sc_eeprom_freq4[channel][j].pad = 0;
 1216                 }
 1217 
 1218                 DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
 1219                     le16toh(freq4_1[i].freq), channel);
 1220         }
 1221 }
 1222 
 1223 void
 1224 upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len)
 1225 {
 1226         struct upgt_lmac_freq6 *freq6;
 1227         int i;
 1228         int elements;
 1229         unsigned channel;
 1230 
 1231         freq6 = (struct upgt_lmac_freq6 *)data;
 1232         elements = len / sizeof(struct upgt_lmac_freq6);
 1233 
 1234         DPRINTF(sc, UPGT_DEBUG_FW, "elements=%d\n", elements);
 1235 
 1236         if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq6[0])))
 1237                 return;
 1238 
 1239         for (i = 0; i < elements; i++) {
 1240                 channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0);
 1241                 if (channel >= IEEE80211_CHAN_MAX)
 1242                         continue;
 1243 
 1244                 sc->sc_eeprom_freq6[channel] = freq6[i];
 1245 
 1246                 DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
 1247                     le16toh(sc->sc_eeprom_freq6[channel].freq), channel);
 1248         }
 1249 }
 1250 
 1251 static void
 1252 upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data)
 1253 {
 1254         struct upgt_eeprom_option_hwrx *option_hwrx;
 1255 
 1256         option_hwrx = (struct upgt_eeprom_option_hwrx *)data;
 1257 
 1258         sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST;
 1259 
 1260         DPRINTF(sc, UPGT_DEBUG_FW, "hwrx option value=0x%04x\n",
 1261             sc->sc_eeprom_hwrx);
 1262 }
 1263 
 1264 static int
 1265 upgt_eeprom_read(struct upgt_softc *sc)
 1266 {
 1267         struct upgt_data *data_cmd;
 1268         struct upgt_lmac_mem *mem;
 1269         struct upgt_lmac_eeprom *eeprom;
 1270         int block, error, offset;
 1271 
 1272         UPGT_LOCK(sc);
 1273         usb_pause_mtx(&sc->sc_mtx, USB_MS_TO_TICKS(100));
 1274 
 1275         offset = 0;
 1276         block = UPGT_EEPROM_BLOCK_SIZE;
 1277         while (offset < UPGT_EEPROM_SIZE) {
 1278                 DPRINTF(sc, UPGT_DEBUG_FW,
 1279                     "request EEPROM block (offset=%d, len=%d)\n", offset, block);
 1280 
 1281                 data_cmd = upgt_getbuf(sc);
 1282                 if (data_cmd == NULL) {
 1283                         UPGT_UNLOCK(sc);
 1284                         return (ENOBUFS);
 1285                 }
 1286 
 1287                 /*
 1288                  * Transmit the URB containing the CMD data.
 1289                  */
 1290                 memset(data_cmd->buf, 0, MCLBYTES);
 1291 
 1292                 mem = (struct upgt_lmac_mem *)data_cmd->buf;
 1293                 mem->addr = htole32(sc->sc_memaddr_frame_start +
 1294                     UPGT_MEMSIZE_FRAME_HEAD);
 1295 
 1296                 eeprom = (struct upgt_lmac_eeprom *)(mem + 1);
 1297                 eeprom->header1.flags = 0;
 1298                 eeprom->header1.type = UPGT_H1_TYPE_CTRL;
 1299                 eeprom->header1.len = htole16((
 1300                     sizeof(struct upgt_lmac_eeprom) -
 1301                     sizeof(struct upgt_lmac_header)) + block);
 1302 
 1303                 eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start);
 1304                 eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM);
 1305                 eeprom->header2.flags = 0;
 1306 
 1307                 eeprom->offset = htole16(offset);
 1308                 eeprom->len = htole16(block);
 1309 
 1310                 data_cmd->buflen = sizeof(*mem) + sizeof(*eeprom) + block;
 1311 
 1312                 mem->chksum = upgt_chksum_le((uint32_t *)eeprom,
 1313                     data_cmd->buflen - sizeof(*mem));
 1314                 upgt_bulk_tx(sc, data_cmd);
 1315 
 1316                 error = mtx_sleep(sc, &sc->sc_mtx, 0, "eeprom_request", hz);
 1317                 if (error != 0) {
 1318                         device_printf(sc->sc_dev,
 1319                             "timeout while waiting for EEPROM data\n");
 1320                         UPGT_UNLOCK(sc);
 1321                         return (EIO);
 1322                 }
 1323 
 1324                 offset += block;
 1325                 if (UPGT_EEPROM_SIZE - offset < block)
 1326                         block = UPGT_EEPROM_SIZE - offset;
 1327         }
 1328 
 1329         UPGT_UNLOCK(sc);
 1330         return (0);
 1331 }
 1332 
 1333 /*
 1334  * When a rx data came in the function returns a mbuf and a rssi values.
 1335  */
 1336 static struct mbuf *
 1337 upgt_rxeof(struct usb_xfer *xfer, struct upgt_data *data, int *rssi)
 1338 {
 1339         struct mbuf *m = NULL;
 1340         struct upgt_softc *sc = usbd_xfer_softc(xfer);
 1341         struct upgt_lmac_header *header;
 1342         struct upgt_lmac_eeprom *eeprom;
 1343         uint8_t h1_type;
 1344         uint16_t h2_type;
 1345         int actlen, sumlen;
 1346 
 1347         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
 1348 
 1349         UPGT_ASSERT_LOCKED(sc);
 1350 
 1351         if (actlen < 1)
 1352                 return (NULL);
 1353 
 1354         /* Check only at the very beginning.  */
 1355         if (!(sc->sc_flags & UPGT_FLAG_FWLOADED) &&
 1356             (memcmp(data->buf, "OK", 2) == 0)) {
 1357                 sc->sc_flags |= UPGT_FLAG_FWLOADED;
 1358                 wakeup_one(sc);
 1359                 return (NULL);
 1360         }
 1361 
 1362         if (actlen < (int)UPGT_RX_MINSZ)
 1363                 return (NULL);
 1364 
 1365         /*
 1366          * Check what type of frame came in.
 1367          */
 1368         header = (struct upgt_lmac_header *)(data->buf + 4);
 1369 
 1370         h1_type = header->header1.type;
 1371         h2_type = le16toh(header->header2.type);
 1372 
 1373         if (h1_type == UPGT_H1_TYPE_CTRL && h2_type == UPGT_H2_TYPE_EEPROM) {
 1374                 eeprom = (struct upgt_lmac_eeprom *)(data->buf + 4);
 1375                 uint16_t eeprom_offset = le16toh(eeprom->offset);
 1376                 uint16_t eeprom_len = le16toh(eeprom->len);
 1377 
 1378                 DPRINTF(sc, UPGT_DEBUG_FW,
 1379                     "received EEPROM block (offset=%d, len=%d)\n",
 1380                     eeprom_offset, eeprom_len);
 1381 
 1382                 memcpy(sc->sc_eeprom + eeprom_offset,
 1383                     data->buf + sizeof(struct upgt_lmac_eeprom) + 4,
 1384                     eeprom_len);
 1385 
 1386                 /* EEPROM data has arrived in time, wakeup.  */
 1387                 wakeup(sc);
 1388         } else if (h1_type == UPGT_H1_TYPE_CTRL &&
 1389             h2_type == UPGT_H2_TYPE_TX_DONE) {
 1390                 DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: received 802.11 TX done\n",
 1391                     __func__);
 1392                 upgt_tx_done(sc, data->buf + 4);
 1393         } else if (h1_type == UPGT_H1_TYPE_RX_DATA ||
 1394             h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) {
 1395                 DPRINTF(sc, UPGT_DEBUG_RECV, "%s: received 802.11 RX data\n",
 1396                     __func__);
 1397                 m = upgt_rx(sc, data->buf + 4, le16toh(header->header1.len),
 1398                     rssi);
 1399         } else if (h1_type == UPGT_H1_TYPE_CTRL &&
 1400             h2_type == UPGT_H2_TYPE_STATS) {
 1401                 DPRINTF(sc, UPGT_DEBUG_STAT, "%s: received statistic data\n",
 1402                     __func__);
 1403                 /* TODO: what could we do with the statistic data? */
 1404         } else {
 1405                 /* ignore unknown frame types */
 1406                 DPRINTF(sc, UPGT_DEBUG_INTR,
 1407                     "received unknown frame type 0x%02x\n",
 1408                     header->header1.type);
 1409         }
 1410         return (m);
 1411 }
 1412 
 1413 /*
 1414  * The firmware awaits a checksum for each frame we send to it.
 1415  * The algorithm used therefor is uncommon but somehow similar to CRC32.
 1416  */
 1417 static uint32_t
 1418 upgt_chksum_le(const uint32_t *buf, size_t size)
 1419 {
 1420         size_t i;
 1421         uint32_t crc = 0;
 1422 
 1423         for (i = 0; i < size; i += sizeof(uint32_t)) {
 1424                 crc = htole32(crc ^ *buf++);
 1425                 crc = htole32((crc >> 5) ^ (crc << 3));
 1426         }
 1427 
 1428         return (crc);
 1429 }
 1430 
 1431 static struct mbuf *
 1432 upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
 1433 {
 1434         struct ieee80211com *ic = &sc->sc_ic;
 1435         struct upgt_lmac_rx_desc *rxdesc;
 1436         struct mbuf *m;
 1437 
 1438         /*
 1439          * don't pass packets to the ieee80211 framework if the driver isn't
 1440          * RUNNING.
 1441          */
 1442         if (!(sc->sc_flags & UPGT_FLAG_INITDONE))
 1443                 return (NULL);
 1444 
 1445         /* access RX packet descriptor */
 1446         rxdesc = (struct upgt_lmac_rx_desc *)data;
 1447 
 1448         /* create mbuf which is suitable for strict alignment archs */
 1449         KASSERT((pkglen + ETHER_ALIGN) < MCLBYTES,
 1450             ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN));
 1451         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
 1452         if (m == NULL) {
 1453                 device_printf(sc->sc_dev, "could not create RX mbuf\n");
 1454                 return (NULL);
 1455         }
 1456         m_adj(m, ETHER_ALIGN);
 1457         memcpy(mtod(m, char *), rxdesc->data, pkglen);
 1458         /* trim FCS */
 1459         m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
 1460 
 1461         if (ieee80211_radiotap_active(ic)) {
 1462                 struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
 1463 
 1464                 tap->wr_flags = 0;
 1465                 tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
 1466                 tap->wr_antsignal = rxdesc->rssi;
 1467         }
 1468 
 1469         DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__);
 1470         *rssi = rxdesc->rssi;
 1471         return (m);
 1472 }
 1473 
 1474 static uint8_t
 1475 upgt_rx_rate(struct upgt_softc *sc, const int rate)
 1476 {
 1477         struct ieee80211com *ic = &sc->sc_ic;
 1478         static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 };
 1479         static const uint8_t ofdm_upgt2rate[12] =
 1480             { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
 1481 
 1482         if (ic->ic_curmode == IEEE80211_MODE_11B &&
 1483             !(rate < 0 || rate > 3))
 1484                 return cck_upgt2rate[rate & 0xf];
 1485 
 1486         if (ic->ic_curmode == IEEE80211_MODE_11G &&
 1487             !(rate < 0 || rate > 11))
 1488                 return ofdm_upgt2rate[rate & 0xf];
 1489 
 1490         return (0);
 1491 }
 1492 
 1493 static void
 1494 upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
 1495 {
 1496         struct upgt_lmac_tx_done_desc *desc;
 1497         int i, freed = 0;
 1498 
 1499         UPGT_ASSERT_LOCKED(sc);
 1500 
 1501         desc = (struct upgt_lmac_tx_done_desc *)data;
 1502 
 1503         for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
 1504                 struct upgt_data *data_tx = &sc->sc_tx_data[i];
 1505 
 1506                 if (data_tx->addr == le32toh(desc->header2.reqid)) {
 1507                         upgt_mem_free(sc, data_tx->addr);
 1508                         data_tx->ni = NULL;
 1509                         data_tx->addr = 0;
 1510                         data_tx->m = NULL;
 1511 
 1512                         DPRINTF(sc, UPGT_DEBUG_TX_PROC,
 1513                             "TX done: memaddr=0x%08x, status=0x%04x, rssi=%d, ",
 1514                             le32toh(desc->header2.reqid),
 1515                             le16toh(desc->status), le16toh(desc->rssi));
 1516                         DPRINTF(sc, UPGT_DEBUG_TX_PROC, "seq=%d\n",
 1517                             le16toh(desc->seq));
 1518 
 1519                         freed++;
 1520                 }
 1521         }
 1522 
 1523         if (freed != 0) {
 1524                 UPGT_UNLOCK(sc);
 1525                 sc->sc_tx_timer = 0;
 1526                 upgt_start(sc);
 1527                 UPGT_LOCK(sc);
 1528         }
 1529 }
 1530 
 1531 static void
 1532 upgt_mem_free(struct upgt_softc *sc, uint32_t addr)
 1533 {
 1534         int i;
 1535 
 1536         for (i = 0; i < sc->sc_memory.pages; i++) {
 1537                 if (sc->sc_memory.page[i].addr == addr) {
 1538                         sc->sc_memory.page[i].used = 0;
 1539                         return;
 1540                 }
 1541         }
 1542 
 1543         device_printf(sc->sc_dev,
 1544             "could not free memory address 0x%08x\n", addr);
 1545 }
 1546 
 1547 static int
 1548 upgt_fw_load(struct upgt_softc *sc)
 1549 {
 1550         const struct firmware *fw;
 1551         struct upgt_data *data_cmd;
 1552         struct upgt_fw_x2_header *x2;
 1553         char start_fwload_cmd[] = { 0x3c, 0x0d };
 1554         int error = 0;
 1555         size_t offset;
 1556         int bsize;
 1557         int n;
 1558         uint32_t crc32;
 1559 
 1560         fw = firmware_get(upgt_fwname);
 1561         if (fw == NULL) {
 1562                 device_printf(sc->sc_dev, "could not read microcode %s\n",
 1563                     upgt_fwname);
 1564                 return (EIO);
 1565         }
 1566 
 1567         UPGT_LOCK(sc);
 1568 
 1569         /* send firmware start load command */
 1570         data_cmd = upgt_getbuf(sc);
 1571         if (data_cmd == NULL) {
 1572                 error = ENOBUFS;
 1573                 goto fail;
 1574         }
 1575         data_cmd->buflen = sizeof(start_fwload_cmd);
 1576         memcpy(data_cmd->buf, start_fwload_cmd, data_cmd->buflen);
 1577         upgt_bulk_tx(sc, data_cmd);
 1578 
 1579         /* send X2 header */
 1580         data_cmd = upgt_getbuf(sc);
 1581         if (data_cmd == NULL) {
 1582                 error = ENOBUFS;
 1583                 goto fail;
 1584         }
 1585         data_cmd->buflen = sizeof(struct upgt_fw_x2_header);
 1586         x2 = (struct upgt_fw_x2_header *)data_cmd->buf;
 1587         memcpy(x2->signature, UPGT_X2_SIGNATURE, UPGT_X2_SIGNATURE_SIZE);
 1588         x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START);
 1589         x2->len = htole32(fw->datasize);
 1590         x2->crc = upgt_crc32_le((uint8_t *)data_cmd->buf +
 1591             UPGT_X2_SIGNATURE_SIZE,
 1592             sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE -
 1593             sizeof(uint32_t));
 1594         upgt_bulk_tx(sc, data_cmd);
 1595 
 1596         /* download firmware */
 1597         for (offset = 0; offset < fw->datasize; offset += bsize) {
 1598                 if (fw->datasize - offset > UPGT_FW_BLOCK_SIZE)
 1599                         bsize = UPGT_FW_BLOCK_SIZE;
 1600                 else
 1601                         bsize = fw->datasize - offset;
 1602 
 1603                 data_cmd = upgt_getbuf(sc);
 1604                 if (data_cmd == NULL) {
 1605                         error = ENOBUFS;
 1606                         goto fail;
 1607                 }
 1608                 n = upgt_fw_copy((const uint8_t *)fw->data + offset,
 1609                     data_cmd->buf, bsize);
 1610                 data_cmd->buflen = bsize;
 1611                 upgt_bulk_tx(sc, data_cmd);
 1612 
 1613                 DPRINTF(sc, UPGT_DEBUG_FW, "FW offset=%zu, read=%d, sent=%d\n",
 1614                     offset, n, bsize);
 1615                 bsize = n;
 1616         }
 1617         DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware downloaded\n", __func__);
 1618 
 1619         /* load firmware */
 1620         data_cmd = upgt_getbuf(sc);
 1621         if (data_cmd == NULL) {
 1622                 error = ENOBUFS;
 1623                 goto fail;
 1624         }
 1625         crc32 = upgt_crc32_le(fw->data, fw->datasize);
 1626         *((uint32_t *)(data_cmd->buf)    ) = crc32;
 1627         *((uint8_t  *)(data_cmd->buf) + 4) = 'g';
 1628         *((uint8_t  *)(data_cmd->buf) + 5) = '\r';
 1629         data_cmd->buflen = 6;
 1630         upgt_bulk_tx(sc, data_cmd);
 1631 
 1632         /* waiting 'OK' response.  */
 1633         usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
 1634         error = mtx_sleep(sc, &sc->sc_mtx, 0, "upgtfw", 2 * hz);
 1635         if (error != 0) {
 1636                 device_printf(sc->sc_dev, "firmware load failed\n");
 1637                 error = EIO;
 1638         }
 1639 
 1640         DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware loaded\n", __func__);
 1641 fail:
 1642         UPGT_UNLOCK(sc);
 1643         firmware_put(fw, FIRMWARE_UNLOAD);
 1644         return (error);
 1645 }
 1646 
 1647 static uint32_t
 1648 upgt_crc32_le(const void *buf, size_t size)
 1649 {
 1650         uint32_t crc;
 1651 
 1652         crc = ether_crc32_le(buf, size);
 1653 
 1654         /* apply final XOR value as common for CRC-32 */
 1655         crc = htole32(crc ^ 0xffffffffU);
 1656 
 1657         return (crc);
 1658 }
 1659 
 1660 /*
 1661  * While copying the version 2 firmware, we need to replace two characters:
 1662  *
 1663  * 0x7e -> 0x7d 0x5e
 1664  * 0x7d -> 0x7d 0x5d
 1665  */
 1666 static int
 1667 upgt_fw_copy(const uint8_t *src, char *dst, int size)
 1668 {
 1669         int i, j;
 1670 
 1671         for (i = 0, j = 0; i < size && j < size; i++) {
 1672                 switch (src[i]) {
 1673                 case 0x7e:
 1674                         dst[j] = 0x7d;
 1675                         j++;
 1676                         dst[j] = 0x5e;
 1677                         j++;
 1678                         break;
 1679                 case 0x7d:
 1680                         dst[j] = 0x7d;
 1681                         j++;
 1682                         dst[j] = 0x5d;
 1683                         j++;
 1684                         break;
 1685                 default:
 1686                         dst[j] = src[i];
 1687                         j++;
 1688                         break;
 1689                 }
 1690         }
 1691 
 1692         return (i);
 1693 }
 1694 
 1695 static int
 1696 upgt_mem_init(struct upgt_softc *sc)
 1697 {
 1698         int i;
 1699 
 1700         for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) {
 1701                 sc->sc_memory.page[i].used = 0;
 1702 
 1703                 if (i == 0) {
 1704                         /*
 1705                          * The first memory page is always reserved for
 1706                          * command data.
 1707                          */
 1708                         sc->sc_memory.page[i].addr =
 1709                             sc->sc_memaddr_frame_start + MCLBYTES;
 1710                 } else {
 1711                         sc->sc_memory.page[i].addr =
 1712                             sc->sc_memory.page[i - 1].addr + MCLBYTES;
 1713                 }
 1714 
 1715                 if (sc->sc_memory.page[i].addr + MCLBYTES >=
 1716                     sc->sc_memaddr_frame_end)
 1717                         break;
 1718 
 1719                 DPRINTF(sc, UPGT_DEBUG_FW, "memory address page %d=0x%08x\n",
 1720                     i, sc->sc_memory.page[i].addr);
 1721         }
 1722 
 1723         sc->sc_memory.pages = i;
 1724 
 1725         DPRINTF(sc, UPGT_DEBUG_FW, "memory pages=%d\n", sc->sc_memory.pages);
 1726         return (0);
 1727 }
 1728 
 1729 static int
 1730 upgt_fw_verify(struct upgt_softc *sc)
 1731 {
 1732         const struct firmware *fw;
 1733         const struct upgt_fw_bra_option *bra_opt;
 1734         const struct upgt_fw_bra_descr *descr;
 1735         const uint8_t *p;
 1736         const uint32_t *uc;
 1737         uint32_t bra_option_type, bra_option_len;
 1738         size_t offset;
 1739         int bra_end = 0;
 1740         int error = 0;
 1741 
 1742         fw = firmware_get(upgt_fwname);
 1743         if (fw == NULL) {
 1744                 device_printf(sc->sc_dev, "could not read microcode %s\n",
 1745                     upgt_fwname);
 1746                 return EIO;
 1747         }
 1748 
 1749         /*
 1750          * Seek to beginning of Boot Record Area (BRA).
 1751          */
 1752         for (offset = 0; offset < fw->datasize; offset += sizeof(*uc)) {
 1753                 uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
 1754                 if (*uc == 0)
 1755                         break;
 1756         }
 1757         for (; offset < fw->datasize; offset += sizeof(*uc)) {
 1758                 uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
 1759                 if (*uc != 0)
 1760                         break;
 1761         }
 1762         if (offset == fw->datasize) { 
 1763                 device_printf(sc->sc_dev,
 1764                     "firmware Boot Record Area not found\n");
 1765                 error = EIO;
 1766                 goto fail;
 1767         }
 1768 
 1769         DPRINTF(sc, UPGT_DEBUG_FW,
 1770             "firmware Boot Record Area found at offset %zu\n", offset);
 1771 
 1772         /*
 1773          * Parse Boot Record Area (BRA) options.
 1774          */
 1775         while (offset < fw->datasize && bra_end == 0) {
 1776                 /* get current BRA option */
 1777                 p = (const uint8_t *)fw->data + offset;
 1778                 bra_opt = (const struct upgt_fw_bra_option *)p;
 1779                 bra_option_type = le32toh(bra_opt->type);
 1780                 bra_option_len = le32toh(bra_opt->len) * sizeof(*uc);
 1781 
 1782                 switch (bra_option_type) {
 1783                 case UPGT_BRA_TYPE_FW:
 1784                         DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_FW len=%d\n",
 1785                             bra_option_len);
 1786 
 1787                         if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) {
 1788                                 device_printf(sc->sc_dev,
 1789                                     "wrong UPGT_BRA_TYPE_FW len\n");
 1790                                 error = EIO;
 1791                                 goto fail;
 1792                         }
 1793                         if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_opt->data,
 1794                             bra_option_len) == 0) {
 1795                                 sc->sc_fw_type = UPGT_FWTYPE_LM86;
 1796                                 break;
 1797                         }
 1798                         if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_opt->data,
 1799                             bra_option_len) == 0) {
 1800                                 sc->sc_fw_type = UPGT_FWTYPE_LM87;
 1801                                 break;
 1802                         }
 1803                         device_printf(sc->sc_dev,
 1804                             "unsupported firmware type\n");
 1805                         error = EIO;
 1806                         goto fail;
 1807                 case UPGT_BRA_TYPE_VERSION:
 1808                         DPRINTF(sc, UPGT_DEBUG_FW,
 1809                             "UPGT_BRA_TYPE_VERSION len=%d\n", bra_option_len);
 1810                         break;
 1811                 case UPGT_BRA_TYPE_DEPIF:
 1812                         DPRINTF(sc, UPGT_DEBUG_FW,
 1813                             "UPGT_BRA_TYPE_DEPIF len=%d\n", bra_option_len);
 1814                         break;
 1815                 case UPGT_BRA_TYPE_EXPIF:
 1816                         DPRINTF(sc, UPGT_DEBUG_FW,
 1817                             "UPGT_BRA_TYPE_EXPIF len=%d\n", bra_option_len);
 1818                         break;
 1819                 case UPGT_BRA_TYPE_DESCR:
 1820                         DPRINTF(sc, UPGT_DEBUG_FW,
 1821                             "UPGT_BRA_TYPE_DESCR len=%d\n", bra_option_len);
 1822 
 1823                         descr = (const struct upgt_fw_bra_descr *)bra_opt->data;
 1824 
 1825                         sc->sc_memaddr_frame_start =
 1826                             le32toh(descr->memaddr_space_start);
 1827                         sc->sc_memaddr_frame_end =
 1828                             le32toh(descr->memaddr_space_end);
 1829 
 1830                         DPRINTF(sc, UPGT_DEBUG_FW,
 1831                             "memory address space start=0x%08x\n",
 1832                             sc->sc_memaddr_frame_start);
 1833                         DPRINTF(sc, UPGT_DEBUG_FW,
 1834                             "memory address space end=0x%08x\n",
 1835                             sc->sc_memaddr_frame_end);
 1836                         break;
 1837                 case UPGT_BRA_TYPE_END:
 1838                         DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_END len=%d\n",
 1839                             bra_option_len);
 1840                         bra_end = 1;
 1841                         break;
 1842                 default:
 1843                         DPRINTF(sc, UPGT_DEBUG_FW, "unknown BRA option len=%d\n",
 1844                             bra_option_len);
 1845                         error = EIO;
 1846                         goto fail;
 1847                 }
 1848 
 1849                 /* jump to next BRA option */
 1850                 offset += sizeof(struct upgt_fw_bra_option) + bra_option_len;
 1851         }
 1852 
 1853         DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware verified", __func__);
 1854 fail:
 1855         firmware_put(fw, FIRMWARE_UNLOAD);
 1856         return (error);
 1857 }
 1858 
 1859 static void
 1860 upgt_bulk_tx(struct upgt_softc *sc, struct upgt_data *data)
 1861 {
 1862 
 1863         UPGT_ASSERT_LOCKED(sc);
 1864 
 1865         STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
 1866         UPGT_STAT_INC(sc, st_tx_pending);
 1867         usbd_transfer_start(sc->sc_xfer[UPGT_BULK_TX]);
 1868 }
 1869 
 1870 static int
 1871 upgt_device_reset(struct upgt_softc *sc)
 1872 {
 1873         struct upgt_data *data;
 1874         char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e };
 1875 
 1876         UPGT_LOCK(sc);
 1877 
 1878         data = upgt_getbuf(sc);
 1879         if (data == NULL) {
 1880                 UPGT_UNLOCK(sc);
 1881                 return (ENOBUFS);
 1882         }
 1883         memcpy(data->buf, init_cmd, sizeof(init_cmd));
 1884         data->buflen = sizeof(init_cmd);
 1885         upgt_bulk_tx(sc, data);
 1886         usb_pause_mtx(&sc->sc_mtx, USB_MS_TO_TICKS(100));
 1887 
 1888         UPGT_UNLOCK(sc);
 1889         DPRINTF(sc, UPGT_DEBUG_FW, "%s: device initialized\n", __func__);
 1890         return (0);
 1891 }
 1892 
 1893 static int
 1894 upgt_alloc_tx(struct upgt_softc *sc)
 1895 {
 1896         int i;
 1897 
 1898         STAILQ_INIT(&sc->sc_tx_active);
 1899         STAILQ_INIT(&sc->sc_tx_inactive);
 1900         STAILQ_INIT(&sc->sc_tx_pending);
 1901 
 1902         for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
 1903                 struct upgt_data *data = &sc->sc_tx_data[i];
 1904                 data->buf = ((uint8_t *)sc->sc_tx_dma_buf) + (i * MCLBYTES);
 1905                 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
 1906                 UPGT_STAT_INC(sc, st_tx_inactive);
 1907         }
 1908 
 1909         return (0);
 1910 }
 1911 
 1912 static int
 1913 upgt_alloc_rx(struct upgt_softc *sc)
 1914 {
 1915         int i;
 1916 
 1917         STAILQ_INIT(&sc->sc_rx_active);
 1918         STAILQ_INIT(&sc->sc_rx_inactive);
 1919 
 1920         for (i = 0; i < UPGT_RX_MAXCOUNT; i++) {
 1921                 struct upgt_data *data = &sc->sc_rx_data[i];
 1922                 data->buf = ((uint8_t *)sc->sc_rx_dma_buf) + (i * MCLBYTES);
 1923                 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
 1924         }
 1925         return (0);
 1926 }
 1927 
 1928 static int
 1929 upgt_detach(device_t dev)
 1930 {
 1931         struct upgt_softc *sc = device_get_softc(dev);
 1932         struct ieee80211com *ic = &sc->sc_ic;
 1933         unsigned x;
 1934 
 1935         /*
 1936          * Prevent further allocations from RX/TX/CMD
 1937          * data lists and ioctls
 1938          */
 1939         UPGT_LOCK(sc);
 1940         sc->sc_flags |= UPGT_FLAG_DETACHED;
 1941 
 1942         STAILQ_INIT(&sc->sc_tx_active);
 1943         STAILQ_INIT(&sc->sc_tx_inactive);
 1944         STAILQ_INIT(&sc->sc_tx_pending);
 1945 
 1946         STAILQ_INIT(&sc->sc_rx_active);
 1947         STAILQ_INIT(&sc->sc_rx_inactive);
 1948 
 1949         upgt_stop(sc);
 1950         UPGT_UNLOCK(sc);
 1951 
 1952         callout_drain(&sc->sc_led_ch);
 1953         callout_drain(&sc->sc_watchdog_ch);
 1954 
 1955         /* drain USB transfers */
 1956         for (x = 0; x != UPGT_N_XFERS; x++)
 1957                 usbd_transfer_drain(sc->sc_xfer[x]);
 1958 
 1959         /* free data buffers */
 1960         UPGT_LOCK(sc);
 1961         upgt_free_rx(sc);
 1962         upgt_free_tx(sc);
 1963         UPGT_UNLOCK(sc);
 1964 
 1965         /* free USB transfers and some data buffers */
 1966         usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
 1967 
 1968         ieee80211_ifdetach(ic);
 1969         mbufq_drain(&sc->sc_snd);
 1970         mtx_destroy(&sc->sc_mtx);
 1971 
 1972         return (0);
 1973 }
 1974 
 1975 static void
 1976 upgt_free_rx(struct upgt_softc *sc)
 1977 {
 1978         int i;
 1979 
 1980         for (i = 0; i < UPGT_RX_MAXCOUNT; i++) {
 1981                 struct upgt_data *data = &sc->sc_rx_data[i];
 1982 
 1983                 data->buf = NULL;
 1984                 data->ni = NULL;
 1985         }
 1986 }
 1987 
 1988 static void
 1989 upgt_free_tx(struct upgt_softc *sc)
 1990 {
 1991         int i;
 1992 
 1993         for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
 1994                 struct upgt_data *data = &sc->sc_tx_data[i];
 1995 
 1996                 if (data->ni != NULL)
 1997                         ieee80211_free_node(data->ni);
 1998 
 1999                 data->buf = NULL;
 2000                 data->ni = NULL;
 2001         }
 2002 }
 2003 
 2004 static void
 2005 upgt_abort_xfers_locked(struct upgt_softc *sc)
 2006 {
 2007         int i;
 2008 
 2009         UPGT_ASSERT_LOCKED(sc);
 2010         /* abort any pending transfers */
 2011         for (i = 0; i < UPGT_N_XFERS; i++)
 2012                 usbd_transfer_stop(sc->sc_xfer[i]);
 2013 }
 2014 
 2015 static void
 2016 upgt_abort_xfers(struct upgt_softc *sc)
 2017 {
 2018 
 2019         UPGT_LOCK(sc);
 2020         upgt_abort_xfers_locked(sc);
 2021         UPGT_UNLOCK(sc);
 2022 }
 2023 
 2024 #define UPGT_SYSCTL_STAT_ADD32(c, h, n, p, d)   \
 2025             SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
 2026 
 2027 static void
 2028 upgt_sysctl_node(struct upgt_softc *sc)
 2029 {
 2030         struct sysctl_ctx_list *ctx;
 2031         struct sysctl_oid_list *child;
 2032         struct sysctl_oid *tree;
 2033         struct upgt_stat *stats;
 2034 
 2035         stats = &sc->sc_stat;
 2036         ctx = device_get_sysctl_ctx(sc->sc_dev);
 2037         child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
 2038 
 2039         tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
 2040             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "UPGT statistics");
 2041         child = SYSCTL_CHILDREN(tree);
 2042         UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_active",
 2043             &stats->st_tx_active, "Active numbers in TX queue");
 2044         UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_inactive",
 2045             &stats->st_tx_inactive, "Inactive numbers in TX queue");
 2046         UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_pending",
 2047             &stats->st_tx_pending, "Pending numbers in TX queue");
 2048 }
 2049 
 2050 #undef UPGT_SYSCTL_STAT_ADD32
 2051 
 2052 static struct upgt_data *
 2053 _upgt_getbuf(struct upgt_softc *sc)
 2054 {
 2055         struct upgt_data *bf;
 2056 
 2057         bf = STAILQ_FIRST(&sc->sc_tx_inactive);
 2058         if (bf != NULL) {
 2059                 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
 2060                 UPGT_STAT_DEC(sc, st_tx_inactive);
 2061         } else
 2062                 bf = NULL;
 2063         if (bf == NULL)
 2064                 DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: %s\n", __func__,
 2065                     "out of xmit buffers");
 2066         return (bf);
 2067 }
 2068 
 2069 static struct upgt_data *
 2070 upgt_getbuf(struct upgt_softc *sc)
 2071 {
 2072         struct upgt_data *bf;
 2073 
 2074         UPGT_ASSERT_LOCKED(sc);
 2075 
 2076         bf = _upgt_getbuf(sc);
 2077         if (bf == NULL)
 2078                 DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__);
 2079 
 2080         return (bf);
 2081 }
 2082 
 2083 static struct upgt_data *
 2084 upgt_gettxbuf(struct upgt_softc *sc)
 2085 {
 2086         struct upgt_data *bf;
 2087 
 2088         UPGT_ASSERT_LOCKED(sc);
 2089 
 2090         bf = upgt_getbuf(sc);
 2091         if (bf == NULL)
 2092                 return (NULL);
 2093 
 2094         bf->addr = upgt_mem_alloc(sc);
 2095         if (bf->addr == 0) {
 2096                 DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n",
 2097                     __func__);
 2098                 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
 2099                 UPGT_STAT_INC(sc, st_tx_inactive);
 2100                 return (NULL);
 2101         }
 2102         return (bf);
 2103 }
 2104 
 2105 static int
 2106 upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
 2107     struct upgt_data *data)
 2108 {
 2109         struct ieee80211vap *vap = ni->ni_vap;
 2110         int error = 0, len;
 2111         struct ieee80211_frame *wh;
 2112         struct ieee80211_key *k;
 2113         struct upgt_lmac_mem *mem;
 2114         struct upgt_lmac_tx_desc *txdesc;
 2115 
 2116         UPGT_ASSERT_LOCKED(sc);
 2117 
 2118         upgt_set_led(sc, UPGT_LED_BLINK);
 2119 
 2120         /*
 2121          * Software crypto.
 2122          */
 2123         wh = mtod(m, struct ieee80211_frame *);
 2124         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 2125                 k = ieee80211_crypto_encap(ni, m);
 2126                 if (k == NULL) {
 2127                         device_printf(sc->sc_dev,
 2128                             "ieee80211_crypto_encap returns NULL.\n");
 2129                         error = EIO;
 2130                         goto done;
 2131                 }
 2132 
 2133                 /* in case packet header moved, reset pointer */
 2134                 wh = mtod(m, struct ieee80211_frame *);
 2135         }
 2136 
 2137         /* Transmit the URB containing the TX data.  */
 2138         memset(data->buf, 0, MCLBYTES);
 2139         mem = (struct upgt_lmac_mem *)data->buf;
 2140         mem->addr = htole32(data->addr);
 2141         txdesc = (struct upgt_lmac_tx_desc *)(mem + 1);
 2142 
 2143         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
 2144             IEEE80211_FC0_TYPE_MGT) {
 2145                 /* mgmt frames  */
 2146                 txdesc->header1.flags = UPGT_H1_FLAGS_TX_MGMT;
 2147                 /* always send mgmt frames at lowest rate (DS1) */
 2148                 memset(txdesc->rates, 0x10, sizeof(txdesc->rates));
 2149         } else {
 2150                 /* data frames  */
 2151                 txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA;
 2152                 memcpy(txdesc->rates, sc->sc_cur_rateset, sizeof(txdesc->rates));
 2153         }
 2154         txdesc->header1.type = UPGT_H1_TYPE_TX_DATA;
 2155         txdesc->header1.len = htole16(m->m_pkthdr.len);
 2156         txdesc->header2.reqid = htole32(data->addr);
 2157         txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES);
 2158         txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES);
 2159         txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
 2160         txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
 2161 
 2162         if (ieee80211_radiotap_active_vap(vap)) {
 2163                 struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
 2164 
 2165                 tap->wt_flags = 0;
 2166                 tap->wt_rate = 0;       /* XXX where to get from? */
 2167 
 2168                 ieee80211_radiotap_tx(vap, m);
 2169         }
 2170 
 2171         /* copy frame below our TX descriptor header */
 2172         m_copydata(m, 0, m->m_pkthdr.len,
 2173             data->buf + (sizeof(*mem) + sizeof(*txdesc)));
 2174         /* calculate frame size */
 2175         len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len;
 2176         /* we need to align the frame to a 4 byte boundary */
 2177         len = (len + 3) & ~3;
 2178         /* calculate frame checksum */
 2179         mem->chksum = upgt_chksum_le((uint32_t *)txdesc, len - sizeof(*mem));
 2180         data->ni = ni;
 2181         data->m = m;
 2182         data->buflen = len;
 2183 
 2184         DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: TX start data sending (%d bytes)\n",
 2185             __func__, len);
 2186         KASSERT(len <= MCLBYTES, ("mbuf is small for saving data"));
 2187 
 2188         upgt_bulk_tx(sc, data);
 2189 done:
 2190         /*
 2191          * If we don't regulary read the device statistics, the RX queue
 2192          * will stall.  It's strange, but it works, so we keep reading
 2193          * the statistics here.  *shrug*
 2194          */
 2195         if (!(vap->iv_ifp->if_get_counter(vap->iv_ifp, IFCOUNTER_OPACKETS) %
 2196             UPGT_TX_STAT_INTERVAL))
 2197                 upgt_get_stats(sc);
 2198 
 2199         return (error);
 2200 }
 2201 
 2202 static void
 2203 upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
 2204 {
 2205         struct upgt_softc *sc = usbd_xfer_softc(xfer);
 2206         struct ieee80211com *ic = &sc->sc_ic;
 2207         struct ieee80211_frame *wh;
 2208         struct ieee80211_node *ni;
 2209         struct epoch_tracker et;
 2210         struct mbuf *m = NULL;
 2211         struct upgt_data *data;
 2212         int8_t nf;
 2213         int rssi = -1;
 2214 
 2215         UPGT_ASSERT_LOCKED(sc);
 2216 
 2217         switch (USB_GET_STATE(xfer)) {
 2218         case USB_ST_TRANSFERRED:
 2219                 data = STAILQ_FIRST(&sc->sc_rx_active);
 2220                 if (data == NULL)
 2221                         goto setup;
 2222                 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
 2223                 m = upgt_rxeof(xfer, data, &rssi);
 2224                 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
 2225                 /* FALLTHROUGH */
 2226         case USB_ST_SETUP:
 2227 setup:
 2228                 data = STAILQ_FIRST(&sc->sc_rx_inactive);
 2229                 if (data == NULL)
 2230                         return;
 2231                 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
 2232                 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
 2233                 usbd_xfer_set_frame_data(xfer, 0, data->buf, MCLBYTES);
 2234                 usbd_transfer_submit(xfer);
 2235 
 2236                 /*
 2237                  * To avoid LOR we should unlock our private mutex here to call
 2238                  * ieee80211_input() because here is at the end of a USB
 2239                  * callback and safe to unlock.
 2240                  */
 2241                 UPGT_UNLOCK(sc);
 2242                 if (m != NULL) {
 2243                         wh = mtod(m, struct ieee80211_frame *);
 2244                         ni = ieee80211_find_rxnode(ic,
 2245                             (struct ieee80211_frame_min *)wh);
 2246                         nf = -95;       /* XXX */
 2247                         NET_EPOCH_ENTER(et);
 2248                         if (ni != NULL) {
 2249                                 (void) ieee80211_input(ni, m, rssi, nf);
 2250                                 /* node is no longer needed */
 2251                                 ieee80211_free_node(ni);
 2252                         } else
 2253                                 (void) ieee80211_input_all(ic, m, rssi, nf);
 2254                         NET_EPOCH_EXIT(et);
 2255                         m = NULL;
 2256                 }
 2257                 UPGT_LOCK(sc);
 2258                 upgt_start(sc);
 2259                 break;
 2260         default:
 2261                 /* needs it to the inactive queue due to a error.  */
 2262                 data = STAILQ_FIRST(&sc->sc_rx_active);
 2263                 if (data != NULL) {
 2264                         STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
 2265                         STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
 2266                 }
 2267                 if (error != USB_ERR_CANCELLED) {
 2268                         usbd_xfer_set_stall(xfer);
 2269                         counter_u64_add(ic->ic_ierrors, 1);
 2270                         goto setup;
 2271                 }
 2272                 break;
 2273         }
 2274 }
 2275 
 2276 static void
 2277 upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
 2278 {
 2279         struct upgt_softc *sc = usbd_xfer_softc(xfer);
 2280         struct upgt_data *data;
 2281 
 2282         UPGT_ASSERT_LOCKED(sc);
 2283         switch (USB_GET_STATE(xfer)) {
 2284         case USB_ST_TRANSFERRED:
 2285                 data = STAILQ_FIRST(&sc->sc_tx_active);
 2286                 if (data == NULL)
 2287                         goto setup;
 2288                 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
 2289                 UPGT_STAT_DEC(sc, st_tx_active);
 2290                 upgt_txeof(xfer, data);
 2291                 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
 2292                 UPGT_STAT_INC(sc, st_tx_inactive);
 2293                 /* FALLTHROUGH */
 2294         case USB_ST_SETUP:
 2295 setup:
 2296                 data = STAILQ_FIRST(&sc->sc_tx_pending);
 2297                 if (data == NULL) {
 2298                         DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: empty pending queue\n",
 2299                             __func__);
 2300                         return;
 2301                 }
 2302                 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
 2303                 UPGT_STAT_DEC(sc, st_tx_pending);
 2304                 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
 2305                 UPGT_STAT_INC(sc, st_tx_active);
 2306 
 2307                 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
 2308                 usbd_transfer_submit(xfer);
 2309                 upgt_start(sc);
 2310                 break;
 2311         default:
 2312                 data = STAILQ_FIRST(&sc->sc_tx_active);
 2313                 if (data == NULL)
 2314                         goto setup;
 2315                 if (data->ni != NULL) {
 2316                         if_inc_counter(data->ni->ni_vap->iv_ifp,
 2317                             IFCOUNTER_OERRORS, 1);
 2318                         ieee80211_free_node(data->ni);
 2319                         data->ni = NULL;
 2320                 }
 2321                 if (error != USB_ERR_CANCELLED) {
 2322                         usbd_xfer_set_stall(xfer);
 2323                         goto setup;
 2324                 }
 2325                 break;
 2326         }
 2327 }
 2328 
 2329 static device_method_t upgt_methods[] = {
 2330         /* Device interface */
 2331         DEVMETHOD(device_probe, upgt_match),
 2332         DEVMETHOD(device_attach, upgt_attach),
 2333         DEVMETHOD(device_detach, upgt_detach),
 2334         DEVMETHOD_END
 2335 };
 2336 
 2337 static driver_t upgt_driver = {
 2338         .name = "upgt",
 2339         .methods = upgt_methods,
 2340         .size = sizeof(struct upgt_softc)
 2341 };
 2342 
 2343 DRIVER_MODULE(if_upgt, uhub, upgt_driver, NULL, NULL);
 2344 MODULE_VERSION(if_upgt, 1);
 2345 MODULE_DEPEND(if_upgt, usb, 1, 1, 1);
 2346 MODULE_DEPEND(if_upgt, wlan, 1, 1, 1);
 2347 MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1);
 2348 USB_PNP_HOST_INFO(upgt_devs);

Cache object: f6f1d7a18018d46b2bfe56adf7c1113c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.