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/otus/if_otus.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_otus.c,v 1.49 2015/11/24 13:33:18 mpi Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
    5  * Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.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 /*
   21  * Driver for Atheros AR9001U chipset.
   22  */
   23 
   24 #include <sys/cdefs.h>
   25 __FBSDID("$FreeBSD$");
   26 
   27 #include "opt_wlan.h"
   28 
   29 #include <sys/param.h>
   30 #include <sys/endian.h>
   31 #include <sys/sockio.h>
   32 #include <sys/mbuf.h>
   33 #include <sys/kernel.h>
   34 #include <sys/malloc.h>
   35 #include <sys/socket.h>
   36 #include <sys/systm.h>
   37 #include <sys/conf.h>
   38 #include <sys/bus.h>
   39 #include <sys/rman.h>
   40 #include <sys/firmware.h>
   41 #include <sys/module.h>
   42 #include <sys/taskqueue.h>
   43 
   44 #include <machine/bus.h>
   45 #include <machine/resource.h>
   46 
   47 #include <net/bpf.h>
   48 #include <net/if.h>
   49 #include <net/if_var.h>
   50 #include <net/if_arp.h>
   51 #include <net/if_dl.h>
   52 #include <net/if_media.h>
   53 
   54 #include <netinet/in.h>
   55 #include <netinet/in_systm.h>
   56 #include <netinet/in_var.h>
   57 #include <netinet/if_ether.h>
   58 #include <netinet/ip.h>
   59 
   60 #include <net80211/ieee80211_var.h>
   61 #include <net80211/ieee80211_regdomain.h>
   62 #include <net80211/ieee80211_radiotap.h>
   63 #include <net80211/ieee80211_ratectl.h>
   64 #ifdef  IEEE80211_SUPPORT_SUPERG
   65 #include <net80211/ieee80211_superg.h>
   66 #endif
   67 
   68 #include <dev/usb/usb.h>
   69 #include <dev/usb/usbdi.h>
   70 #include "usbdevs.h"
   71 
   72 #define USB_DEBUG_VAR otus_debug
   73 #include <dev/usb/usb_debug.h>
   74 
   75 #include "if_otusreg.h"
   76 
   77 static int otus_debug = 0;
   78 static SYSCTL_NODE(_hw_usb, OID_AUTO, otus, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   79     "USB otus");
   80 SYSCTL_INT(_hw_usb_otus, OID_AUTO, debug, CTLFLAG_RWTUN, &otus_debug, 0,
   81     "Debug level");
   82 #define OTUS_DEBUG_XMIT         0x00000001
   83 #define OTUS_DEBUG_RECV         0x00000002
   84 #define OTUS_DEBUG_TXDONE       0x00000004
   85 #define OTUS_DEBUG_RXDONE       0x00000008
   86 #define OTUS_DEBUG_CMD          0x00000010
   87 #define OTUS_DEBUG_CMDDONE      0x00000020
   88 #define OTUS_DEBUG_RESET        0x00000040
   89 #define OTUS_DEBUG_STATE        0x00000080
   90 #define OTUS_DEBUG_CMDNOTIFY    0x00000100
   91 #define OTUS_DEBUG_REGIO        0x00000200
   92 #define OTUS_DEBUG_IRQ          0x00000400
   93 #define OTUS_DEBUG_TXCOMP       0x00000800
   94 #define OTUS_DEBUG_RX_BUFFER    0x00001000
   95 #define OTUS_DEBUG_ANY          0xffffffff
   96 
   97 #define OTUS_DPRINTF(sc, dm, ...) \
   98         do { \
   99                 if ((dm == OTUS_DEBUG_ANY) || (dm & otus_debug)) \
  100                         device_printf(sc->sc_dev, __VA_ARGS__); \
  101         } while (0)
  102 #define OTUS_DEV(v, p) { USB_VPI(v, p, 0) }
  103 static const STRUCT_USB_HOST_ID otus_devs[] = {
  104         OTUS_DEV(USB_VENDOR_ACCTON,             USB_PRODUCT_ACCTON_WN7512),
  105         OTUS_DEV(USB_VENDOR_ATHEROS2,           USB_PRODUCT_ATHEROS2_3CRUSBN275),
  106         OTUS_DEV(USB_VENDOR_ATHEROS2,           USB_PRODUCT_ATHEROS2_TG121N),
  107         OTUS_DEV(USB_VENDOR_ATHEROS2,           USB_PRODUCT_ATHEROS2_AR9170),
  108         OTUS_DEV(USB_VENDOR_ATHEROS2,           USB_PRODUCT_ATHEROS2_WN612),
  109         OTUS_DEV(USB_VENDOR_ATHEROS2,           USB_PRODUCT_ATHEROS2_WN821NV2),
  110         OTUS_DEV(USB_VENDOR_AVM,                USB_PRODUCT_AVM_FRITZWLAN),
  111         OTUS_DEV(USB_VENDOR_CACE,               USB_PRODUCT_CACE_AIRPCAPNX),
  112         OTUS_DEV(USB_VENDOR_DLINK2,             USB_PRODUCT_DLINK2_DWA130D1),
  113         OTUS_DEV(USB_VENDOR_DLINK2,             USB_PRODUCT_DLINK2_DWA160A1),
  114         OTUS_DEV(USB_VENDOR_DLINK2,             USB_PRODUCT_DLINK2_DWA160A2),
  115         OTUS_DEV(USB_VENDOR_IODATA,             USB_PRODUCT_IODATA_WNGDNUS2),
  116         OTUS_DEV(USB_VENDOR_NEC,                USB_PRODUCT_NEC_WL300NUG),
  117         OTUS_DEV(USB_VENDOR_NETGEAR,            USB_PRODUCT_NETGEAR_WN111V2),
  118         OTUS_DEV(USB_VENDOR_NETGEAR,            USB_PRODUCT_NETGEAR_WNA1000),
  119         OTUS_DEV(USB_VENDOR_NETGEAR,            USB_PRODUCT_NETGEAR_WNDA3100),
  120         OTUS_DEV(USB_VENDOR_PLANEX2,            USB_PRODUCT_PLANEX2_GW_US300),
  121         OTUS_DEV(USB_VENDOR_WISTRONNEWEB,       USB_PRODUCT_WISTRONNEWEB_O8494),
  122         OTUS_DEV(USB_VENDOR_WISTRONNEWEB,       USB_PRODUCT_WISTRONNEWEB_WNC0600),
  123         OTUS_DEV(USB_VENDOR_ZCOM,               USB_PRODUCT_ZCOM_UB81),
  124         OTUS_DEV(USB_VENDOR_ZCOM,               USB_PRODUCT_ZCOM_UB82),
  125         OTUS_DEV(USB_VENDOR_ZYDAS,              USB_PRODUCT_ZYDAS_ZD1221),
  126         OTUS_DEV(USB_VENDOR_ZYXEL,              USB_PRODUCT_ZYXEL_NWD271N),
  127 };
  128 
  129 static device_probe_t otus_match;
  130 static device_attach_t otus_attach;
  131 static device_detach_t otus_detach;
  132 
  133 static int      otus_attachhook(struct otus_softc *);
  134 static void     otus_getradiocaps(struct ieee80211com *, int, int *,
  135                     struct ieee80211_channel[]);
  136 int             otus_load_firmware(struct otus_softc *, const char *,
  137                     uint32_t);
  138 int             otus_open_pipes(struct otus_softc *);
  139 void            otus_close_pipes(struct otus_softc *);
  140 
  141 static int      otus_alloc_tx_cmd_list(struct otus_softc *);
  142 static void     otus_free_tx_cmd_list(struct otus_softc *);
  143 
  144 static int      otus_alloc_rx_list(struct otus_softc *);
  145 static void     otus_free_rx_list(struct otus_softc *);
  146 static int      otus_alloc_tx_list(struct otus_softc *);
  147 static void     otus_free_tx_list(struct otus_softc *);
  148 static void     otus_free_list(struct otus_softc *, struct otus_data [], int);
  149 static struct otus_data *_otus_getbuf(struct otus_softc *);
  150 static struct otus_data *otus_getbuf(struct otus_softc *);
  151 static void     otus_freebuf(struct otus_softc *, struct otus_data *);
  152 
  153 static struct otus_tx_cmd *_otus_get_txcmd(struct otus_softc *);
  154 static struct otus_tx_cmd *otus_get_txcmd(struct otus_softc *);
  155 static void     otus_free_txcmd(struct otus_softc *, struct otus_tx_cmd *);
  156 
  157 void            otus_next_scan(void *, int);
  158 static void     otus_tx_task(void *, int pending);
  159 void            otus_do_async(struct otus_softc *,
  160                     void (*)(struct otus_softc *, void *), void *, int);
  161 int             otus_newstate(struct ieee80211vap *, enum ieee80211_state,
  162                     int);
  163 int             otus_cmd(struct otus_softc *, uint8_t, const void *, int,
  164                     void *, int);
  165 void            otus_write(struct otus_softc *, uint32_t, uint32_t);
  166 int             otus_write_barrier(struct otus_softc *);
  167 static struct   ieee80211_node *otus_node_alloc(struct ieee80211vap *vap,
  168                     const uint8_t mac[IEEE80211_ADDR_LEN]);
  169 int             otus_read_eeprom(struct otus_softc *);
  170 void            otus_newassoc(struct ieee80211_node *, int);
  171 void            otus_cmd_rxeof(struct otus_softc *, uint8_t *, int);
  172 void            otus_sub_rxeof(struct otus_softc *, uint8_t *, int,
  173                     struct mbufq *);
  174 static int      otus_tx(struct otus_softc *, struct ieee80211_node *,
  175                     struct mbuf *, struct otus_data *,
  176                     const struct ieee80211_bpf_params *);
  177 int             otus_ioctl(if_t, u_long, caddr_t);
  178 int             otus_set_multi(struct otus_softc *);
  179 static int      otus_updateedca(struct ieee80211com *);
  180 static void     otus_updateedca_locked(struct otus_softc *);
  181 static void     otus_updateslot(struct otus_softc *);
  182 static void     otus_set_operating_mode(struct otus_softc *sc);
  183 static void     otus_set_rx_filter(struct otus_softc *sc);
  184 int             otus_init_mac(struct otus_softc *);
  185 uint32_t        otus_phy_get_def(struct otus_softc *, uint32_t);
  186 int             otus_set_board_values(struct otus_softc *,
  187                     struct ieee80211_channel *);
  188 int             otus_program_phy(struct otus_softc *,
  189                     struct ieee80211_channel *);
  190 int             otus_set_rf_bank4(struct otus_softc *,
  191                     struct ieee80211_channel *);
  192 void            otus_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
  193 static int      otus_set_chan(struct otus_softc *, struct ieee80211_channel *,
  194                     int);
  195 int             otus_set_key(struct ieee80211com *, struct ieee80211_node *,
  196                     struct ieee80211_key *);
  197 void            otus_set_key_cb(struct otus_softc *, void *);
  198 void            otus_delete_key(struct ieee80211com *, struct ieee80211_node *,
  199                     struct ieee80211_key *);
  200 void            otus_delete_key_cb(struct otus_softc *, void *);
  201 void            otus_calibrate_to(void *, int);
  202 int             otus_set_bssid(struct otus_softc *, const uint8_t *);
  203 int             otus_set_macaddr(struct otus_softc *, const uint8_t *);
  204 void            otus_led_newstate_type1(struct otus_softc *);
  205 void            otus_led_newstate_type2(struct otus_softc *);
  206 void            otus_led_newstate_type3(struct otus_softc *);
  207 int             otus_init(struct otus_softc *sc);
  208 void            otus_stop(struct otus_softc *sc);
  209 
  210 static device_method_t otus_methods[] = {
  211         DEVMETHOD(device_probe,         otus_match),
  212         DEVMETHOD(device_attach,        otus_attach),
  213         DEVMETHOD(device_detach,        otus_detach),
  214 
  215         DEVMETHOD_END
  216 };
  217 
  218 static driver_t otus_driver = {
  219         .name = "otus",
  220         .methods = otus_methods,
  221         .size = sizeof(struct otus_softc)
  222 };
  223 
  224 DRIVER_MODULE(otus, uhub, otus_driver, NULL, NULL);
  225 MODULE_DEPEND(otus, wlan, 1, 1, 1);
  226 MODULE_DEPEND(otus, usb, 1, 1, 1);
  227 MODULE_DEPEND(otus, firmware, 1, 1, 1);
  228 MODULE_VERSION(otus, 1);
  229 
  230 static usb_callback_t   otus_bulk_tx_callback;
  231 static usb_callback_t   otus_bulk_rx_callback;
  232 static usb_callback_t   otus_bulk_irq_callback;
  233 static usb_callback_t   otus_bulk_cmd_callback;
  234 
  235 static const struct usb_config otus_config[OTUS_N_XFER] = {
  236         [OTUS_BULK_TX] = {
  237         .type = UE_BULK,
  238         .endpoint = UE_ADDR_ANY,
  239         .direction = UE_DIR_OUT,
  240         .bufsize = 0x200,
  241         .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
  242         .callback = otus_bulk_tx_callback,
  243         .timeout = 5000,        /* ms */
  244         },
  245         [OTUS_BULK_RX] = {
  246         .type = UE_BULK,
  247         .endpoint = UE_ADDR_ANY,
  248         .direction = UE_DIR_IN,
  249         .bufsize = OTUS_RXBUFSZ,
  250         .flags = { .ext_buffer = 1, .pipe_bof = 1,.short_xfer_ok = 1,},
  251         .callback = otus_bulk_rx_callback,
  252         },
  253         [OTUS_BULK_IRQ] = {
  254         .type = UE_INTERRUPT,
  255         .endpoint = UE_ADDR_ANY,
  256         .direction = UE_DIR_IN,
  257         .bufsize = OTUS_MAX_CTRLSZ,
  258         .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  259         .callback = otus_bulk_irq_callback,
  260         },
  261         [OTUS_BULK_CMD] = {
  262         .type = UE_INTERRUPT,
  263         .endpoint = UE_ADDR_ANY,
  264         .direction = UE_DIR_OUT,
  265         .bufsize = OTUS_MAX_CTRLSZ,
  266         .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
  267         .callback = otus_bulk_cmd_callback,
  268         .timeout = 5000,        /* ms */
  269         },
  270 };
  271 
  272 static int
  273 otus_match(device_t self)
  274 {
  275         struct usb_attach_arg *uaa = device_get_ivars(self);
  276 
  277         if (uaa->usb_mode != USB_MODE_HOST ||
  278             uaa->info.bIfaceIndex != 0 ||
  279             uaa->info.bConfigIndex != 0)
  280         return (ENXIO);
  281 
  282         return (usbd_lookup_id_by_uaa(otus_devs, sizeof(otus_devs), uaa));
  283 }
  284 
  285 static int
  286 otus_attach(device_t self)
  287 {
  288         struct usb_attach_arg *uaa = device_get_ivars(self);
  289         struct otus_softc *sc = device_get_softc(self);
  290         int error;
  291         uint8_t iface_index;
  292 
  293         device_set_usb_desc(self);
  294         sc->sc_udev = uaa->device;
  295         sc->sc_dev = self;
  296 
  297         mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
  298             MTX_DEF);
  299 
  300         TIMEOUT_TASK_INIT(taskqueue_thread, &sc->scan_to, 0, otus_next_scan, sc);
  301         TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_to, 0, otus_calibrate_to, sc);
  302         TASK_INIT(&sc->tx_task, 0, otus_tx_task, sc);
  303         mbufq_init(&sc->sc_snd, ifqmaxlen);
  304 
  305         iface_index = 0;
  306         error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
  307             otus_config, OTUS_N_XFER, sc, &sc->sc_mtx);
  308         if (error) {
  309                 device_printf(sc->sc_dev,
  310                     "could not allocate USB transfers, err=%s\n",
  311                     usbd_errstr(error));
  312                 goto fail_usb;
  313         }
  314 
  315         if ((error = otus_open_pipes(sc)) != 0) {
  316                 device_printf(sc->sc_dev, "%s: could not open pipes\n",
  317                     __func__);
  318                 goto fail;
  319         }
  320 
  321         /* XXX check return status; fail out if appropriate */
  322         if (otus_attachhook(sc) != 0)
  323                 goto fail;
  324 
  325         return (0);
  326 
  327 fail:
  328         otus_close_pipes(sc);
  329 fail_usb:
  330         mtx_destroy(&sc->sc_mtx);
  331         return (ENXIO);
  332 }
  333 
  334 static int
  335 otus_detach(device_t self)
  336 {
  337         struct otus_softc *sc = device_get_softc(self);
  338         struct ieee80211com *ic = &sc->sc_ic;
  339 
  340         otus_stop(sc);
  341 
  342         usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER);
  343 
  344         taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to);
  345         taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to);
  346         taskqueue_drain(taskqueue_thread, &sc->tx_task);
  347 
  348         otus_close_pipes(sc);
  349 #if 0
  350         /* Wait for all queued asynchronous commands to complete. */
  351         usb_rem_wait_task(sc->sc_udev, &sc->sc_task);
  352 
  353         usbd_ref_wait(sc->sc_udev);
  354 #endif
  355 
  356         ieee80211_ifdetach(ic);
  357         mtx_destroy(&sc->sc_mtx);
  358         return 0;
  359 }
  360 
  361 static void
  362 otus_delay_ms(struct otus_softc *sc, int ms)
  363 {
  364 
  365         DELAY(1000 * ms);
  366 }
  367 
  368 static struct ieee80211vap *
  369 otus_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
  370     enum ieee80211_opmode opmode, int flags,
  371     const uint8_t bssid[IEEE80211_ADDR_LEN],
  372     const uint8_t mac[IEEE80211_ADDR_LEN])
  373 {
  374         struct otus_vap *uvp;
  375         struct ieee80211vap *vap;
  376 
  377         if (!TAILQ_EMPTY(&ic->ic_vaps))  /* only one at a time */
  378                 return (NULL);
  379 
  380         uvp =  malloc(sizeof(struct otus_vap), M_80211_VAP, M_WAITOK | M_ZERO);
  381         vap = &uvp->vap;
  382 
  383         if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
  384             flags, bssid) != 0) {
  385                 /* out of memory */
  386                 free(uvp, M_80211_VAP);
  387                 return (NULL);
  388         }
  389 
  390         /* override state transition machine */
  391         uvp->newstate = vap->iv_newstate;
  392         vap->iv_newstate = otus_newstate;
  393 
  394         vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_8;
  395         vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
  396 
  397         ieee80211_ratectl_init(vap);
  398 
  399         /* complete setup */
  400         ieee80211_vap_attach(vap, ieee80211_media_change,
  401             ieee80211_media_status, mac);
  402         ic->ic_opmode = opmode;
  403 
  404         return (vap);
  405 }
  406 
  407 static void
  408 otus_vap_delete(struct ieee80211vap *vap)
  409 {
  410         struct otus_vap *uvp = OTUS_VAP(vap);
  411 
  412         ieee80211_ratectl_deinit(vap);
  413         ieee80211_vap_detach(vap);
  414         free(uvp, M_80211_VAP);
  415 }
  416 
  417 static void
  418 otus_parent(struct ieee80211com *ic)
  419 {
  420         struct otus_softc *sc = ic->ic_softc;
  421         int startall = 0;
  422 
  423         if (ic->ic_nrunning > 0) {
  424                 if (!sc->sc_running) {
  425                         otus_init(sc);
  426                         startall = 1;
  427                 } else {
  428                         (void) otus_set_multi(sc);
  429                 }
  430         } else if (sc->sc_running)
  431                 otus_stop(sc);
  432 
  433         if (startall)
  434                 ieee80211_start_all(ic);
  435 }
  436 
  437 static void
  438 otus_drain_mbufq(struct otus_softc *sc)
  439 {
  440         struct mbuf *m;
  441         struct ieee80211_node *ni;
  442 
  443         OTUS_LOCK_ASSERT(sc);
  444         while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
  445                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
  446                 m->m_pkthdr.rcvif = NULL;
  447                 ieee80211_free_node(ni);
  448                 m_freem(m);
  449         }
  450 }
  451 
  452 static void
  453 otus_tx_start(struct otus_softc *sc)
  454 {
  455 
  456         taskqueue_enqueue(taskqueue_thread, &sc->tx_task);
  457 }
  458 
  459 static int
  460 otus_transmit(struct ieee80211com *ic, struct mbuf *m)
  461 {
  462         struct otus_softc *sc = ic->ic_softc;
  463         int error;
  464 
  465         OTUS_LOCK(sc);
  466         if (! sc->sc_running) {
  467                 OTUS_UNLOCK(sc);
  468                 return (ENXIO);
  469         }
  470 
  471         /* XXX TODO: handle fragments */
  472         error = mbufq_enqueue(&sc->sc_snd, m);
  473         if (error) {
  474                 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
  475                     "%s: mbufq_enqueue failed: %d\n",
  476                     __func__,
  477                     error);
  478                 OTUS_UNLOCK(sc);
  479                 return (error);
  480         }
  481         OTUS_UNLOCK(sc);
  482 
  483         /* Kick TX */
  484         otus_tx_start(sc);
  485 
  486         return (0);
  487 }
  488 
  489 static void
  490 _otus_start(struct otus_softc *sc)
  491 {
  492         struct ieee80211_node *ni;
  493         struct otus_data *bf;
  494         struct mbuf *m;
  495 
  496         OTUS_LOCK_ASSERT(sc);
  497 
  498         while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
  499                 bf = otus_getbuf(sc);
  500                 if (bf == NULL) {
  501                         OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
  502                             "%s: failed to get buffer\n", __func__);
  503                         mbufq_prepend(&sc->sc_snd, m);
  504                         break;
  505                 }
  506 
  507                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
  508                 m->m_pkthdr.rcvif = NULL;
  509 
  510                 if (otus_tx(sc, ni, m, bf, NULL) != 0) {
  511                         OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
  512                             "%s: failed to transmit\n", __func__);
  513                         if_inc_counter(ni->ni_vap->iv_ifp,
  514                             IFCOUNTER_OERRORS, 1);
  515                         otus_freebuf(sc, bf);
  516                         ieee80211_free_node(ni);
  517                         m_freem(m);
  518                         break;
  519                 }
  520         }
  521 }
  522 
  523 static void
  524 otus_tx_task(void *arg, int pending)
  525 {
  526         struct otus_softc *sc = arg;
  527 
  528         OTUS_LOCK(sc);
  529         _otus_start(sc);
  530         OTUS_UNLOCK(sc);
  531 }
  532 
  533 static int
  534 otus_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
  535     const struct ieee80211_bpf_params *params)
  536 {
  537         struct ieee80211com *ic= ni->ni_ic;
  538         struct otus_softc *sc = ic->ic_softc;
  539         struct otus_data *bf = NULL;
  540         int error = 0;
  541 
  542         /* Don't transmit if we're not running */
  543         OTUS_LOCK(sc);
  544         if (! sc->sc_running) {
  545                 error = ENETDOWN;
  546                 goto error;
  547         }
  548 
  549         bf = otus_getbuf(sc);
  550         if (bf == NULL) {
  551                 error = ENOBUFS;
  552                 goto error;
  553         }
  554 
  555         if (otus_tx(sc, ni, m, bf, params) != 0) {
  556                 error = EIO;
  557                 goto error;
  558         }
  559 
  560         OTUS_UNLOCK(sc);
  561         return (0);
  562 error:
  563         if (bf)
  564                 otus_freebuf(sc, bf);
  565         OTUS_UNLOCK(sc);
  566         m_freem(m);
  567         return (error);
  568 }
  569 
  570 static void
  571 otus_update_chw(struct ieee80211com *ic)
  572 {
  573 
  574         printf("%s: TODO\n", __func__);
  575 }
  576 
  577 static void
  578 otus_set_channel(struct ieee80211com *ic)
  579 {
  580         struct otus_softc *sc = ic->ic_softc;
  581         OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "%s: set channel: %d\n",
  582             __func__,
  583             ic->ic_curchan->ic_freq);
  584 
  585         OTUS_LOCK(sc);
  586         (void) otus_set_chan(sc, ic->ic_curchan, 0);
  587         OTUS_UNLOCK(sc);
  588 }
  589 
  590 static int
  591 otus_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
  592 {
  593 
  594         /* For now, no A-MPDU TX support in the driver */
  595         return (0);
  596 }
  597 
  598 static void
  599 otus_scan_start(struct ieee80211com *ic)
  600 {
  601 
  602 //      printf("%s: TODO\n", __func__);
  603 }
  604 
  605 static void
  606 otus_scan_end(struct ieee80211com *ic)
  607 {
  608 
  609 //      printf("%s: TODO\n", __func__);
  610 }
  611 
  612 static void
  613 otus_update_mcast(struct ieee80211com *ic)
  614 {
  615         struct otus_softc *sc = ic->ic_softc;
  616 
  617         (void) otus_set_multi(sc);
  618 }
  619 
  620 static int
  621 otus_attachhook(struct otus_softc *sc)
  622 {
  623         struct ieee80211com *ic = &sc->sc_ic;
  624         usb_device_request_t req;
  625         uint32_t in, out;
  626         int error;
  627 
  628         /* Not locked */
  629         error = otus_load_firmware(sc, "otusfw_init", AR_FW_INIT_ADDR);
  630         if (error != 0) {
  631                 device_printf(sc->sc_dev, "%s: could not load %s firmware\n",
  632                     __func__, "init");
  633                 return (ENXIO);
  634         }
  635 
  636         /* XXX not locked? */
  637         otus_delay_ms(sc, 1000);
  638 
  639         /* Not locked */
  640         error = otus_load_firmware(sc, "otusfw_main", AR_FW_MAIN_ADDR);
  641         if (error != 0) {
  642                 device_printf(sc->sc_dev, "%s: could not load %s firmware\n",
  643                     __func__, "main");
  644                 return (ENXIO);
  645         }
  646 
  647         OTUS_LOCK(sc);
  648 
  649         /* Tell device that firmware transfer is complete. */
  650         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  651         req.bRequest = AR_FW_DOWNLOAD_COMPLETE;
  652         USETW(req.wValue, 0);
  653         USETW(req.wIndex, 0);
  654         USETW(req.wLength, 0);
  655         if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, &req, NULL,
  656             0, NULL, 250) != 0) {
  657                 OTUS_UNLOCK(sc);
  658                 device_printf(sc->sc_dev,
  659                     "%s: firmware initialization failed\n",
  660                     __func__);
  661                 return (ENXIO);
  662         }
  663 
  664         /* Send an ECHO command to check that everything is settled. */
  665         in = 0xbadc0ffe;
  666         if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof in, &out, sizeof(out)) != 0) {
  667                 OTUS_UNLOCK(sc);
  668                 device_printf(sc->sc_dev,
  669                     "%s: echo command failed\n", __func__);
  670                 return (ENXIO);
  671         }
  672         if (in != out) {
  673                 OTUS_UNLOCK(sc);
  674                 device_printf(sc->sc_dev,
  675                     "%s: echo reply mismatch: 0x%08x!=0x%08x\n",
  676                     __func__, in, out);
  677                 return (ENXIO);
  678         }
  679 
  680         /* Read entire EEPROM. */
  681         if (otus_read_eeprom(sc) != 0) {
  682                 OTUS_UNLOCK(sc);
  683                 device_printf(sc->sc_dev,
  684                     "%s: could not read EEPROM\n",
  685                     __func__);
  686                 return (ENXIO);
  687         }
  688 
  689         OTUS_UNLOCK(sc);
  690 
  691         sc->txmask = sc->eeprom.baseEepHeader.txMask;
  692         sc->rxmask = sc->eeprom.baseEepHeader.rxMask;
  693         sc->capflags = sc->eeprom.baseEepHeader.opCapFlags;
  694         IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->eeprom.baseEepHeader.macAddr);
  695         sc->sc_led_newstate = otus_led_newstate_type3;  /* XXX */
  696 
  697         if (sc->txmask == 0x5)
  698                 ic->ic_txstream = 2;
  699         else
  700                 ic->ic_txstream = 1;
  701 
  702         if (sc->rxmask == 0x5)
  703                 ic->ic_rxstream = 2;
  704         else
  705                 ic->ic_rxstream = 1;
  706 
  707         device_printf(sc->sc_dev,
  708             "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n",
  709             (sc->capflags & AR5416_OPFLAGS_11A) ?
  710                 0x9104 : ((sc->txmask == 0x5) ? 0x9102 : 0x9101),
  711             (sc->txmask == 0x5) ? 2 : 1, (sc->rxmask == 0x5) ? 2 : 1,
  712             ether_sprintf(ic->ic_macaddr));
  713 
  714         ic->ic_softc = sc;
  715         ic->ic_name = device_get_nameunit(sc->sc_dev);
  716         ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
  717         ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
  718 
  719         /* Set device capabilities. */
  720         ic->ic_caps =
  721             IEEE80211_C_STA |           /* station mode */
  722 #if 0
  723             IEEE80211_C_BGSCAN |        /* Background scan. */
  724 #endif
  725             IEEE80211_C_SHPREAMBLE |    /* Short preamble supported. */
  726             IEEE80211_C_WME |           /* WME/QoS */
  727             IEEE80211_C_SHSLOT |        /* Short slot time supported. */
  728             IEEE80211_C_FF |            /* Atheros fast-frames supported. */
  729             IEEE80211_C_MONITOR |       /* Enable monitor mode */
  730             IEEE80211_C_SWAMSDUTX |     /* Do software A-MSDU TX */
  731             IEEE80211_C_WPA;            /* WPA/RSN. */
  732 
  733         ic->ic_htcaps =
  734             IEEE80211_HTC_HT |
  735 #if 0
  736             IEEE80211_HTC_AMPDU |
  737 #endif
  738             IEEE80211_HTC_AMSDU |
  739             IEEE80211_HTCAP_MAXAMSDU_3839 |
  740             IEEE80211_HTCAP_SMPS_OFF;
  741 
  742         otus_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
  743             ic->ic_channels);
  744 
  745         ieee80211_ifattach(ic);
  746         ic->ic_raw_xmit = otus_raw_xmit;
  747         ic->ic_scan_start = otus_scan_start;
  748         ic->ic_scan_end = otus_scan_end;
  749         ic->ic_set_channel = otus_set_channel;
  750         ic->ic_getradiocaps = otus_getradiocaps;
  751         ic->ic_vap_create = otus_vap_create;
  752         ic->ic_vap_delete = otus_vap_delete;
  753         ic->ic_update_mcast = otus_update_mcast;
  754         ic->ic_update_promisc = otus_update_mcast;
  755         ic->ic_parent = otus_parent;
  756         ic->ic_transmit = otus_transmit;
  757         ic->ic_update_chw = otus_update_chw;
  758         ic->ic_ampdu_enable = otus_ampdu_enable;
  759         ic->ic_wme.wme_update = otus_updateedca;
  760         ic->ic_newassoc = otus_newassoc;
  761         ic->ic_node_alloc = otus_node_alloc;
  762 
  763 #ifdef notyet
  764         ic->ic_set_key = otus_set_key;
  765         ic->ic_delete_key = otus_delete_key;
  766 #endif
  767 
  768         ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
  769             sizeof(sc->sc_txtap), OTUS_TX_RADIOTAP_PRESENT,
  770             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
  771             OTUS_RX_RADIOTAP_PRESENT);
  772 
  773         return (0);
  774 }
  775 
  776 static void
  777 otus_getradiocaps(struct ieee80211com *ic,
  778     int maxchans, int *nchans, struct ieee80211_channel chans[])
  779 {
  780         struct otus_softc *sc = ic->ic_softc;
  781         uint8_t bands[IEEE80211_MODE_BYTES];
  782 
  783         /* Set supported .11b and .11g rates. */
  784         memset(bands, 0, sizeof(bands));
  785         if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
  786                 setbit(bands, IEEE80211_MODE_11B);
  787                 setbit(bands, IEEE80211_MODE_11G);
  788                 setbit(bands, IEEE80211_MODE_11NG);
  789                 ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
  790                     ar_chans, 14, bands, 0);
  791         }
  792         if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
  793                 setbit(bands, IEEE80211_MODE_11A);
  794                 setbit(bands, IEEE80211_MODE_11NA);
  795                 ieee80211_add_channel_list_5ghz(chans, maxchans, nchans,
  796                     &ar_chans[14], nitems(ar_chans) - 14, bands, 0);
  797         }
  798 }
  799 
  800 int
  801 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr)
  802 {
  803         usb_device_request_t req;
  804         char *ptr;
  805         const struct firmware *fw;
  806         int mlen, error, size;
  807 
  808         error = 0;
  809 
  810         /* Read firmware image from the filesystem. */
  811         if ((fw = firmware_get(name)) == NULL) {
  812                 device_printf(sc->sc_dev,
  813                     "%s: failed loadfirmware of file %s\n", __func__, name);
  814                 return (ENXIO);
  815         }
  816         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  817         req.bRequest = AR_FW_DOWNLOAD;
  818         USETW(req.wIndex, 0);
  819 
  820         OTUS_LOCK(sc);
  821 
  822         /* XXX const */
  823         ptr = __DECONST(char *, fw->data);
  824         size = fw->datasize;
  825         addr >>= 8;
  826         while (size > 0) {
  827                 mlen = MIN(size, 4096);
  828 
  829                 USETW(req.wValue, addr);
  830                 USETW(req.wLength, mlen);
  831                 if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
  832                     &req, ptr, 0, NULL, 250) != 0) {
  833                         error = EIO;
  834                         break;
  835                 }
  836                 addr += mlen >> 8;
  837                 ptr  += mlen;
  838                 size -= mlen;
  839         }
  840 
  841         OTUS_UNLOCK(sc);
  842 
  843         firmware_put(fw, FIRMWARE_UNLOAD);
  844         if (error != 0)
  845                 device_printf(sc->sc_dev,
  846                     "%s: %s: error=%d\n", __func__, name, error);
  847         return error;
  848 }
  849 
  850 int
  851 otus_open_pipes(struct otus_softc *sc)
  852 {
  853 #if 0
  854         int isize, error;
  855         int i;
  856 #endif
  857         int error;
  858 
  859         OTUS_UNLOCK_ASSERT(sc);
  860 
  861         if ((error = otus_alloc_tx_cmd_list(sc)) != 0) {
  862                 device_printf(sc->sc_dev,
  863                     "%s: could not allocate command xfer\n",
  864                     __func__);
  865                 goto fail;
  866         }
  867 
  868         if ((error = otus_alloc_tx_list(sc)) != 0) {
  869                 device_printf(sc->sc_dev, "%s: could not allocate Tx xfers\n",
  870                     __func__);
  871                 goto fail;
  872         }
  873 
  874         if ((error = otus_alloc_rx_list(sc)) != 0) {
  875                 device_printf(sc->sc_dev, "%s: could not allocate Rx xfers\n",
  876                     __func__);
  877                 goto fail;
  878         }
  879 
  880         /* Enable RX transfers; needed for initial firmware messages */
  881         OTUS_LOCK(sc);
  882         usbd_transfer_start(sc->sc_xfer[OTUS_BULK_RX]);
  883         usbd_transfer_start(sc->sc_xfer[OTUS_BULK_IRQ]);
  884         OTUS_UNLOCK(sc);
  885         return 0;
  886 
  887 fail:   otus_close_pipes(sc);
  888         return error;
  889 }
  890 
  891 void
  892 otus_close_pipes(struct otus_softc *sc)
  893 {
  894 
  895         OTUS_LOCK(sc);
  896         otus_free_tx_cmd_list(sc);
  897         otus_free_tx_list(sc);
  898         otus_free_rx_list(sc);
  899         OTUS_UNLOCK(sc);
  900 
  901         usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER);
  902 }
  903 
  904 static void
  905 otus_free_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[], int ndata)
  906 {
  907         int i;
  908 
  909         /* XXX TODO: someone has to have waken up waiters! */
  910         for (i = 0; i < ndata; i++) {
  911                 struct otus_tx_cmd *dp = &cmd[i];
  912 
  913                 if (dp->buf != NULL) {
  914                         free(dp->buf, M_USBDEV);
  915                         dp->buf = NULL;
  916                 }
  917         }
  918 }
  919 
  920 static int
  921 otus_alloc_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[],
  922     int ndata, int maxsz)
  923 {
  924         int i, error;
  925 
  926         for (i = 0; i < ndata; i++) {
  927                 struct otus_tx_cmd *dp = &cmd[i];
  928                 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT | M_ZERO);
  929                 dp->odata = NULL;
  930                 if (dp->buf == NULL) {
  931                         device_printf(sc->sc_dev,
  932                             "could not allocate buffer\n");
  933                         error = ENOMEM;
  934                         goto fail;
  935                 }
  936         }
  937 
  938         return (0);
  939 fail:
  940         otus_free_cmd_list(sc, cmd, ndata);
  941         return (error);
  942 }
  943 
  944 static int
  945 otus_alloc_tx_cmd_list(struct otus_softc *sc)
  946 {
  947         int error, i;
  948 
  949         error = otus_alloc_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT,
  950             OTUS_MAX_TXCMDSZ);
  951         if (error != 0)
  952                 return (error);
  953 
  954         STAILQ_INIT(&sc->sc_cmd_active);
  955         STAILQ_INIT(&sc->sc_cmd_inactive);
  956         STAILQ_INIT(&sc->sc_cmd_pending);
  957         STAILQ_INIT(&sc->sc_cmd_waiting);
  958 
  959         for (i = 0; i < OTUS_CMD_LIST_COUNT; i++)
  960                 STAILQ_INSERT_HEAD(&sc->sc_cmd_inactive, &sc->sc_cmd[i],
  961                     next_cmd);
  962 
  963         return (0);
  964 }
  965 
  966 static void
  967 otus_free_tx_cmd_list(struct otus_softc *sc)
  968 {
  969 
  970         /*
  971          * XXX TODO: something needs to wake up any pending/sleeping
  972          * waiters!
  973          */
  974         STAILQ_INIT(&sc->sc_cmd_active);
  975         STAILQ_INIT(&sc->sc_cmd_inactive);
  976         STAILQ_INIT(&sc->sc_cmd_pending);
  977         STAILQ_INIT(&sc->sc_cmd_waiting);
  978 
  979         otus_free_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT);
  980 }
  981 
  982 static int
  983 otus_alloc_list(struct otus_softc *sc, struct otus_data data[],
  984     int ndata, int maxsz)
  985 {
  986         int i, error;
  987 
  988         for (i = 0; i < ndata; i++) {
  989                 struct otus_data *dp = &data[i];
  990                 dp->sc = sc;
  991                 dp->m = NULL;
  992                 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT | M_ZERO);
  993                 if (dp->buf == NULL) {
  994                         device_printf(sc->sc_dev,
  995                             "could not allocate buffer\n");
  996                         error = ENOMEM;
  997                         goto fail;
  998                 }
  999                 dp->ni = NULL;
 1000         }
 1001 
 1002         return (0);
 1003 fail:
 1004         otus_free_list(sc, data, ndata);
 1005         return (error);
 1006 }
 1007 
 1008 static int
 1009 otus_alloc_rx_list(struct otus_softc *sc)
 1010 {
 1011         int error, i;
 1012 
 1013         error = otus_alloc_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT,
 1014             OTUS_RXBUFSZ);
 1015         if (error != 0)
 1016                 return (error);
 1017 
 1018         STAILQ_INIT(&sc->sc_rx_active);
 1019         STAILQ_INIT(&sc->sc_rx_inactive);
 1020 
 1021         for (i = 0; i < OTUS_RX_LIST_COUNT; i++)
 1022                 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
 1023 
 1024         return (0);
 1025 }
 1026 
 1027 static int
 1028 otus_alloc_tx_list(struct otus_softc *sc)
 1029 {
 1030         int error, i;
 1031 
 1032         error = otus_alloc_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT,
 1033             OTUS_TXBUFSZ);
 1034         if (error != 0)
 1035                 return (error);
 1036 
 1037         STAILQ_INIT(&sc->sc_tx_inactive);
 1038 
 1039         for (i = 0; i != OTUS_N_XFER; i++) {
 1040                 STAILQ_INIT(&sc->sc_tx_active[i]);
 1041                 STAILQ_INIT(&sc->sc_tx_pending[i]);
 1042         }
 1043 
 1044         for (i = 0; i < OTUS_TX_LIST_COUNT; i++) {
 1045                 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
 1046         }
 1047 
 1048         return (0);
 1049 }
 1050 
 1051 static void
 1052 otus_free_tx_list(struct otus_softc *sc)
 1053 {
 1054         int i;
 1055 
 1056         /* prevent further allocations from TX list(s) */
 1057         STAILQ_INIT(&sc->sc_tx_inactive);
 1058 
 1059         for (i = 0; i != OTUS_N_XFER; i++) {
 1060                 STAILQ_INIT(&sc->sc_tx_active[i]);
 1061                 STAILQ_INIT(&sc->sc_tx_pending[i]);
 1062         }
 1063 
 1064         otus_free_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT);
 1065 }
 1066 
 1067 static void
 1068 otus_free_rx_list(struct otus_softc *sc)
 1069 {
 1070         /* prevent further allocations from RX list(s) */
 1071         STAILQ_INIT(&sc->sc_rx_inactive);
 1072         STAILQ_INIT(&sc->sc_rx_active);
 1073 
 1074         otus_free_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT);
 1075 }
 1076 
 1077 static void
 1078 otus_free_list(struct otus_softc *sc, struct otus_data data[], int ndata)
 1079 {
 1080         int i;
 1081 
 1082         for (i = 0; i < ndata; i++) {
 1083                 struct otus_data *dp = &data[i];
 1084 
 1085                 if (dp->buf != NULL) {
 1086                         free(dp->buf, M_USBDEV);
 1087                         dp->buf = NULL;
 1088                 }
 1089                 if (dp->ni != NULL) {
 1090                         ieee80211_free_node(dp->ni);
 1091                         dp->ni = NULL;
 1092                 }
 1093         }
 1094 }
 1095 
 1096 static struct otus_data *
 1097 _otus_getbuf(struct otus_softc *sc)
 1098 {
 1099         struct otus_data *bf;
 1100 
 1101         bf = STAILQ_FIRST(&sc->sc_tx_inactive);
 1102         if (bf != NULL)
 1103                 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
 1104         else
 1105                 bf = NULL;
 1106         /* XXX bzero? */
 1107         return (bf);
 1108 }
 1109 
 1110 static struct otus_data *
 1111 otus_getbuf(struct otus_softc *sc)
 1112 {
 1113         struct otus_data *bf;
 1114 
 1115         OTUS_LOCK_ASSERT(sc);
 1116 
 1117         bf = _otus_getbuf(sc);
 1118         return (bf);
 1119 }
 1120 
 1121 static void
 1122 otus_freebuf(struct otus_softc *sc, struct otus_data *bf)
 1123 {
 1124 
 1125         OTUS_LOCK_ASSERT(sc);
 1126         STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, bf, next);
 1127 }
 1128 
 1129 static struct otus_tx_cmd *
 1130 _otus_get_txcmd(struct otus_softc *sc)
 1131 {
 1132         struct otus_tx_cmd *bf;
 1133 
 1134         bf = STAILQ_FIRST(&sc->sc_cmd_inactive);
 1135         if (bf != NULL)
 1136                 STAILQ_REMOVE_HEAD(&sc->sc_cmd_inactive, next_cmd);
 1137         else
 1138                 bf = NULL;
 1139         return (bf);
 1140 }
 1141 
 1142 static struct otus_tx_cmd *
 1143 otus_get_txcmd(struct otus_softc *sc)
 1144 {
 1145         struct otus_tx_cmd *bf;
 1146 
 1147         OTUS_LOCK_ASSERT(sc);
 1148 
 1149         bf = _otus_get_txcmd(sc);
 1150         if (bf == NULL) {
 1151                 device_printf(sc->sc_dev, "%s: no tx cmd buffers\n",
 1152                     __func__);
 1153         }
 1154         return (bf);
 1155 }
 1156 
 1157 static void
 1158 otus_free_txcmd(struct otus_softc *sc, struct otus_tx_cmd *bf)
 1159 {
 1160 
 1161         OTUS_LOCK_ASSERT(sc);
 1162         STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, bf, next_cmd);
 1163 }
 1164 
 1165 void
 1166 otus_next_scan(void *arg, int pending)
 1167 {
 1168 #if 0
 1169         struct otus_softc *sc = arg;
 1170 
 1171         if (usbd_is_dying(sc->sc_udev))
 1172                 return;
 1173 
 1174         usbd_ref_incr(sc->sc_udev);
 1175 
 1176         if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
 1177                 ieee80211_next_scan(&sc->sc_ic.ic_if);
 1178 
 1179         usbd_ref_decr(sc->sc_udev);
 1180 #endif
 1181 }
 1182 
 1183 int
 1184 otus_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 1185 {
 1186         struct otus_vap *uvp = OTUS_VAP(vap);
 1187         struct ieee80211com *ic = vap->iv_ic;
 1188         struct otus_softc *sc = ic->ic_softc;
 1189         enum ieee80211_state ostate;
 1190 
 1191         ostate = vap->iv_state;
 1192         OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "%s: %s -> %s\n", __func__,
 1193             ieee80211_state_name[ostate],
 1194             ieee80211_state_name[nstate]);
 1195 
 1196         IEEE80211_UNLOCK(ic);
 1197 
 1198         OTUS_LOCK(sc);
 1199 
 1200         /* XXX TODO: more fleshing out! */
 1201 
 1202         switch (nstate) {
 1203         case IEEE80211_S_INIT:
 1204                 otus_set_operating_mode(sc);
 1205                 otus_set_rx_filter(sc);
 1206                 break;
 1207         case IEEE80211_S_RUN:
 1208                 if (ic->ic_opmode == IEEE80211_M_STA) {
 1209                         otus_updateslot(sc);
 1210                         otus_set_operating_mode(sc);
 1211                         otus_set_rx_filter(sc);
 1212 
 1213                         /* Start calibration timer. */
 1214                         taskqueue_enqueue_timeout(taskqueue_thread,
 1215                             &sc->calib_to, hz);
 1216                 }
 1217                 break;
 1218         default:
 1219                 break;
 1220         }
 1221 
 1222         /* XXX TODO: calibration? */
 1223 
 1224         sc->sc_led_newstate(sc);
 1225 
 1226         OTUS_UNLOCK(sc);
 1227         IEEE80211_LOCK(ic);
 1228         return (uvp->newstate(vap, nstate, arg));
 1229 }
 1230 
 1231 int
 1232 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen,
 1233     void *odata, int odatalen)
 1234 {
 1235         struct otus_tx_cmd *cmd;
 1236         struct ar_cmd_hdr *hdr;
 1237         int xferlen, error;
 1238 
 1239         OTUS_LOCK_ASSERT(sc);
 1240 
 1241         /* Always bulk-out a multiple of 4 bytes. */
 1242         xferlen = (sizeof (*hdr) + ilen + 3) & ~3;
 1243         if (xferlen > OTUS_MAX_TXCMDSZ) {
 1244                 device_printf(sc->sc_dev, "%s: command (0x%02x) size (%d) > %d\n",
 1245                     __func__,
 1246                     code,
 1247                     xferlen,
 1248                     OTUS_MAX_TXCMDSZ);
 1249                 return (EIO);
 1250         }
 1251 
 1252         cmd = otus_get_txcmd(sc);
 1253         if (cmd == NULL) {
 1254                 device_printf(sc->sc_dev, "%s: failed to get buf\n",
 1255                     __func__);
 1256                 return (EIO);
 1257         }
 1258 
 1259         hdr = (struct ar_cmd_hdr *)cmd->buf;
 1260         hdr->code  = code;
 1261         hdr->len   = ilen;
 1262         hdr->token = ++sc->token;       /* Don't care about endianness. */
 1263         cmd->token = hdr->token;
 1264         /* XXX TODO: check max cmd length? */
 1265         memcpy((uint8_t *)&hdr[1], idata, ilen);
 1266 
 1267         OTUS_DPRINTF(sc, OTUS_DEBUG_CMD,
 1268             "%s: sending command code=0x%02x len=%d token=%d\n",
 1269             __func__, code, ilen, hdr->token);
 1270 
 1271         cmd->odata = odata;
 1272         cmd->odatalen = odatalen;
 1273         cmd->buflen = xferlen;
 1274 
 1275         /* Queue the command to the endpoint */
 1276         STAILQ_INSERT_TAIL(&sc->sc_cmd_pending, cmd, next_cmd);
 1277         usbd_transfer_start(sc->sc_xfer[OTUS_BULK_CMD]);
 1278 
 1279         /* Sleep on the command; wait for it to complete */
 1280         error = msleep(cmd, &sc->sc_mtx, PCATCH, "otuscmd", hz);
 1281 
 1282         /*
 1283          * At this point we don't own cmd any longer; it'll be
 1284          * freed by the cmd bulk path or the RX notification
 1285          * path.  If the data is made available then it'll be copied
 1286          * to the caller.  All that is left to do is communicate
 1287          * status back to the caller.
 1288          */
 1289         if (error != 0) {
 1290                 device_printf(sc->sc_dev,
 1291                     "%s: timeout waiting for command 0x%02x reply\n",
 1292                     __func__, code);
 1293         }
 1294         return error;
 1295 }
 1296 
 1297 void
 1298 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val)
 1299 {
 1300 
 1301         OTUS_LOCK_ASSERT(sc);
 1302 
 1303         sc->write_buf[sc->write_idx].reg = htole32(reg);
 1304         sc->write_buf[sc->write_idx].val = htole32(val);
 1305 
 1306         if (++sc->write_idx > (AR_MAX_WRITE_IDX-1))
 1307                 (void)otus_write_barrier(sc);
 1308 }
 1309 
 1310 int
 1311 otus_write_barrier(struct otus_softc *sc)
 1312 {
 1313         int error;
 1314 
 1315         OTUS_LOCK_ASSERT(sc);
 1316 
 1317         if (sc->write_idx == 0)
 1318                 return 0;       /* Nothing to flush. */
 1319 
 1320         OTUS_DPRINTF(sc, OTUS_DEBUG_REGIO, "%s: called; %d updates\n",
 1321             __func__,
 1322             sc->write_idx);
 1323 
 1324         error = otus_cmd(sc, AR_CMD_WREG, sc->write_buf,
 1325             sizeof (sc->write_buf[0]) * sc->write_idx, NULL, 0);
 1326         sc->write_idx = 0;
 1327         return error;
 1328 }
 1329 
 1330 static struct ieee80211_node *
 1331 otus_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
 1332 {
 1333 
 1334         return malloc(sizeof (struct otus_node), M_80211_NODE,
 1335             M_NOWAIT | M_ZERO);
 1336 }
 1337 
 1338 int
 1339 otus_read_eeprom(struct otus_softc *sc)
 1340 {
 1341         uint32_t regs[8], reg;
 1342         uint8_t *eep;
 1343         int i, j, error;
 1344 
 1345         OTUS_LOCK_ASSERT(sc);
 1346 
 1347         /* Read EEPROM by blocks of 32 bytes. */
 1348         eep = (uint8_t *)&sc->eeprom;
 1349         reg = AR_EEPROM_OFFSET;
 1350         for (i = 0; i < sizeof (sc->eeprom) / 32; i++) {
 1351                 for (j = 0; j < 8; j++, reg += 4)
 1352                         regs[j] = htole32(reg);
 1353                 error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof regs, eep, 32);
 1354                 if (error != 0)
 1355                         break;
 1356                 eep += 32;
 1357         }
 1358         return error;
 1359 }
 1360 
 1361 void
 1362 otus_newassoc(struct ieee80211_node *ni, int isnew)
 1363 {
 1364         struct ieee80211com *ic = ni->ni_ic;
 1365         struct otus_softc *sc = ic->ic_softc;
 1366         struct otus_node *on = OTUS_NODE(ni);
 1367 
 1368         OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "new assoc isnew=%d addr=%s\n",
 1369             isnew, ether_sprintf(ni->ni_macaddr));
 1370 
 1371         on->tx_done = 0;
 1372         on->tx_err = 0;
 1373         on->tx_retries = 0;
 1374 }
 1375 
 1376 static void
 1377 otus_cmd_handle_response(struct otus_softc *sc, struct ar_cmd_hdr *hdr)
 1378 {
 1379         struct otus_tx_cmd *cmd;
 1380 
 1381         OTUS_LOCK_ASSERT(sc);
 1382 
 1383         OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 1384             "%s: received reply code=0x%02x len=%d token=%d\n",
 1385             __func__,
 1386             hdr->code, hdr->len, hdr->token);
 1387 
 1388         /*
 1389          * Walk the list, freeing items that aren't ours,
 1390          * stopping when we hit our token.
 1391          */
 1392         while ((cmd = STAILQ_FIRST(&sc->sc_cmd_waiting)) != NULL) {
 1393                 STAILQ_REMOVE_HEAD(&sc->sc_cmd_waiting, next_cmd);
 1394                 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 1395                     "%s: cmd=%p; hdr.token=%d, cmd.token=%d\n",
 1396                     __func__,
 1397                     cmd,
 1398                     (int) hdr->token,
 1399                     (int) cmd->token);
 1400                 if (hdr->token == cmd->token) {
 1401                         /* Copy answer into caller's supplied buffer. */
 1402                         if (cmd->odata != NULL) {
 1403                                 if (hdr->len != cmd->odatalen) {
 1404                                         device_printf(sc->sc_dev,
 1405                                             "%s: code 0x%02x, len=%d, olen=%d\n",
 1406                                             __func__,
 1407                                             (int) hdr->code,
 1408                                             (int) hdr->len,
 1409                                             (int) cmd->odatalen);
 1410                                 }
 1411                                 memcpy(cmd->odata, &hdr[1],
 1412                                     MIN(cmd->odatalen, hdr->len));
 1413                         }
 1414                         wakeup(cmd);
 1415                 }
 1416 
 1417                 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next_cmd);
 1418         }
 1419 }
 1420 
 1421 void
 1422 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
 1423 {
 1424         struct ieee80211com *ic = &sc->sc_ic;
 1425         struct ar_cmd_hdr *hdr;
 1426 
 1427         OTUS_LOCK_ASSERT(sc);
 1428 
 1429         if (__predict_false(len < sizeof (*hdr))) {
 1430                 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 1431                     "cmd too small %d\n", len);
 1432                 return;
 1433         }
 1434         hdr = (struct ar_cmd_hdr *)buf;
 1435         if (__predict_false(sizeof (*hdr) + hdr->len > len ||
 1436             sizeof (*hdr) + hdr->len > 64)) {
 1437                 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 1438                     "cmd too large %d\n", hdr->len);
 1439                 return;
 1440         }
 1441 
 1442         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1443             "%s: code=%.02x\n",
 1444             __func__,
 1445             hdr->code);
 1446 
 1447         /*
 1448          * This has to reach into the cmd queue "waiting for
 1449          * an RX response" list, grab the head entry and check
 1450          * if we need to wake anyone up.
 1451          */
 1452         if ((hdr->code & 0xc0) != 0xc0) {
 1453                 otus_cmd_handle_response(sc, hdr);
 1454                 return;
 1455         }
 1456 
 1457         /* Received unsolicited notification. */
 1458         switch (hdr->code & 0x3f) {
 1459         case AR_EVT_BEACON:
 1460                 break;
 1461         case AR_EVT_TX_COMP:
 1462         {
 1463                 struct ar_evt_tx_comp *tx = (struct ar_evt_tx_comp *)&hdr[1];
 1464                 struct ieee80211_node *ni;
 1465 
 1466                 ni = ieee80211_find_node(&ic->ic_sta, tx->macaddr);
 1467                 if (ni == NULL) {
 1468                         device_printf(sc->sc_dev,
 1469                             "%s: txcomp on unknown node (%s)\n",
 1470                             __func__,
 1471                             ether_sprintf(tx->macaddr));
 1472                         break;
 1473                 }
 1474 
 1475                 OTUS_DPRINTF(sc, OTUS_DEBUG_TXCOMP,
 1476                     "tx completed %s status=%d phy=0x%x\n",
 1477                     ether_sprintf(tx->macaddr), le16toh(tx->status),
 1478                     le32toh(tx->phy));
 1479 
 1480                 switch (le16toh(tx->status)) {
 1481                 case AR_TX_STATUS_COMP:
 1482 #if 0
 1483                         ackfailcnt = 0;
 1484                         ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
 1485                             IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
 1486 #endif
 1487                         /*
 1488                          * We don't get the above; only error notifications.
 1489                          * Sigh.  So, don't worry about this.
 1490                          */
 1491                         break;
 1492                 case AR_TX_STATUS_RETRY_COMP:
 1493                         OTUS_NODE(ni)->tx_retries++;
 1494                         break;
 1495                 case AR_TX_STATUS_FAILED:
 1496                         OTUS_NODE(ni)->tx_err++;
 1497                         break;
 1498                 }
 1499                 ieee80211_free_node(ni);
 1500                 break;
 1501         }
 1502         case AR_EVT_TBTT:
 1503                 break;
 1504         case AR_EVT_DO_BB_RESET:
 1505                 /*
 1506                  * This is "tell driver to reset baseband" from ar9170-fw.
 1507                  *
 1508                  * I'm not sure what we should do here, so I'm going to
 1509                  * fall through; it gets generated when RTSRetryCnt internally
 1510                  * reaches '5' - I guess the firmware authors thought that
 1511                  * meant that the BB may have gone deaf or something.
 1512                  */
 1513         default:
 1514                 device_printf(sc->sc_dev,
 1515                     "%s: received notification code=0x%02x len=%d\n",
 1516                     __func__,
 1517                     hdr->code, hdr->len);
 1518         }
 1519 }
 1520 
 1521 /*
 1522  * Handle a single MPDU.
 1523  *
 1524  * This may be a single MPDU, or it may be a sub-frame from an A-MPDU.
 1525  * In the latter case some of the header details need to be adjusted.
 1526  */
 1527 void
 1528 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
 1529 {
 1530         struct ieee80211com *ic = &sc->sc_ic;
 1531         struct ieee80211_rx_stats rxs;
 1532 #if 0
 1533         struct ieee80211_node *ni;
 1534 #endif
 1535         struct ar_rx_macstatus *mac_status = NULL;
 1536         struct ar_rx_phystatus *phy_status = NULL;
 1537         struct ieee80211_frame *wh;
 1538         struct mbuf *m;
 1539 //      int s;
 1540 
 1541         if (otus_debug & OTUS_DEBUG_RX_BUFFER) {
 1542                 device_printf(sc->sc_dev, "%s: %*D\n",
 1543                     __func__, len, buf, "-");
 1544         }
 1545 
 1546         /*
 1547          * Before any data path stuff - check to see if this is a command
 1548          * response.
 1549          *
 1550          * All bits in the PLCP header are set to 1 for non-MPDU.
 1551          */
 1552         if ((len >= AR_PLCP_HDR_LEN) &&
 1553             memcmp(buf, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
 1554                 otus_cmd_rxeof(sc, buf + AR_PLCP_HDR_LEN,
 1555                     len - AR_PLCP_HDR_LEN);
 1556                 return;
 1557         }
 1558 
 1559         /*
 1560          * First step - get the status for the given frame.
 1561          * This will tell us whether it's a single MPDU or
 1562          * an A-MPDU subframe.
 1563          */
 1564         if (len < sizeof(*mac_status)) {
 1565                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1566                     "%s: sub-xfer too short (no mac_status) (len %d)\n",
 1567                     __func__, len);
 1568                 counter_u64_add(ic->ic_ierrors, 1);
 1569                 return;
 1570         }
 1571         /*
 1572          * Remove the mac_status from the payload length.
 1573          *
 1574          * Note: cheating, don't reallocate the buffer!
 1575          */
 1576         mac_status = (struct ar_rx_macstatus *)(buf + len - sizeof(*mac_status));
 1577         len -= sizeof(*mac_status);
 1578 
 1579         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: mac status=0x%x\n",
 1580             __func__, mac_status->status);
 1581 
 1582         /*
 1583          * Next - check the MAC status before doing anything else.
 1584          * Extract out the PLCP header for single and first frames;
 1585          * since there's a single RX path we can shove PLCP headers
 1586          * from both into sc->ar_last_rx_plcp[] so it can be reused.
 1587          */
 1588         if (((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_SINGLE) ||
 1589             ((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_FIRST)) {
 1590                 /*
 1591                  * Ok, we need to at least have a PLCP header at
 1592                  * this point.
 1593                  */
 1594                 if (len < AR_PLCP_HDR_LEN) {
 1595                         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1596                             "%s sub-xfer too short (no mac+plcp) (len %d\n)",
 1597                             __func__, len);
 1598                         counter_u64_add(ic->ic_ierrors, 1);
 1599                         return;
 1600                 }
 1601                 memcpy(sc->ar_last_rx_plcp, buf, AR_PLCP_HDR_LEN);
 1602 
 1603                 /*
 1604                  * At this point we can just consume the PLCP header.
 1605                  * The beginning of the frame should thus be data.
 1606                  */
 1607                 buf += AR_PLCP_HDR_LEN;
 1608                 len -= AR_PLCP_HDR_LEN;
 1609         }
 1610 
 1611         /*
 1612          * Next - see if we have a PHY status.
 1613          *
 1614          * The PHY status is at the end of the final A-MPDU subframe
 1615          * or a single MPDU frame.
 1616          *
 1617          * We'll use this to tag frames with noise floor / RSSI
 1618          * if they have valid information.
 1619          */
 1620         if (((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_SINGLE) ||
 1621             ((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_LAST)) {
 1622                 if (len < sizeof(*phy_status)) {
 1623                         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1624                             "%s sub-xfer too short (no phy status) (len %d\n)",
 1625                             __func__, len);
 1626                         counter_u64_add(ic->ic_ierrors, 1);
 1627                         return;
 1628                 }
 1629                 /*
 1630                  * Take a pointer to the phy status and remove the length
 1631                  * from the end of the buffer.
 1632                  *
 1633                  * Note: we're cheating here; don't reallocate the buffer!
 1634                  */
 1635                 phy_status = (struct ar_rx_phystatus *)
 1636                     (buf + len - sizeof(*phy_status));
 1637                 len -= sizeof(*phy_status);
 1638         }
 1639 
 1640         /*
 1641          * Middle frames just have a MAC status (stripped above.)
 1642          * No PHY status, and PLCP is from ar_last_rx_plcp.
 1643          */
 1644 
 1645         /*
 1646          * Discard error frames; don't discard BAD_RA (eg monitor mode);
 1647          * let net80211 do that
 1648          */
 1649         if (__predict_false((mac_status->error & ~AR_RX_ERROR_BAD_RA) != 0)) {
 1650                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "error frame 0x%02x\n", mac_status->error);
 1651                 if (mac_status->error & AR_RX_ERROR_FCS) {
 1652                         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "bad FCS\n");
 1653                 } else if (mac_status->error & AR_RX_ERROR_MMIC) {
 1654                         /* Report Michael MIC failures to net80211. */
 1655 #if 0
 1656                         ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx);
 1657 #endif
 1658                         device_printf(sc->sc_dev, "%s: MIC failure\n", __func__);
 1659                 }
 1660                 counter_u64_add(ic->ic_ierrors, 1);
 1661                 return;
 1662         }
 1663 
 1664         /*
 1665          * Make sure there's room for an 802.11 header + FCS.
 1666          *
 1667          * Note: a CTS/ACK is 14 bytes (FC, DUR, RA, FCS).
 1668          * Making it IEEE80211_MIN_LEN misses CTS/ACKs.
 1669          *
 1670          * This won't be tossed at this point; eventually once
 1671          * rx radiotap is implemented this will allow for
 1672          * CTS/ACK frames.  Passing them up to net80211 will
 1673          * currently make it angry (too short packets.)
 1674          */
 1675         if (len < 2 + 2 + IEEE80211_ADDR_LEN + IEEE80211_CRC_LEN) {
 1676                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1677                     "%s: too short for 802.11 (len %d)\n",
 1678                     __func__, len);
 1679                 counter_u64_add(ic->ic_ierrors, 1);
 1680                 return;
 1681         }
 1682 
 1683         len -= IEEE80211_CRC_LEN;       /* strip 802.11 FCS */
 1684         wh = (struct ieee80211_frame *) buf;
 1685 
 1686         /*
 1687          * The firmware does seem to spit out a bunch of frames
 1688          * with invalid frame control values here.  Just toss them
 1689          * rather than letting net80211 get angry and log.
 1690          */
 1691         if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
 1692             IEEE80211_FC0_VERSION_0) {
 1693                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1694                     "%s: invalid 802.11 fc version (firmware bug?)\n",
 1695                         __func__);
 1696                 counter_u64_add(ic->ic_ierrors, 1);
 1697                 return;
 1698         }
 1699 
 1700         m = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
 1701         if (m == NULL) {
 1702                 device_printf(sc->sc_dev, "%s: failed m_get2() (len=%d)\n",
 1703                     __func__, len);
 1704                 counter_u64_add(ic->ic_ierrors, 1);
 1705                 return;
 1706         }
 1707 
 1708         /* Finalize mbuf. */
 1709         memcpy(mtod(m, uint8_t *), wh, len);
 1710         m->m_pkthdr.len = m->m_len = len;
 1711 
 1712         /* XXX TODO: add setting rx radiotap fields here */
 1713 
 1714         /*
 1715          * Ok, check the frame length and toss if it's too short
 1716          * for net80211.  This will toss ACK/CTS.
 1717          */
 1718         if (m->m_len < IEEE80211_MIN_LEN) {
 1719                 /* XXX TODO: add radiotap receive here */
 1720                 m_free(m); m = NULL;
 1721                 return;
 1722         }
 1723 
 1724         /* Add RSSI to this mbuf if we have a PHY header */
 1725         bzero(&rxs, sizeof(rxs));
 1726         rxs.r_flags = IEEE80211_R_NF;
 1727         rxs.c_nf = sc->sc_nf[0];        /* XXX chain 0 != combined rssi/nf */
 1728         if (phy_status != NULL) {
 1729                 rxs.r_flags |= IEEE80211_R_RSSI;
 1730                 rxs.c_rssi = phy_status->rssi;
 1731         }
 1732         /* XXX TODO: add MIMO RSSI/NF as well */
 1733         if (ieee80211_add_rx_params(m, &rxs) == 0) {
 1734                 counter_u64_add(ic->ic_ierrors, 1);
 1735                 return;
 1736         }
 1737 
 1738         /* XXX make a method */
 1739         STAILQ_INSERT_TAIL(&rxq->mq_head, m, m_stailqpkt);
 1740 
 1741 #if 0
 1742         OTUS_UNLOCK(sc);
 1743         ni = ieee80211_find_rxnode(ic, wh);
 1744         rxi.rxi_flags = 0;
 1745         rxi.rxi_rssi = tail->rssi;
 1746         rxi.rxi_tstamp = 0;     /* unused */
 1747         ieee80211_input(ifp, m, ni, &rxi);
 1748 
 1749         /* Node is no longer needed. */
 1750         ieee80211_release_node(ic, ni);
 1751         OTUS_LOCK(sc);
 1752 #endif
 1753 }
 1754 
 1755 static void
 1756 otus_rxeof(struct usb_xfer *xfer, struct otus_data *data, struct mbufq *rxq)
 1757 {
 1758         struct otus_softc *sc = usbd_xfer_softc(xfer);
 1759         caddr_t buf = data->buf;
 1760         struct ar_rx_head *head;
 1761         uint16_t hlen;
 1762         int len, offset = 0;
 1763 
 1764         usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
 1765 
 1766         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1767             "%s: transfer completed; len=%d\n",
 1768             __func__, len);
 1769         if (otus_debug & OTUS_DEBUG_RX_BUFFER) {
 1770                 device_printf(sc->sc_dev, "%s: %*D\n",
 1771                     __func__, len, buf, "-");
 1772         }
 1773 
 1774         while (len >= sizeof (*head)) {
 1775                 head = (struct ar_rx_head *)buf;
 1776                 if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) {
 1777                         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1778                             "tag not valid 0x%x\n", le16toh(head->tag));
 1779                         break;
 1780                 }
 1781                 hlen = le16toh(head->len);
 1782                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: hlen=%d\n",
 1783                     __func__, hlen);
 1784                 if (__predict_false(sizeof (*head) + hlen > len)) {
 1785                         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1786                             "xfer too short %d/%d\n", len, hlen);
 1787                         break;
 1788                 }
 1789                 /* Process sub-xfer. */
 1790                 otus_sub_rxeof(sc, (uint8_t *) (((uint8_t *) buf) + 4), hlen, rxq);
 1791 
 1792                 /* Next sub-xfer is aligned on a 32-bit boundary. */
 1793                 hlen = (sizeof (*head) + hlen + 3) & ~3;
 1794                 offset += hlen;
 1795                 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
 1796                     "%s: rounded size is %d, next packet starts at %d\n",
 1797                     __func__, hlen, offset);
 1798                 buf += hlen;
 1799                 len -= hlen;
 1800         }
 1801         OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: done!\n", __func__);
 1802 }
 1803 
 1804 static void
 1805 otus_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
 1806 {
 1807         struct epoch_tracker et;
 1808         struct otus_softc *sc = usbd_xfer_softc(xfer);
 1809         struct ieee80211com *ic = &sc->sc_ic;
 1810         struct ieee80211_frame *wh;
 1811         struct ieee80211_node *ni;
 1812         struct mbuf *m;
 1813         struct mbufq scrx;
 1814         struct otus_data *data;
 1815 
 1816         OTUS_LOCK_ASSERT(sc);
 1817 
 1818         mbufq_init(&scrx, 1024);
 1819 
 1820 #if 0
 1821         device_printf(sc->sc_dev, "%s: called; state=%d; error=%d\n",
 1822             __func__,
 1823             USB_GET_STATE(xfer),
 1824             error);
 1825 #endif
 1826 
 1827         switch (USB_GET_STATE(xfer)) {
 1828         case USB_ST_TRANSFERRED:
 1829                 data = STAILQ_FIRST(&sc->sc_rx_active);
 1830                 if (data == NULL)
 1831                         goto tr_setup;
 1832                 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
 1833                 otus_rxeof(xfer, data, &scrx);
 1834                 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
 1835                 /* FALLTHROUGH */
 1836         case USB_ST_SETUP:
 1837 tr_setup:
 1838                 /*
 1839                  * XXX TODO: what if sc_rx isn't empty, but data
 1840                  * is empty?  Then we leak mbufs.
 1841                  */
 1842                 data = STAILQ_FIRST(&sc->sc_rx_inactive);
 1843                 if (data == NULL) {
 1844                         //KASSERT(m == NULL, ("mbuf isn't NULL"));
 1845                         return;
 1846                 }
 1847                 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
 1848                 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
 1849                 usbd_xfer_set_frame_data(xfer, 0, data->buf,
 1850                     usbd_xfer_max_len(xfer));
 1851                 usbd_transfer_submit(xfer);
 1852                 /*
 1853                  * To avoid LOR we should unlock our private mutex here to call
 1854                  * ieee80211_input() because here is at the end of a USB
 1855                  * callback and safe to unlock.
 1856                  */
 1857                 OTUS_UNLOCK(sc);
 1858                 NET_EPOCH_ENTER(et);
 1859                 while ((m = mbufq_dequeue(&scrx)) != NULL) {
 1860                         wh = mtod(m, struct ieee80211_frame *);
 1861                         ni = ieee80211_find_rxnode(ic,
 1862                             (struct ieee80211_frame_min *)wh);
 1863                         if (ni != NULL) {
 1864                                 if (ni->ni_flags & IEEE80211_NODE_HT)
 1865                                         m->m_flags |= M_AMPDU;
 1866                                 (void)ieee80211_input_mimo(ni, m);
 1867                                 ieee80211_free_node(ni);
 1868                         } else
 1869                                 (void)ieee80211_input_mimo_all(ic, m);
 1870                 }
 1871                 NET_EPOCH_EXIT(et);
 1872 #ifdef  IEEE80211_SUPPORT_SUPERG
 1873                 ieee80211_ff_age_all(ic, 100);
 1874 #endif
 1875                 OTUS_LOCK(sc);
 1876                 break;
 1877         default:
 1878                 /* needs it to the inactive queue due to a error. */
 1879                 data = STAILQ_FIRST(&sc->sc_rx_active);
 1880                 if (data != NULL) {
 1881                         STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
 1882                         STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
 1883                 }
 1884                 if (error != USB_ERR_CANCELLED) {
 1885                         usbd_xfer_set_stall(xfer);
 1886                         counter_u64_add(ic->ic_ierrors, 1);
 1887                         goto tr_setup;
 1888                 }
 1889                 break;
 1890         }
 1891 }
 1892 
 1893 static void
 1894 otus_txeof(struct usb_xfer *xfer, struct otus_data *data)
 1895 {
 1896         struct otus_softc *sc = usbd_xfer_softc(xfer);
 1897 
 1898         OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE,
 1899             "%s: called; data=%p\n", __func__, data);
 1900 
 1901         OTUS_LOCK_ASSERT(sc);
 1902 
 1903         if (sc->sc_tx_n_active == 0) {
 1904                 device_printf(sc->sc_dev,
 1905                     "%s: completed but tx_active=0\n",
 1906                     __func__);
 1907         } else {
 1908                 sc->sc_tx_n_active--;
 1909         }
 1910 
 1911         if (data->m) {
 1912                 /* XXX status? */
 1913                 /* XXX we get TX status via the RX path.. */
 1914                 ieee80211_tx_complete(data->ni, data->m, 0);
 1915                 data->m = NULL;
 1916                 data->ni = NULL;
 1917         }
 1918 }
 1919 
 1920 static void
 1921 otus_txcmdeof(struct usb_xfer *xfer, struct otus_tx_cmd *cmd)
 1922 {
 1923         struct otus_softc *sc = usbd_xfer_softc(xfer);
 1924 
 1925         OTUS_LOCK_ASSERT(sc);
 1926 
 1927         OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 1928             "%s: called; data=%p; odata=%p\n",
 1929             __func__, cmd, cmd->odata);
 1930 
 1931         /*
 1932          * Non-response commands still need wakeup so the caller
 1933          * knows it was submitted and completed OK; response commands should
 1934          * wait until they're ACKed by the firmware with a response.
 1935          */
 1936         if (cmd->odata) {
 1937                 STAILQ_INSERT_TAIL(&sc->sc_cmd_waiting, cmd, next_cmd);
 1938         } else {
 1939                 wakeup(cmd);
 1940                 otus_free_txcmd(sc, cmd);
 1941         }
 1942 }
 1943 
 1944 static void
 1945 otus_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
 1946 {
 1947         uint8_t which = OTUS_BULK_TX;
 1948         struct otus_softc *sc = usbd_xfer_softc(xfer);
 1949         struct ieee80211com *ic = &sc->sc_ic;
 1950         struct otus_data *data;
 1951 
 1952         OTUS_LOCK_ASSERT(sc);
 1953 
 1954         switch (USB_GET_STATE(xfer)) {
 1955         case USB_ST_TRANSFERRED:
 1956                 data = STAILQ_FIRST(&sc->sc_tx_active[which]);
 1957                 if (data == NULL)
 1958                         goto tr_setup;
 1959                 OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE,
 1960                     "%s: transfer done %p\n", __func__, data);
 1961                 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
 1962                 otus_txeof(xfer, data);
 1963                 otus_freebuf(sc, data);
 1964                 /* FALLTHROUGH */
 1965         case USB_ST_SETUP:
 1966 tr_setup:
 1967                 data = STAILQ_FIRST(&sc->sc_tx_pending[which]);
 1968                 if (data == NULL) {
 1969                         OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
 1970                             "%s: empty pending queue sc %p\n", __func__, sc);
 1971                         sc->sc_tx_n_active = 0;
 1972                         goto finish;
 1973                 }
 1974                 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next);
 1975                 STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next);
 1976                 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
 1977                 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
 1978                     "%s: submitting transfer %p\n", __func__, data);
 1979                 usbd_transfer_submit(xfer);
 1980                 sc->sc_tx_n_active++;
 1981                 break;
 1982         default:
 1983                 data = STAILQ_FIRST(&sc->sc_tx_active[which]);
 1984                 if (data != NULL) {
 1985                         STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
 1986                         otus_txeof(xfer, data);
 1987                         otus_freebuf(sc, data);
 1988                 }
 1989                 counter_u64_add(ic->ic_oerrors, 1);
 1990 
 1991                 if (error != USB_ERR_CANCELLED) {
 1992                         usbd_xfer_set_stall(xfer);
 1993                         goto tr_setup;
 1994                 }
 1995                 break;
 1996         }
 1997 
 1998 finish:
 1999 #ifdef  IEEE80211_SUPPORT_SUPERG
 2000         /*
 2001          * If the TX active queue drops below a certain
 2002          * threshold, ensure we age fast-frames out so they're
 2003          * transmitted.
 2004          */
 2005         if (sc->sc_tx_n_active < 2) {
 2006                 /* XXX ew - net80211 should defer this for us! */
 2007                 OTUS_UNLOCK(sc);
 2008                 ieee80211_ff_flush(ic, WME_AC_VO);
 2009                 ieee80211_ff_flush(ic, WME_AC_VI);
 2010                 ieee80211_ff_flush(ic, WME_AC_BE);
 2011                 ieee80211_ff_flush(ic, WME_AC_BK);
 2012                 OTUS_LOCK(sc);
 2013         }
 2014 #endif
 2015         /* Kick TX */
 2016         otus_tx_start(sc);
 2017 }
 2018 
 2019 static void
 2020 otus_bulk_cmd_callback(struct usb_xfer *xfer, usb_error_t error)
 2021 {
 2022         struct otus_softc *sc = usbd_xfer_softc(xfer);
 2023 #if 0
 2024         struct ieee80211com *ic = &sc->sc_ic;
 2025 #endif
 2026         struct otus_tx_cmd *cmd;
 2027 
 2028         OTUS_LOCK_ASSERT(sc);
 2029 
 2030         switch (USB_GET_STATE(xfer)) {
 2031         case USB_ST_TRANSFERRED:
 2032                 cmd = STAILQ_FIRST(&sc->sc_cmd_active);
 2033                 if (cmd == NULL)
 2034                         goto tr_setup;
 2035                 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE,
 2036                     "%s: transfer done %p\n", __func__, cmd);
 2037                 STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd);
 2038                 otus_txcmdeof(xfer, cmd);
 2039                 /* FALLTHROUGH */
 2040         case USB_ST_SETUP:
 2041 tr_setup:
 2042                 cmd = STAILQ_FIRST(&sc->sc_cmd_pending);
 2043                 if (cmd == NULL) {
 2044                         OTUS_DPRINTF(sc, OTUS_DEBUG_CMD,
 2045                             "%s: empty pending queue sc %p\n", __func__, sc);
 2046                         return;
 2047                 }
 2048                 STAILQ_REMOVE_HEAD(&sc->sc_cmd_pending, next_cmd);
 2049                 STAILQ_INSERT_TAIL(&sc->sc_cmd_active, cmd, next_cmd);
 2050                 usbd_xfer_set_frame_data(xfer, 0, cmd->buf, cmd->buflen);
 2051                 OTUS_DPRINTF(sc, OTUS_DEBUG_CMD,
 2052                     "%s: submitting transfer %p; buf=%p, buflen=%d\n", __func__, cmd, cmd->buf, cmd->buflen);
 2053                 usbd_transfer_submit(xfer);
 2054                 break;
 2055         default:
 2056                 cmd = STAILQ_FIRST(&sc->sc_cmd_active);
 2057                 if (cmd != NULL) {
 2058                         STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd);
 2059                         otus_txcmdeof(xfer, cmd);
 2060                 }
 2061 
 2062                 if (error != USB_ERR_CANCELLED) {
 2063                         usbd_xfer_set_stall(xfer);
 2064                         goto tr_setup;
 2065                 }
 2066                 break;
 2067         }
 2068 }
 2069 
 2070 /*
 2071  * This isn't used by carl9170; it however may be used by the
 2072  * initial bootloader.
 2073  */
 2074 static void
 2075 otus_bulk_irq_callback(struct usb_xfer *xfer, usb_error_t error)
 2076 {
 2077         struct otus_softc *sc = usbd_xfer_softc(xfer);
 2078         int actlen;
 2079         int sumlen;
 2080 
 2081         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
 2082         OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ,
 2083             "%s: called; state=%d\n", __func__, USB_GET_STATE(xfer));
 2084 
 2085         switch (USB_GET_STATE(xfer)) {
 2086         case USB_ST_TRANSFERRED:
 2087                 /*
 2088                  * Read usb frame data, if any.
 2089                  * "actlen" has the total length for all frames
 2090                  * transferred.
 2091                  */
 2092                 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ,
 2093                     "%s: comp; %d bytes\n",
 2094                     __func__,
 2095                     actlen);
 2096 #if 0
 2097                 pc = usbd_xfer_get_frame(xfer, 0);
 2098                 otus_dump_usb_rx_page(sc, pc, actlen);
 2099 #endif
 2100                 /* XXX fallthrough */
 2101         case USB_ST_SETUP:
 2102                 /*
 2103                  * Setup xfer frame lengths/count and data
 2104                  */
 2105                 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: setup\n", __func__);
 2106                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
 2107                 usbd_transfer_submit(xfer);
 2108                 break;
 2109 
 2110         default: /* Error */
 2111                 /*
 2112                  * Print error message and clear stall
 2113                  * for example.
 2114                  */
 2115                 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: ERROR?\n", __func__);
 2116                 break;
 2117         }
 2118 }
 2119 
 2120 /*
 2121  * Map net80211 rate to hw rate for otus MAC/PHY.
 2122  */
 2123 static uint8_t
 2124 otus_rate_to_hw_rate(struct otus_softc *sc, uint8_t rate)
 2125 {
 2126         int is_2ghz;
 2127 
 2128         is_2ghz = !! (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_curchan));
 2129 
 2130         /* MCS check */
 2131         if (rate & 0x80) {
 2132                 return rate;
 2133         }
 2134 
 2135         switch (rate) {
 2136         /* CCK */
 2137         case 2:
 2138                 return (0x0);
 2139         case 4:
 2140                 return (0x1);
 2141         case 11:
 2142                 return (0x2);
 2143         case 22:
 2144                 return (0x3);
 2145         /* OFDM */
 2146         case 12:
 2147                 return (0xb);
 2148         case 18:
 2149                 return (0xf);
 2150         case 24:
 2151                 return (0xa);
 2152         case 36:
 2153                 return (0xe);
 2154         case 48:
 2155                 return (0x9);
 2156         case 72:
 2157                 return (0xd);
 2158         case 96:
 2159                 return (0x8);
 2160         case 108:
 2161                 return (0xc);
 2162         default:
 2163                 device_printf(sc->sc_dev, "%s: unknown rate '%d'\n",
 2164                     __func__, (int) rate);
 2165         case 0:
 2166                 if (is_2ghz)
 2167                         return (0x0);   /* 1MB CCK */
 2168                 else
 2169                         return (0xb);   /* 6MB OFDM */
 2170         }
 2171 }
 2172 
 2173 static int
 2174 otus_hw_rate_is_ht(struct otus_softc *sc, uint8_t hw_rate)
 2175 {
 2176 
 2177         return !! (hw_rate & 0x80);
 2178 }
 2179 
 2180 static int
 2181 otus_hw_rate_is_ofdm(struct otus_softc *sc, uint8_t hw_rate)
 2182 {
 2183 
 2184         switch (hw_rate) {
 2185         case 0x0:
 2186         case 0x1:
 2187         case 0x2:
 2188         case 0x3:
 2189                 return (0);
 2190         default:
 2191                 return (1);
 2192         }
 2193 }
 2194 
 2195 static void
 2196 otus_tx_update_ratectl(struct otus_softc *sc, struct ieee80211_node *ni)
 2197 {
 2198         struct ieee80211_ratectl_tx_stats *txs = &sc->sc_txs;
 2199         struct otus_node *on = OTUS_NODE(ni);
 2200 
 2201         txs->flags = IEEE80211_RATECTL_TX_STATS_NODE |
 2202                      IEEE80211_RATECTL_TX_STATS_RETRIES;
 2203         txs->ni = ni;
 2204         txs->nframes = on->tx_done;
 2205         txs->nsuccess = on->tx_done - on->tx_err;
 2206         txs->nretries = on->tx_retries;
 2207 
 2208         ieee80211_ratectl_tx_update(ni->ni_vap, txs);
 2209         on->tx_done = on->tx_err = on->tx_retries = 0;
 2210 }
 2211 
 2212 /*
 2213  * XXX TODO: support tx bpf parameters for configuration!
 2214  *
 2215  * Relevant pieces:
 2216  *
 2217  * ac = params->ibp_pri & 3;
 2218  * rate = params->ibp_rate0;
 2219  * params->ibp_flags & IEEE80211_BPF_NOACK
 2220  * params->ibp_flags & IEEE80211_BPF_RTS
 2221  * params->ibp_flags & IEEE80211_BPF_CTS
 2222  * tx->rts_ntries = params->ibp_try1;
 2223  * tx->data_ntries = params->ibp_try0;
 2224  */
 2225 static int
 2226 otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
 2227     struct otus_data *data, const struct ieee80211_bpf_params *params)
 2228 {
 2229         const struct ieee80211_txparam *tp = ni->ni_txparms;
 2230         struct ieee80211com *ic = &sc->sc_ic;
 2231         struct ieee80211vap *vap = ni->ni_vap;
 2232         struct ieee80211_frame *wh;
 2233         struct ieee80211_key *k;
 2234         struct ar_tx_head *head;
 2235         uint32_t phyctl;
 2236         uint16_t macctl, qos;
 2237         uint8_t qid, rate;
 2238         int hasqos, xferlen, type, ismcast;
 2239 
 2240         wh = mtod(m, struct ieee80211_frame *);
 2241         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 2242                 k = ieee80211_crypto_encap(ni, m);
 2243                 if (k == NULL) {
 2244                         device_printf(sc->sc_dev,
 2245                             "%s: m=%p: ieee80211_crypto_encap returns NULL\n",
 2246                             __func__,
 2247                             m);
 2248                         return (ENOBUFS);
 2249                 }
 2250                 wh = mtod(m, struct ieee80211_frame *);
 2251         }
 2252 
 2253         /* Calculate transfer length; ensure data buffer is large enough */
 2254         xferlen = sizeof (*head) + m->m_pkthdr.len;
 2255         if (xferlen > OTUS_TXBUFSZ) {
 2256                 device_printf(sc->sc_dev,
 2257                     "%s: 802.11 TX frame is %d bytes, max %d bytes\n",
 2258                     __func__,
 2259                     xferlen,
 2260                     OTUS_TXBUFSZ);
 2261                 return (ENOBUFS);
 2262         }
 2263 
 2264         hasqos = !! IEEE80211_QOS_HAS_SEQ(wh);
 2265 
 2266         if (hasqos) {
 2267                 uint8_t tid;
 2268                 qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
 2269                 tid = qos & IEEE80211_QOS_TID;
 2270                 qid = TID_TO_WME_AC(tid);
 2271         } else {
 2272                 qos = 0;
 2273                 qid = WME_AC_BE;
 2274         }
 2275 
 2276         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 2277         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
 2278 
 2279         /* Pickup a rate index. */
 2280         if (params != NULL)
 2281                 rate = otus_rate_to_hw_rate(sc, params->ibp_rate0);
 2282         else if (!!(m->m_flags & M_EAPOL) || type != IEEE80211_FC0_TYPE_DATA)
 2283                 rate = otus_rate_to_hw_rate(sc, tp->mgmtrate);
 2284         else if (ismcast)
 2285                 rate = otus_rate_to_hw_rate(sc, tp->mcastrate);
 2286         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 2287                 rate = otus_rate_to_hw_rate(sc, tp->ucastrate);
 2288         else {
 2289                 (void) ieee80211_ratectl_rate(ni, NULL, 0);
 2290                 rate = otus_rate_to_hw_rate(sc, ni->ni_txrate);
 2291         }
 2292 
 2293         phyctl = 0;
 2294         macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid);
 2295 
 2296         /*
 2297          * XXX TODO: params for NOACK, ACK, RTS, CTS, etc
 2298          */
 2299         if (ismcast ||
 2300             (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY) ==
 2301              IEEE80211_QOS_ACKPOLICY_NOACK)))
 2302                 macctl |= AR_TX_MAC_NOACK;
 2303 
 2304         if (!ismcast) {
 2305                 if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= vap->iv_rtsthreshold)
 2306                         macctl |= AR_TX_MAC_RTS;
 2307                 else if (otus_hw_rate_is_ht(sc, rate)) {
 2308                         if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
 2309                                 macctl |= AR_TX_MAC_RTS;
 2310                 } else if (ic->ic_flags & IEEE80211_F_USEPROT) {
 2311                         if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
 2312                                 macctl |= AR_TX_MAC_CTS;
 2313                         else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
 2314                                 macctl |= AR_TX_MAC_RTS;
 2315                 }
 2316         }
 2317 
 2318         phyctl |= AR_TX_PHY_MCS(rate & 0x7f); /* Note: MCS rates are 0x80 and above */
 2319         if (otus_hw_rate_is_ht(sc, rate)) {
 2320                 phyctl |= AR_TX_PHY_MT_HT;
 2321                 /* Always use all tx antennas for now, just to be safe */
 2322                 phyctl |= AR_TX_PHY_ANTMSK(sc->txmask);
 2323 
 2324                 /* Heavy clip */
 2325                 phyctl |= (rate & 0x7) << AR_TX_PHY_TX_HEAVY_CLIP_SHIFT;
 2326         } else if (otus_hw_rate_is_ofdm(sc, rate)) {
 2327                 phyctl |= AR_TX_PHY_MT_OFDM;
 2328                 /* Always use all tx antennas for now, just to be safe */
 2329                 phyctl |= AR_TX_PHY_ANTMSK(sc->txmask);
 2330         } else {        /* CCK */
 2331                 phyctl |= AR_TX_PHY_MT_CCK;
 2332                 phyctl |= AR_TX_PHY_ANTMSK(sc->txmask);
 2333         }
 2334 
 2335         /* Update net80211 with the current counters */
 2336         otus_tx_update_ratectl(sc, ni);
 2337 
 2338         /* Update rate control stats for frames that are ACK'ed. */
 2339         if (!(macctl & AR_TX_MAC_NOACK))
 2340                 OTUS_NODE(ni)->tx_done++;
 2341 
 2342         /* Fill Tx descriptor. */
 2343         head = (struct ar_tx_head *)data->buf;
 2344         head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN);
 2345         head->macctl = htole16(macctl);
 2346         head->phyctl = htole32(phyctl);
 2347 
 2348         m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&head[1]);
 2349 
 2350         data->buflen = xferlen;
 2351         data->ni = ni;
 2352         data->m = m;
 2353 
 2354         OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
 2355             "%s: tx: m=%p; data=%p; len=%d mac=0x%04x phy=0x%08x rate=0x%02x, ni_txrate=%d\n",
 2356             __func__, m, data, le16toh(head->len), macctl, phyctl,
 2357             (int) rate, (int) ni->ni_txrate);
 2358 
 2359         /* Submit transfer */
 2360         STAILQ_INSERT_TAIL(&sc->sc_tx_pending[OTUS_BULK_TX], data, next);
 2361         usbd_transfer_start(sc->sc_xfer[OTUS_BULK_TX]);
 2362 
 2363         return 0;
 2364 }
 2365 
 2366 static u_int
 2367 otus_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
 2368 {
 2369         uint32_t val, *hashes = arg;
 2370 
 2371         val = le32dec(LLADDR(sdl) + 4);
 2372         /* Get address byte 5 */
 2373         val = val & 0x0000ff00;
 2374         val = val >> 8;
 2375 
 2376         /* As per below, shift it >> 2 to get only 6 bits */
 2377         val = val >> 2;
 2378         if (val < 32)
 2379                 hashes[0] |= 1 << val;
 2380         else
 2381                 hashes[1] |= 1 << (val - 32);
 2382 
 2383         return (1);
 2384 }
 2385 
 2386 int
 2387 otus_set_multi(struct otus_softc *sc)
 2388 {
 2389         struct ieee80211com *ic = &sc->sc_ic;
 2390         uint32_t hashes[2];
 2391         int r;
 2392 
 2393         if (ic->ic_allmulti > 0 || ic->ic_promisc > 0 ||
 2394             ic->ic_opmode == IEEE80211_M_MONITOR) {
 2395                 hashes[0] = 0xffffffff;
 2396                 hashes[1] = 0xffffffff;
 2397         } else {
 2398                 struct ieee80211vap *vap;
 2399 
 2400                 hashes[0] = hashes[1] = 0;
 2401                 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
 2402                         if_foreach_llmaddr(vap->iv_ifp, otus_hash_maddr,
 2403                             hashes);
 2404         }
 2405 #if 0
 2406         /* XXX openbsd code */
 2407         while (enm != NULL) {
 2408                 bit = enm->enm_addrlo[5] >> 2;
 2409                 if (bit < 32)
 2410                         hashes[0] |= 1 << bit;
 2411                 else
 2412                         hashes[1] |= 1 << (bit - 32);
 2413                 ETHER_NEXT_MULTI(step, enm);
 2414         }
 2415 #endif
 2416 
 2417         hashes[1] |= 1U << 31;  /* Make sure the broadcast bit is set. */
 2418 
 2419         OTUS_LOCK(sc);
 2420         otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, hashes[0]);
 2421         otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hashes[1]);
 2422         r = otus_write_barrier(sc);
 2423         /* XXX operating mode? filter? */
 2424         OTUS_UNLOCK(sc);
 2425         return (r);
 2426 }
 2427 
 2428 static int
 2429 otus_updateedca(struct ieee80211com *ic)
 2430 {
 2431         struct otus_softc *sc = ic->ic_softc;
 2432 
 2433         OTUS_LOCK(sc);
 2434         /*
 2435          * XXX TODO: take temporary copy of EDCA information
 2436          * when scheduling this so we have a more time-correct view
 2437          * of things.
 2438          * XXX TODO: this can be done on the net80211 level
 2439          */
 2440         otus_updateedca_locked(sc);
 2441         OTUS_UNLOCK(sc);
 2442         return (0);
 2443 }
 2444 
 2445 static void
 2446 otus_updateedca_locked(struct otus_softc *sc)
 2447 {
 2448 #define EXP2(val)       ((1 << (val)) - 1)
 2449 #define AIFS(val)       ((val) * 9 + 10)
 2450         struct chanAccParams chp;
 2451         struct ieee80211com *ic = &sc->sc_ic;
 2452         const struct wmeParams *edca;
 2453 
 2454         ieee80211_wme_ic_getparams(ic, &chp);
 2455 
 2456         OTUS_LOCK_ASSERT(sc);
 2457 
 2458         edca = chp.cap_wmeParams;
 2459 
 2460         /* Set CWmin/CWmax values. */
 2461         otus_write(sc, AR_MAC_REG_AC0_CW,
 2462             EXP2(edca[WME_AC_BE].wmep_logcwmax) << 16 |
 2463             EXP2(edca[WME_AC_BE].wmep_logcwmin));
 2464         otus_write(sc, AR_MAC_REG_AC1_CW,
 2465             EXP2(edca[WME_AC_BK].wmep_logcwmax) << 16 |
 2466             EXP2(edca[WME_AC_BK].wmep_logcwmin));
 2467         otus_write(sc, AR_MAC_REG_AC2_CW,
 2468             EXP2(edca[WME_AC_VI].wmep_logcwmax) << 16 |
 2469             EXP2(edca[WME_AC_VI].wmep_logcwmin));
 2470         otus_write(sc, AR_MAC_REG_AC3_CW,
 2471             EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 |
 2472             EXP2(edca[WME_AC_VO].wmep_logcwmin));
 2473         otus_write(sc, AR_MAC_REG_AC4_CW,               /* Special TXQ. */
 2474             EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 |
 2475             EXP2(edca[WME_AC_VO].wmep_logcwmin));
 2476 
 2477         /* Set AIFSN values. */
 2478         otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS,
 2479             AIFS(edca[WME_AC_VI].wmep_aifsn) << 24 |
 2480             AIFS(edca[WME_AC_BK].wmep_aifsn) << 12 |
 2481             AIFS(edca[WME_AC_BE].wmep_aifsn));
 2482         otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS,
 2483             AIFS(edca[WME_AC_VO].wmep_aifsn) << 16 |    /* Special TXQ. */
 2484             AIFS(edca[WME_AC_VO].wmep_aifsn) <<  4 |
 2485             AIFS(edca[WME_AC_VI].wmep_aifsn) >>  8);
 2486 
 2487         /* Set TXOP limit. */
 2488         otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP,
 2489             edca[WME_AC_BK].wmep_txopLimit << 16 |
 2490             edca[WME_AC_BE].wmep_txopLimit);
 2491         otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP,
 2492             edca[WME_AC_VO].wmep_txopLimit << 16 |
 2493             edca[WME_AC_VI].wmep_txopLimit);
 2494 
 2495         /* XXX ACK policy? */
 2496 
 2497         (void)otus_write_barrier(sc);
 2498 
 2499 #undef AIFS
 2500 #undef EXP2
 2501 }
 2502 
 2503 static void
 2504 otus_updateslot(struct otus_softc *sc)
 2505 {
 2506         struct ieee80211com *ic = &sc->sc_ic;
 2507         uint32_t slottime;
 2508 
 2509         OTUS_LOCK_ASSERT(sc);
 2510 
 2511         slottime = IEEE80211_GET_SLOTTIME(ic);
 2512         otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10);
 2513         (void)otus_write_barrier(sc);
 2514 }
 2515 
 2516 /*
 2517  * Things to do based on 2GHz or 5GHz:
 2518  *
 2519  * + slottime
 2520  * + dyn_sifs_ack
 2521  * + rts_cts_rate
 2522  * + slot time
 2523  * + mac_rates
 2524  * + mac_tpc
 2525  *
 2526  * And in the transmit path
 2527  * + tpc: carl9170_tx_rate_tpc_chains
 2528  * + carl9170_tx_physet()
 2529  * + disable short premable tx
 2530  */
 2531 
 2532 int
 2533 otus_init_mac(struct otus_softc *sc)
 2534 {
 2535         int error;
 2536 
 2537         OTUS_LOCK_ASSERT(sc);
 2538 
 2539         otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40);
 2540         otus_write(sc, AR_MAC_REG_RETRY_MAX, 0);
 2541         otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80);
 2542         otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70);
 2543         otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000);
 2544         otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10);
 2545         otus_write(sc, AR_MAC_REG_TID_CFACK_CFEND_RATE, 0x19000000);
 2546         /* NAV protects ACK only (in TXOP). */
 2547         otus_write(sc, AR_MAC_REG_TXOP_DURATION, 0x201);
 2548         /* Set beacon Tx power to 0x7. */
 2549         otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170);
 2550         otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105);
 2551         otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a);
 2552 
 2553         otus_set_rx_filter(sc);
 2554 
 2555         otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f);
 2556         otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f);
 2557         otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
 2558         otus_write(sc, AR_MAC_REG_ACK_TPC, 0x4003c1e);
 2559 
 2560         /* Enable LED0 and LED1. */
 2561         otus_write(sc, AR_GPIO_REG_PORT_TYPE, 0x3);
 2562         otus_write(sc, AR_GPIO_REG_PORT_DATA, 0x3);
 2563         /* Switch MAC to OTUS interface. */
 2564         otus_write(sc, 0x1c3600, 0x3);
 2565         otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff);
 2566         otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008);
 2567         /* Disable Rx timeout (workaround). */
 2568         otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0);
 2569 
 2570         /* Set USB Rx stream mode maximum frame number to 2. */
 2571         otus_write(sc, 0x1e1110, 0x4);
 2572         /* Set USB Rx stream mode timeout to 10us. */
 2573         otus_write(sc, 0x1e1114, 0x80);
 2574 
 2575         /* Set clock frequency to 88/80MHz. */
 2576         otus_write(sc, AR_PWR_REG_CLOCK_SEL, 0x73);
 2577         /* Set WLAN DMA interrupt mode: generate intr per packet. */
 2578         otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011);
 2579         otus_write(sc, AR_MAC_REG_FCS_SELECT, 0x4);
 2580         otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48);
 2581 
 2582         /* Disable HW decryption for now. */
 2583         otus_write(sc, AR_MAC_REG_ENCRYPTION, 0x78);
 2584 
 2585         if ((error = otus_write_barrier(sc)) != 0)
 2586                 return error;
 2587 
 2588         /* Set default EDCA parameters. */
 2589         otus_updateedca_locked(sc);
 2590 
 2591         return 0;
 2592 }
 2593 
 2594 /*
 2595  * Return default value for PHY register based on current operating mode.
 2596  */
 2597 uint32_t
 2598 otus_phy_get_def(struct otus_softc *sc, uint32_t reg)
 2599 {
 2600         int i;
 2601 
 2602         for (i = 0; i < nitems(ar5416_phy_regs); i++)
 2603                 if (AR_PHY(ar5416_phy_regs[i]) == reg)
 2604                         return sc->phy_vals[i];
 2605         return 0;       /* Register not found. */
 2606 }
 2607 
 2608 /*
 2609  * Update PHY's programming based on vendor-specific data stored in EEPROM.
 2610  * This is for FEM-type devices only.
 2611  */
 2612 int
 2613 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c)
 2614 {
 2615         const struct ModalEepHeader *eep;
 2616         uint32_t tmp, offset;
 2617 
 2618         if (IEEE80211_IS_CHAN_5GHZ(c))
 2619                 eep = &sc->eeprom.modalHeader[0];
 2620         else
 2621                 eep = &sc->eeprom.modalHeader[1];
 2622 
 2623         /* Offset of chain 2. */
 2624         offset = 2 * 0x1000;
 2625 
 2626         tmp = le32toh(eep->antCtrlCommon);
 2627         otus_write(sc, AR_PHY_SWITCH_COM, tmp);
 2628 
 2629         tmp = le32toh(eep->antCtrlChain[0]);
 2630         otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp);
 2631 
 2632         tmp = le32toh(eep->antCtrlChain[1]);
 2633         otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp);
 2634 
 2635         if (1 /* sc->sc_sco == AR_SCO_SCN */) {
 2636                 tmp = otus_phy_get_def(sc, AR_PHY_SETTLING);
 2637                 tmp &= ~(0x7f << 7);
 2638                 tmp |= (eep->switchSettling & 0x7f) << 7;
 2639                 otus_write(sc, AR_PHY_SETTLING, tmp);
 2640         }
 2641 
 2642         tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ);
 2643         tmp &= ~0xffff;
 2644         tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize;
 2645         otus_write(sc, AR_PHY_DESIRED_SZ, tmp);
 2646 
 2647         tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 |
 2648               eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn;
 2649         otus_write(sc, AR_PHY_RF_CTL4, tmp);
 2650 
 2651         tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3);
 2652         tmp &= ~(0xff << 16);
 2653         tmp |= eep->txEndToRxOn << 16;
 2654         otus_write(sc, AR_PHY_RF_CTL3, tmp);
 2655 
 2656         tmp = otus_phy_get_def(sc, AR_PHY_CCA);
 2657         tmp &= ~(0x7f << 12);
 2658         tmp |= (eep->thresh62 & 0x7f) << 12;
 2659         otus_write(sc, AR_PHY_CCA, tmp);
 2660 
 2661         tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN);
 2662         tmp &= ~(0x3f << 12);
 2663         tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12;
 2664         otus_write(sc, AR_PHY_RXGAIN, tmp);
 2665 
 2666         tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset);
 2667         tmp &= ~(0x3f << 12);
 2668         tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12;
 2669         otus_write(sc, AR_PHY_RXGAIN + offset, tmp);
 2670 
 2671         tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ);
 2672         tmp &= ~(0x3f << 18);
 2673         tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18;
 2674         if (IEEE80211_IS_CHAN_5GHZ(c)) {
 2675                 tmp &= ~(0xf << 10);
 2676                 tmp |= (eep->bswMargin[0] & 0xf) << 10;
 2677         }
 2678         otus_write(sc, AR_PHY_GAIN_2GHZ, tmp);
 2679 
 2680         tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset);
 2681         tmp &= ~(0x3f << 18);
 2682         tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18;
 2683         otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp);
 2684 
 2685         tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4);
 2686         tmp &= ~(0x3f << 5 | 0x1f);
 2687         tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f);
 2688         otus_write(sc, AR_PHY_TIMING_CTRL4, tmp);
 2689 
 2690         tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset);
 2691         tmp &= ~(0x3f << 5 | 0x1f);
 2692         tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f);
 2693         otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp);
 2694 
 2695         tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1);
 2696         tmp &= ~(0xf << 16);
 2697         tmp |= (eep->xpd & 0xf) << 16;
 2698         otus_write(sc, AR_PHY_TPCRG1, tmp);
 2699 
 2700         return otus_write_barrier(sc);
 2701 }
 2702 
 2703 int
 2704 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c)
 2705 {
 2706         const uint32_t *vals;
 2707         int error, i;
 2708 
 2709         /* Select PHY programming based on band and bandwidth. */
 2710         if (IEEE80211_IS_CHAN_2GHZ(c)) {
 2711                 if (IEEE80211_IS_CHAN_HT40(c))
 2712                         vals = ar5416_phy_vals_2ghz_40mhz;
 2713                 else
 2714                         vals = ar5416_phy_vals_2ghz_20mhz;
 2715         } else {
 2716                 if (IEEE80211_IS_CHAN_HT40(c))
 2717                         vals = ar5416_phy_vals_5ghz_40mhz;
 2718                 else
 2719                         vals = ar5416_phy_vals_5ghz_20mhz;
 2720         }
 2721         for (i = 0; i < nitems(ar5416_phy_regs); i++)
 2722                 otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]);
 2723         sc->phy_vals = vals;
 2724 
 2725         if (sc->eeprom.baseEepHeader.deviceType == 0x80)        /* FEM */
 2726                 if ((error = otus_set_board_values(sc, c)) != 0)
 2727                         return error;
 2728 
 2729         /* Initial Tx power settings. */
 2730         otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f);
 2731         otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f);
 2732         otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f);
 2733         otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f);
 2734         otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f);
 2735         otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f);
 2736         otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f);
 2737         otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f);
 2738         otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f);
 2739         otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f);
 2740 
 2741         if (IEEE80211_IS_CHAN_2GHZ(c))
 2742                 otus_write(sc, AR_PWR_REG_PLL_ADDAC, 0x5163);
 2743         else
 2744                 otus_write(sc, AR_PWR_REG_PLL_ADDAC, 0x5143);
 2745 
 2746         return otus_write_barrier(sc);
 2747 }
 2748 
 2749 static __inline uint8_t
 2750 otus_reverse_bits(uint8_t v)
 2751 {
 2752         v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
 2753         v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
 2754         v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
 2755         return v;
 2756 }
 2757 
 2758 int
 2759 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c)
 2760 {
 2761         uint8_t chansel, d0, d1;
 2762         uint16_t data;
 2763         int error;
 2764 
 2765         OTUS_LOCK_ASSERT(sc);
 2766 
 2767         d0 = 0;
 2768         if (IEEE80211_IS_CHAN_5GHZ(c)) {
 2769                 chansel = (c->ic_freq - 4800) / 5;
 2770                 if (chansel & 1)
 2771                         d0 |= AR_BANK4_AMODE_REFSEL(2);
 2772                 else
 2773                         d0 |= AR_BANK4_AMODE_REFSEL(1);
 2774         } else {
 2775                 d0 |= AR_BANK4_AMODE_REFSEL(2);
 2776                 if (c->ic_freq == 2484) {       /* CH 14 */
 2777                         d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ;
 2778                         chansel = 10 + (c->ic_freq - 2274) / 5;
 2779                 } else
 2780                         chansel = 16 + (c->ic_freq - 2272) / 5;
 2781                 chansel <<= 2;
 2782         }
 2783         d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP;
 2784         d1 = otus_reverse_bits(chansel);
 2785 
 2786         /* Write bits 0-4 of d0 and d1. */
 2787         data = (d1 & 0x1f) << 5 | (d0 & 0x1f);
 2788         otus_write(sc, AR_PHY(44), data);
 2789         /* Write bits 5-7 of d0 and d1. */
 2790         data = (d1 >> 5) << 5 | (d0 >> 5);
 2791         otus_write(sc, AR_PHY(58), data);
 2792 
 2793         if ((error = otus_write_barrier(sc)) == 0)
 2794                 otus_delay_ms(sc, 10);
 2795         return error;
 2796 }
 2797 
 2798 void
 2799 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa)
 2800 {
 2801 #define COEFF_SCALE_SHIFT       24
 2802         uint32_t exp, man;
 2803 
 2804         /* exponent = 14 - floor(log2(coeff)) */
 2805         for (exp = 31; exp > 0; exp--)
 2806                 if (coeff & (1 << exp))
 2807                         break;
 2808         KASSERT(exp != 0, ("exp"));
 2809         exp = 14 - (exp - COEFF_SCALE_SHIFT);
 2810 
 2811         /* mantissa = floor(coeff * 2^exponent + 0.5) */
 2812         man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1));
 2813 
 2814         *mantissa = man >> (COEFF_SCALE_SHIFT - exp);
 2815         *exponent = exp - 16;
 2816 #undef COEFF_SCALE_SHIFT
 2817 }
 2818 
 2819 static int
 2820 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc)
 2821 {
 2822         struct ieee80211com *ic = &sc->sc_ic;
 2823         struct ar_cmd_frequency cmd;
 2824         struct ar_rsp_frequency rsp;
 2825         const uint32_t *vals;
 2826         uint32_t coeff, exp, man, tmp;
 2827         uint8_t code;
 2828         int error, chan, i;
 2829 
 2830         error = 0;
 2831         chan = ieee80211_chan2ieee(ic, c);
 2832 
 2833         OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
 2834             "setting channel %d (%dMHz)\n", chan, c->ic_freq);
 2835 
 2836         tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104;
 2837         otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp);
 2838         if ((error = otus_write_barrier(sc)) != 0)
 2839                 goto finish;
 2840 
 2841         /* Disable BB Heavy Clip. */
 2842         otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200);
 2843         if ((error = otus_write_barrier(sc)) != 0)
 2844                 goto finish;
 2845 
 2846         /* XXX Is that FREQ_START ? */
 2847         error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL, 0);
 2848         if (error != 0)
 2849                 goto finish;
 2850 
 2851         /* Reprogram PHY and RF on channel band or bandwidth changes. */
 2852         if (sc->bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) {
 2853                 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "band switch\n");
 2854 
 2855                 /* Cold/Warm reset BB/ADDA. */
 2856                 otus_write(sc, AR_PWR_REG_RESET, sc->bb_reset ? 0x800 : 0x400);
 2857                 if ((error = otus_write_barrier(sc)) != 0)
 2858                         goto finish;
 2859                 otus_write(sc, AR_PWR_REG_RESET, 0);
 2860                 if ((error = otus_write_barrier(sc)) != 0)
 2861                         goto finish;
 2862                 sc->bb_reset = 0;
 2863 
 2864                 if ((error = otus_program_phy(sc, c)) != 0) {
 2865                         device_printf(sc->sc_dev,
 2866                             "%s: could not program PHY\n",
 2867                             __func__);
 2868                         goto finish;
 2869                 }
 2870 
 2871                 /* Select RF programming based on band. */
 2872                 if (IEEE80211_IS_CHAN_5GHZ(c))
 2873                         vals = ar5416_banks_vals_5ghz;
 2874                 else
 2875                         vals = ar5416_banks_vals_2ghz;
 2876                 for (i = 0; i < nitems(ar5416_banks_regs); i++)
 2877                         otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]);
 2878                 if ((error = otus_write_barrier(sc)) != 0) {
 2879                         device_printf(sc->sc_dev,
 2880                             "%s: could not program RF\n",
 2881                             __func__);
 2882                         goto finish;
 2883                 }
 2884                 code = AR_CMD_RF_INIT;
 2885         } else {
 2886                 code = AR_CMD_FREQUENCY;
 2887         }
 2888 
 2889         if ((error = otus_set_rf_bank4(sc, c)) != 0)
 2890                 goto finish;
 2891 
 2892         tmp = (sc->txmask == 0x5) ? 0x340 : 0x240;
 2893         otus_write(sc, AR_PHY_TURBO, tmp);
 2894         if ((error = otus_write_barrier(sc)) != 0)
 2895                 goto finish;
 2896 
 2897         /* Send firmware command to set channel. */
 2898         cmd.freq = htole32((uint32_t)c->ic_freq * 1000);
 2899         cmd.dynht2040 = htole32(0);
 2900         cmd.htena = htole32(1);
 2901         /* Set Delta Slope (exponent and mantissa). */
 2902         coeff = (100 << 24) / c->ic_freq;
 2903         otus_get_delta_slope(coeff, &exp, &man);
 2904         cmd.dsc_exp = htole32(exp);
 2905         cmd.dsc_man = htole32(man);
 2906         OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
 2907             "ds coeff=%u exp=%u man=%u\n", coeff, exp, man);
 2908         /* For Short GI, coeff is 9/10 that of normal coeff. */
 2909         coeff = (9 * coeff) / 10;
 2910         otus_get_delta_slope(coeff, &exp, &man);
 2911         cmd.dsc_shgi_exp = htole32(exp);
 2912         cmd.dsc_shgi_man = htole32(man);
 2913         OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
 2914             "ds shgi coeff=%u exp=%u man=%u\n", coeff, exp, man);
 2915         /* Set wait time for AGC and noise calibration (100 or 200ms). */
 2916         cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000);
 2917         OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
 2918             "%s\n", (code == AR_CMD_RF_INIT) ? "RF_INIT" : "FREQUENCY");
 2919         error = otus_cmd(sc, code, &cmd, sizeof cmd, &rsp, sizeof(rsp));
 2920         if (error != 0)
 2921                 goto finish;
 2922         if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) {
 2923                 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET,
 2924                     "status=0x%x\n", le32toh(rsp.status));
 2925                 /* Force cold reset on next channel. */
 2926                 sc->bb_reset = 1;
 2927         }
 2928 #ifdef USB_DEBUG
 2929         if (otus_debug & OTUS_DEBUG_RESET) {
 2930                 device_printf(sc->sc_dev, "calibration status=0x%x\n",
 2931                     le32toh(rsp.status));
 2932                 for (i = 0; i < 2; i++) {       /* 2 Rx chains */
 2933                         /* Sign-extend 9-bit NF values. */
 2934                         device_printf(sc->sc_dev,
 2935                             "noisefloor chain %d=%d\n", i,
 2936                             (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23);
 2937                         device_printf(sc->sc_dev,
 2938                             "noisefloor ext chain %d=%d\n", i,
 2939                             ((int32_t)le32toh(rsp.nf_ext[i])) >> 23);
 2940                 }
 2941         }
 2942 #endif
 2943         for (i = 0; i < OTUS_NUM_CHAINS; i++) {
 2944                 sc->sc_nf[i] = ((((int32_t)le32toh(rsp.nf[i])) << 4) >> 23);
 2945         }
 2946         sc->sc_curchan = c;
 2947 finish:
 2948         return (error);
 2949 }
 2950 
 2951 #ifdef notyet
 2952 int
 2953 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
 2954     struct ieee80211_key *k)
 2955 {
 2956         struct otus_softc *sc = ic->ic_softc;
 2957         struct otus_cmd_key cmd;
 2958 
 2959         /* Defer setting of WEP keys until interface is brought up. */
 2960         if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
 2961             (IFF_UP | IFF_RUNNING))
 2962                 return 0;
 2963 
 2964         /* Do it in a process context. */
 2965         cmd.key = *k;
 2966         cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
 2967         otus_do_async(sc, otus_set_key_cb, &cmd, sizeof cmd);
 2968         return 0;
 2969 }
 2970 
 2971 void
 2972 otus_set_key_cb(struct otus_softc *sc, void *arg)
 2973 {
 2974         struct otus_cmd_key *cmd = arg;
 2975         struct ieee80211_key *k = &cmd->key;
 2976         struct ar_cmd_ekey key;
 2977         uint16_t cipher;
 2978         int error;
 2979 
 2980         memset(&key, 0, sizeof key);
 2981         if (k->k_flags & IEEE80211_KEY_GROUP) {
 2982                 key.uid = htole16(k->k_id);
 2983                 IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr);
 2984                 key.macaddr[0] |= 0x80;
 2985         } else {
 2986                 key.uid = htole16(OTUS_UID(cmd->associd));
 2987                 IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr);
 2988         }
 2989         key.kix = htole16(0);
 2990         /* Map net80211 cipher to hardware. */
 2991         switch (k->k_cipher) {
 2992         case IEEE80211_CIPHER_WEP40:
 2993                 cipher = AR_CIPHER_WEP64;
 2994                 break;
 2995         case IEEE80211_CIPHER_WEP104:
 2996                 cipher = AR_CIPHER_WEP128;
 2997                 break;
 2998         case IEEE80211_CIPHER_TKIP:
 2999                 cipher = AR_CIPHER_TKIP;
 3000                 break;
 3001         case IEEE80211_CIPHER_CCMP:
 3002                 cipher = AR_CIPHER_AES;
 3003                 break;
 3004         default:
 3005                 return;
 3006         }
 3007         key.cipher = htole16(cipher);
 3008         memcpy(key.key, k->k_key, MIN(k->k_len, 16));
 3009         error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0);
 3010         if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
 3011                 return;
 3012 
 3013         /* TKIP: set Tx/Rx MIC Key. */
 3014         key.kix = htole16(1);
 3015         memcpy(key.key, k->k_key + 16, 16);
 3016         (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0);
 3017 }
 3018 
 3019 void
 3020 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
 3021     struct ieee80211_key *k)
 3022 {
 3023         struct otus_softc *sc = ic->ic_softc;
 3024         struct otus_cmd_key cmd;
 3025 
 3026         if (!(ic->ic_if.if_flags & IFF_RUNNING) ||
 3027             ic->ic_state != IEEE80211_S_RUN)
 3028                 return; /* Nothing to do. */
 3029 
 3030         /* Do it in a process context. */
 3031         cmd.key = *k;
 3032         cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
 3033         otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof cmd);
 3034 }
 3035 
 3036 void
 3037 otus_delete_key_cb(struct otus_softc *sc, void *arg)
 3038 {
 3039         struct otus_cmd_key *cmd = arg;
 3040         struct ieee80211_key *k = &cmd->key;
 3041         uint32_t uid;
 3042 
 3043         if (k->k_flags & IEEE80211_KEY_GROUP)
 3044                 uid = htole32(k->k_id);
 3045         else
 3046                 uid = htole32(OTUS_UID(cmd->associd));
 3047         (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof uid, NULL, 0);
 3048 }
 3049 #endif
 3050 
 3051 /*
 3052  * XXX TODO: check if we have to be doing any calibration in the host
 3053  * or whether it's purely a firmware thing.
 3054  */
 3055 void
 3056 otus_calibrate_to(void *arg, int pending)
 3057 {
 3058 #if 0
 3059         struct otus_softc *sc = arg;
 3060 
 3061         device_printf(sc->sc_dev, "%s: called\n", __func__);
 3062         struct ieee80211com *ic = &sc->sc_ic;
 3063         struct ieee80211_node *ni;
 3064         int s;
 3065 
 3066         if (usbd_is_dying(sc->sc_udev))
 3067                 return;
 3068 
 3069         usbd_ref_incr(sc->sc_udev);
 3070 
 3071         s = splnet();
 3072         ni = ic->ic_bss;
 3073         ieee80211_amrr_choose(&sc->amrr, ni, &((struct otus_node *)ni)->amn);
 3074         splx(s);
 3075 
 3076         if (!usbd_is_dying(sc->sc_udev))
 3077                 timeout_add_sec(&sc->calib_to, 1);
 3078 
 3079         usbd_ref_decr(sc->sc_udev);
 3080 #endif
 3081 }
 3082 
 3083 int
 3084 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid)
 3085 {
 3086 
 3087         OTUS_LOCK_ASSERT(sc);
 3088 
 3089         otus_write(sc, AR_MAC_REG_BSSID_L,
 3090             bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
 3091         otus_write(sc, AR_MAC_REG_BSSID_H,
 3092             bssid[4] | bssid[5] << 8);
 3093         return otus_write_barrier(sc);
 3094 }
 3095 
 3096 int
 3097 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr)
 3098 {
 3099         OTUS_LOCK_ASSERT(sc);
 3100 
 3101         otus_write(sc, AR_MAC_REG_MAC_ADDR_L,
 3102             addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
 3103         otus_write(sc, AR_MAC_REG_MAC_ADDR_H,
 3104             addr[4] | addr[5] << 8);
 3105         return otus_write_barrier(sc);
 3106 }
 3107 
 3108 /* Default single-LED. */
 3109 void
 3110 otus_led_newstate_type1(struct otus_softc *sc)
 3111 {
 3112         /* TBD */
 3113         device_printf(sc->sc_dev, "%s: TODO\n", __func__);
 3114 }
 3115 
 3116 /* NETGEAR, dual-LED. */
 3117 void
 3118 otus_led_newstate_type2(struct otus_softc *sc)
 3119 {
 3120         /* TBD */
 3121         device_printf(sc->sc_dev, "%s: TODO\n", __func__);
 3122 }
 3123 
 3124 /* NETGEAR, single-LED/3 colors (blue, red, purple.) */
 3125 void
 3126 otus_led_newstate_type3(struct otus_softc *sc)
 3127 {
 3128 #if 0
 3129         struct ieee80211com *ic = &sc->sc_ic;
 3130         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 3131 
 3132         uint32_t state = sc->led_state;
 3133 
 3134         OTUS_LOCK_ASSERT(sc);
 3135 
 3136         if (!vap) {
 3137                 state = 0;      /* led off */
 3138         } else if (vap->iv_state == IEEE80211_S_INIT) {
 3139                 state = 0;      /* LED off. */
 3140         } else if (vap->iv_state == IEEE80211_S_RUN) {
 3141                 /* Associated, LED always on. */
 3142                 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan))
 3143                         state = AR_LED0_ON;     /* 2GHz=>Red. */
 3144                 else
 3145                         state = AR_LED1_ON;     /* 5GHz=>Blue. */
 3146         } else {
 3147                 /* Scanning, blink LED. */
 3148                 state ^= AR_LED0_ON | AR_LED1_ON;
 3149                 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan))
 3150                         state &= ~AR_LED1_ON;
 3151                 else
 3152                         state &= ~AR_LED0_ON;
 3153         }
 3154         if (state != sc->led_state) {
 3155                 otus_write(sc, AR_GPIO_REG_PORT_DATA, state);
 3156                 if (otus_write_barrier(sc) == 0)
 3157                         sc->led_state = state;
 3158         }
 3159 #endif
 3160 }
 3161 
 3162 static uint8_t zero_macaddr[IEEE80211_ADDR_LEN] = { 0,0,0,0,0,0 };
 3163 
 3164 /*
 3165  * Set up operating mode, MAC/BSS address and RX filter.
 3166  */
 3167 static void
 3168 otus_set_operating_mode(struct otus_softc *sc)
 3169 {
 3170         struct ieee80211com *ic = &sc->sc_ic;
 3171         struct ieee80211vap *vap;
 3172         uint32_t cam_mode = AR_MAC_CAM_DEFAULTS;
 3173         uint32_t rx_ctrl = AR_MAC_RX_CTRL_DEAGG | AR_MAC_RX_CTRL_SHORT_FILTER;
 3174         uint32_t sniffer = AR_MAC_SNIFFER_DEFAULTS;
 3175         uint32_t enc_mode = 0x78; /* XXX */
 3176         const uint8_t *macaddr;
 3177         uint8_t bssid[IEEE80211_ADDR_LEN];
 3178         struct ieee80211_node *ni;
 3179 
 3180         OTUS_LOCK_ASSERT(sc);
 3181 
 3182         /*
 3183          * If we're in sniffer mode or we don't have a MAC
 3184          * address assigned, ensure it gets reset to all-zero.
 3185          */
 3186         IEEE80211_ADDR_COPY(bssid, zero_macaddr);
 3187         vap = TAILQ_FIRST(&ic->ic_vaps);
 3188         macaddr = vap ? vap->iv_myaddr : ic->ic_macaddr;
 3189 
 3190         switch (ic->ic_opmode) {
 3191         case IEEE80211_M_STA:
 3192                 if (vap) {
 3193                         ni = ieee80211_ref_node(vap->iv_bss);
 3194                         IEEE80211_ADDR_COPY(bssid, ni->ni_bssid);
 3195                         ieee80211_free_node(ni);
 3196                 }
 3197                 cam_mode |= AR_MAC_CAM_STA;
 3198                 rx_ctrl |= AR_MAC_RX_CTRL_PASS_TO_HOST;
 3199                 break;
 3200         case IEEE80211_M_MONITOR:
 3201                 /*
 3202                  * Note: monitor mode ends up causing the MAC to
 3203                  * generate ACK frames for everything it sees.
 3204                  * So don't do that; instead just put it in STA mode
 3205                  * and disable RX filters.
 3206                  */
 3207         default:
 3208                 cam_mode |= AR_MAC_CAM_STA;
 3209                 rx_ctrl |= AR_MAC_RX_CTRL_PASS_TO_HOST;
 3210                 break;
 3211         }
 3212 
 3213         /*
 3214          * TODO: if/when we do hardware encryption, ensure it's
 3215          * disabled if the NIC is in monitor mode.
 3216          */
 3217         otus_write(sc, AR_MAC_REG_SNIFFER, sniffer);
 3218         otus_write(sc, AR_MAC_REG_CAM_MODE, cam_mode);
 3219         otus_write(sc, AR_MAC_REG_ENCRYPTION, enc_mode);
 3220         otus_write(sc, AR_MAC_REG_RX_CONTROL, rx_ctrl);
 3221         otus_set_macaddr(sc, macaddr);
 3222         otus_set_bssid(sc, bssid);
 3223         /* XXX barrier? */
 3224 }
 3225 
 3226 static void
 3227 otus_set_rx_filter(struct otus_softc *sc)
 3228 {
 3229 //      struct ieee80211com *ic = &sc->sc_ic;
 3230 
 3231         OTUS_LOCK_ASSERT(sc);
 3232 
 3233 #if 0
 3234         if (ic->ic_allmulti > 0 || ic->ic_promisc > 0 ||
 3235             ic->ic_opmode == IEEE80211_M_MONITOR) {
 3236                 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, 0xff00ffff);
 3237         } else {
 3238 #endif
 3239                 /* Filter any control frames, BAR is bit 24. */
 3240                 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, 0x0500ffff);
 3241 #if 0
 3242         }
 3243 #endif
 3244 }
 3245 
 3246 int
 3247 otus_init(struct otus_softc *sc)
 3248 {
 3249         struct ieee80211com *ic = &sc->sc_ic;
 3250         int error;
 3251 
 3252         OTUS_UNLOCK_ASSERT(sc);
 3253 
 3254         OTUS_LOCK(sc);
 3255 
 3256         /* Drain any pending TX frames */
 3257         otus_drain_mbufq(sc);
 3258 
 3259         /* Init MAC */
 3260         if ((error = otus_init_mac(sc)) != 0) {
 3261                 OTUS_UNLOCK(sc);
 3262                 device_printf(sc->sc_dev,
 3263                     "%s: could not initialize MAC\n", __func__);
 3264                 return error;
 3265         }
 3266 
 3267         otus_set_operating_mode(sc);
 3268         otus_set_rx_filter(sc);
 3269         (void) otus_set_operating_mode(sc);
 3270 
 3271         sc->bb_reset = 1;       /* Force cold reset. */
 3272 
 3273         if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) {
 3274                 OTUS_UNLOCK(sc);
 3275                 device_printf(sc->sc_dev,
 3276                     "%s: could not set channel\n", __func__);
 3277                 return error;
 3278         }
 3279 
 3280         /* Start Rx. */
 3281         otus_write(sc, AR_MAC_REG_DMA_TRIGGER, 0x100);
 3282         (void)otus_write_barrier(sc);
 3283 
 3284         sc->sc_running = 1;
 3285 
 3286         OTUS_UNLOCK(sc);
 3287         return 0;
 3288 }
 3289 
 3290 void
 3291 otus_stop(struct otus_softc *sc)
 3292 {
 3293 #if 0
 3294         int s;
 3295 #endif
 3296 
 3297         OTUS_UNLOCK_ASSERT(sc);
 3298 
 3299         OTUS_LOCK(sc);
 3300         sc->sc_running = 0;
 3301         sc->sc_tx_timer = 0;
 3302         OTUS_UNLOCK(sc);
 3303 
 3304         taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to);
 3305         taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to);
 3306         taskqueue_drain(taskqueue_thread, &sc->tx_task);
 3307 
 3308         OTUS_LOCK(sc);
 3309         sc->sc_running = 0;
 3310         /* Stop Rx. */
 3311         otus_write(sc, AR_MAC_REG_DMA_TRIGGER, 0);
 3312         (void)otus_write_barrier(sc);
 3313 
 3314         /* Drain any pending TX frames */
 3315         otus_drain_mbufq(sc);
 3316 
 3317         OTUS_UNLOCK(sc);
 3318 }

Cache object: 47f3a9b5c2b3e0b1bd24f953da22cec6


[ 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.