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/malo/if_malo.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 /*-
    2  * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org>
    3  * Copyright (c) 2007 Marvell Semiconductor, Inc.
    4  * Copyright (c) 2007 Sam Leffler, Errno Consulting
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer,
   12  *    without modification.
   13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   15  *    redistribution must be conditioned upon including a substantially
   16  *    similar Disclaimer requirement for further binary redistribution.
   17  *
   18  * NO WARRANTY
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   29  * THE POSSIBILITY OF SUCH DAMAGES.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 #ifdef __FreeBSD__
   34 __FBSDID("$FreeBSD: releng/11.0/sys/dev/malo/if_malo.c 298818 2016-04-29 22:14:11Z avos $");
   35 #endif
   36 
   37 #include "opt_malo.h"
   38 
   39 #include <sys/param.h>
   40 #include <sys/endian.h>
   41 #include <sys/kernel.h>
   42 #include <sys/malloc.h>
   43 #include <sys/socket.h>
   44 #include <sys/sockio.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/taskqueue.h>
   47 
   48 #include <machine/bus.h>
   49 #include <sys/bus.h>
   50 
   51 #include <net/if.h>
   52 #include <net/if_var.h>
   53 #include <net/if_dl.h>
   54 #include <net/if_media.h>
   55 #include <net/if_types.h>
   56 #include <net/ethernet.h>
   57 
   58 #include <net80211/ieee80211_var.h>
   59 #include <net80211/ieee80211_regdomain.h>
   60 
   61 #include <net/bpf.h>
   62 
   63 #include <dev/malo/if_malo.h>
   64 
   65 SYSCTL_NODE(_hw, OID_AUTO, malo, CTLFLAG_RD, 0,
   66     "Marvell 88w8335 driver parameters");
   67 
   68 static  int malo_txcoalesce = 8;        /* # tx pkts to q before poking f/w*/
   69 SYSCTL_INT(_hw_malo, OID_AUTO, txcoalesce, CTLFLAG_RWTUN, &malo_txcoalesce,
   70             0, "tx buffers to send at once");
   71 static  int malo_rxbuf = MALO_RXBUF;            /* # rx buffers to allocate */
   72 SYSCTL_INT(_hw_malo, OID_AUTO, rxbuf, CTLFLAG_RWTUN, &malo_rxbuf,
   73             0, "rx buffers allocated");
   74 static  int malo_rxquota = MALO_RXBUF;          /* # max buffers to process */
   75 SYSCTL_INT(_hw_malo, OID_AUTO, rxquota, CTLFLAG_RWTUN, &malo_rxquota,
   76             0, "max rx buffers to process per interrupt");
   77 static  int malo_txbuf = MALO_TXBUF;            /* # tx buffers to allocate */
   78 SYSCTL_INT(_hw_malo, OID_AUTO, txbuf, CTLFLAG_RWTUN, &malo_txbuf,
   79             0, "tx buffers allocated");
   80 
   81 #ifdef MALO_DEBUG
   82 static  int malo_debug = 0;
   83 SYSCTL_INT(_hw_malo, OID_AUTO, debug, CTLFLAG_RWTUN, &malo_debug,
   84             0, "control debugging printfs");
   85 enum {
   86         MALO_DEBUG_XMIT         = 0x00000001,   /* basic xmit operation */
   87         MALO_DEBUG_XMIT_DESC    = 0x00000002,   /* xmit descriptors */
   88         MALO_DEBUG_RECV         = 0x00000004,   /* basic recv operation */
   89         MALO_DEBUG_RECV_DESC    = 0x00000008,   /* recv descriptors */
   90         MALO_DEBUG_RESET        = 0x00000010,   /* reset processing */
   91         MALO_DEBUG_INTR         = 0x00000040,   /* ISR */
   92         MALO_DEBUG_TX_PROC      = 0x00000080,   /* tx ISR proc */
   93         MALO_DEBUG_RX_PROC      = 0x00000100,   /* rx ISR proc */
   94         MALO_DEBUG_STATE        = 0x00000400,   /* 802.11 state transitions */
   95         MALO_DEBUG_NODE         = 0x00000800,   /* node management */
   96         MALO_DEBUG_RECV_ALL     = 0x00001000,   /* trace all frames (beacons) */
   97         MALO_DEBUG_FW           = 0x00008000,   /* firmware */
   98         MALO_DEBUG_ANY          = 0xffffffff
   99 };
  100 #define IS_BEACON(wh)                                                   \
  101         ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK |                      \
  102                 IEEE80211_FC0_SUBTYPE_MASK)) ==                         \
  103          (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
  104 #define IFF_DUMPPKTS_RECV(sc, wh)                                       \
  105         (((sc->malo_debug & MALO_DEBUG_RECV) &&                         \
  106           ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))))
  107 #define IFF_DUMPPKTS_XMIT(sc)                                           \
  108         (sc->malo_debug & MALO_DEBUG_XMIT)
  109 #define DPRINTF(sc, m, fmt, ...) do {                           \
  110         if (sc->malo_debug & (m))                               \
  111                 printf(fmt, __VA_ARGS__);                       \
  112 } while (0)
  113 #else
  114 #define DPRINTF(sc, m, fmt, ...) do {                           \
  115         (void) sc;                                              \
  116 } while (0)
  117 #endif
  118 
  119 static MALLOC_DEFINE(M_MALODEV, "malodev", "malo driver dma buffers");
  120 
  121 static struct ieee80211vap *malo_vap_create(struct ieee80211com *,
  122                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
  123                     const uint8_t [IEEE80211_ADDR_LEN],
  124                     const uint8_t [IEEE80211_ADDR_LEN]);
  125 static  void    malo_vap_delete(struct ieee80211vap *);
  126 static  int     malo_dma_setup(struct malo_softc *);
  127 static  int     malo_setup_hwdma(struct malo_softc *);
  128 static  void    malo_txq_init(struct malo_softc *, struct malo_txq *, int);
  129 static  void    malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
  130 static  void    malo_parent(struct ieee80211com *);
  131 static  int     malo_transmit(struct ieee80211com *, struct mbuf *);
  132 static  void    malo_start(struct malo_softc *);
  133 static  void    malo_watchdog(void *);
  134 static  void    malo_updateslot(struct ieee80211com *);
  135 static  int     malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
  136 static  void    malo_scan_start(struct ieee80211com *);
  137 static  void    malo_scan_end(struct ieee80211com *);
  138 static  void    malo_set_channel(struct ieee80211com *);
  139 static  int     malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
  140                     const struct ieee80211_bpf_params *);
  141 static  void    malo_sysctlattach(struct malo_softc *);
  142 static  void    malo_announce(struct malo_softc *);
  143 static  void    malo_dma_cleanup(struct malo_softc *);
  144 static  void    malo_stop(struct malo_softc *);
  145 static  int     malo_chan_set(struct malo_softc *, struct ieee80211_channel *);
  146 static  int     malo_mode_init(struct malo_softc *);
  147 static  void    malo_tx_proc(void *, int);
  148 static  void    malo_rx_proc(void *, int);
  149 static  void    malo_init(void *);
  150 
  151 /*
  152  * Read/Write shorthands for accesses to BAR 0.  Note that all BAR 1
  153  * operations are done in the "hal" except getting H/W MAC address at
  154  * malo_attach and there should be no reference to them here.
  155  */
  156 static uint32_t
  157 malo_bar0_read4(struct malo_softc *sc, bus_size_t off)
  158 {
  159         return bus_space_read_4(sc->malo_io0t, sc->malo_io0h, off);
  160 }
  161 
  162 static void
  163 malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val)
  164 {
  165         DPRINTF(sc, MALO_DEBUG_FW, "%s: off 0x%jx val 0x%x\n",
  166             __func__, (uintmax_t)off, val);
  167 
  168         bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val);
  169 }
  170 
  171 int
  172 malo_attach(uint16_t devid, struct malo_softc *sc)
  173 {
  174         struct ieee80211com *ic = &sc->malo_ic;
  175         struct malo_hal *mh;
  176         int error;
  177         uint8_t bands[IEEE80211_MODE_BYTES];
  178 
  179         MALO_LOCK_INIT(sc);
  180         callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
  181         mbufq_init(&sc->malo_snd, ifqmaxlen);
  182 
  183         mh = malo_hal_attach(sc->malo_dev, devid,
  184             sc->malo_io1h, sc->malo_io1t, sc->malo_dmat);
  185         if (mh == NULL) {
  186                 device_printf(sc->malo_dev, "unable to attach HAL\n");
  187                 error = EIO;
  188                 goto bad;
  189         }
  190         sc->malo_mh = mh;
  191 
  192         /*
  193          * Load firmware so we can get setup.  We arbitrarily pick station
  194          * firmware; we'll re-load firmware as needed so setting up
  195          * the wrong mode isn't a big deal.
  196          */
  197         error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m");
  198         if (error != 0) {
  199                 device_printf(sc->malo_dev, "unable to setup firmware\n");
  200                 goto bad1;
  201         }
  202         /* XXX gethwspecs() extracts correct informations?  not maybe!  */
  203         error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs);
  204         if (error != 0) {
  205                 device_printf(sc->malo_dev, "unable to fetch h/w specs\n");
  206                 goto bad1;
  207         }
  208 
  209         DPRINTF(sc, MALO_DEBUG_FW,
  210             "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x"
  211             "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x"
  212             "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x"
  213             "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x"
  214             "ul_fw_awakecookie 0x%x w[4] = %x %x %x %x",
  215             sc->malo_hwspecs.hwversion,
  216             sc->malo_hwspecs.hostinterface, sc->malo_hwspecs.maxnum_wcb,
  217             sc->malo_hwspecs.maxnum_mcaddr, sc->malo_hwspecs.maxnum_tx_wcb,
  218             sc->malo_hwspecs.regioncode, sc->malo_hwspecs.num_antenna,
  219             sc->malo_hwspecs.fw_releasenum, sc->malo_hwspecs.wcbbase0,
  220             sc->malo_hwspecs.rxdesc_read, sc->malo_hwspecs.rxdesc_write,
  221             sc->malo_hwspecs.ul_fw_awakecookie,
  222             sc->malo_hwspecs.wcbbase[0], sc->malo_hwspecs.wcbbase[1],
  223             sc->malo_hwspecs.wcbbase[2], sc->malo_hwspecs.wcbbase[3]);
  224 
  225         /* NB: firmware looks that it does not export regdomain info API.  */
  226         memset(bands, 0, sizeof(bands));
  227         setbit(bands, IEEE80211_MODE_11B);
  228         setbit(bands, IEEE80211_MODE_11G);
  229         ieee80211_init_channels(ic, NULL, bands);
  230 
  231         sc->malo_txantenna = 0x2;       /* h/w default */
  232         sc->malo_rxantenna = 0xffff;    /* h/w default */
  233 
  234         /*
  235          * Allocate tx + rx descriptors and populate the lists.
  236          * We immediately push the information to the firmware
  237          * as otherwise it gets upset.
  238          */
  239         error = malo_dma_setup(sc);
  240         if (error != 0) {
  241                 device_printf(sc->malo_dev,
  242                     "failed to setup descriptors: %d\n", error);
  243                 goto bad1;
  244         }
  245         error = malo_setup_hwdma(sc);   /* push to firmware */
  246         if (error != 0)                 /* NB: malo_setupdma prints msg */
  247                 goto bad2;
  248 
  249         sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT,
  250                 taskqueue_thread_enqueue, &sc->malo_tq);
  251         taskqueue_start_threads(&sc->malo_tq, 1, PI_NET,
  252                 "%s taskq", device_get_nameunit(sc->malo_dev));
  253 
  254         TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc);
  255         TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc);
  256 
  257         ic->ic_softc = sc;
  258         ic->ic_name = device_get_nameunit(sc->malo_dev);
  259         /* XXX not right but it's not used anywhere important */
  260         ic->ic_phytype = IEEE80211_T_OFDM;
  261         ic->ic_opmode = IEEE80211_M_STA;
  262         ic->ic_caps =
  263               IEEE80211_C_STA                   /* station mode supported */
  264             | IEEE80211_C_BGSCAN                /* capable of bg scanning */
  265             | IEEE80211_C_MONITOR               /* monitor mode */
  266             | IEEE80211_C_SHPREAMBLE            /* short preamble supported */
  267             | IEEE80211_C_SHSLOT                /* short slot time supported */
  268             | IEEE80211_C_TXPMGT                /* capable of txpow mgt */
  269             | IEEE80211_C_WPA                   /* capable of WPA1+WPA2 */
  270             ;
  271         IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr);
  272 
  273         /*
  274          * Transmit requires space in the packet for a special format transmit
  275          * record and optional padding between this record and the payload.
  276          * Ask the net80211 layer to arrange this when encapsulating
  277          * packets so we can add it efficiently. 
  278          */
  279         ic->ic_headroom = sizeof(struct malo_txrec) -
  280                 sizeof(struct ieee80211_frame);
  281 
  282         /* call MI attach routine. */
  283         ieee80211_ifattach(ic);
  284         /* override default methods */
  285         ic->ic_vap_create = malo_vap_create;
  286         ic->ic_vap_delete = malo_vap_delete;
  287         ic->ic_raw_xmit = malo_raw_xmit;
  288         ic->ic_updateslot = malo_updateslot;
  289         ic->ic_scan_start = malo_scan_start;
  290         ic->ic_scan_end = malo_scan_end;
  291         ic->ic_set_channel = malo_set_channel;
  292         ic->ic_parent = malo_parent;
  293         ic->ic_transmit = malo_transmit;
  294 
  295         sc->malo_invalid = 0;           /* ready to go, enable int handling */
  296 
  297         ieee80211_radiotap_attach(ic,
  298             &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th),
  299                 MALO_TX_RADIOTAP_PRESENT,
  300             &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th),
  301                 MALO_RX_RADIOTAP_PRESENT);
  302 
  303         /*
  304          * Setup dynamic sysctl's.
  305          */
  306         malo_sysctlattach(sc);
  307 
  308         if (bootverbose)
  309                 ieee80211_announce(ic);
  310         malo_announce(sc);
  311 
  312         return 0;
  313 bad2:
  314         malo_dma_cleanup(sc);
  315 bad1:
  316         malo_hal_detach(mh);
  317 bad:
  318         sc->malo_invalid = 1;
  319 
  320         return error;
  321 }
  322 
  323 static struct ieee80211vap *
  324 malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
  325     enum ieee80211_opmode opmode, int flags,
  326     const uint8_t bssid[IEEE80211_ADDR_LEN],
  327     const uint8_t mac[IEEE80211_ADDR_LEN])
  328 {
  329         struct malo_softc *sc = ic->ic_softc;
  330         struct malo_vap *mvp;
  331         struct ieee80211vap *vap;
  332 
  333         if (!TAILQ_EMPTY(&ic->ic_vaps)) {
  334                 device_printf(sc->malo_dev, "multiple vaps not supported\n");
  335                 return NULL;
  336         }
  337         switch (opmode) {
  338         case IEEE80211_M_STA:
  339                 if (opmode == IEEE80211_M_STA)
  340                         flags |= IEEE80211_CLONE_NOBEACONS;
  341                 /* fall thru... */
  342         case IEEE80211_M_MONITOR:
  343                 break;
  344         default:
  345                 device_printf(sc->malo_dev, "%s mode not supported\n",
  346                     ieee80211_opmode_name[opmode]);
  347                 return NULL;            /* unsupported */
  348         }
  349         mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO);
  350         vap = &mvp->malo_vap;
  351         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
  352 
  353         /* override state transition machine */
  354         mvp->malo_newstate = vap->iv_newstate;
  355         vap->iv_newstate = malo_newstate;
  356 
  357         /* complete setup */
  358         ieee80211_vap_attach(vap,
  359             ieee80211_media_change, ieee80211_media_status, mac);
  360         ic->ic_opmode = opmode;
  361         return vap;
  362 }
  363 
  364 static void
  365 malo_vap_delete(struct ieee80211vap *vap)
  366 {
  367         struct malo_vap *mvp = MALO_VAP(vap);
  368 
  369         ieee80211_vap_detach(vap);
  370         free(mvp, M_80211_VAP);
  371 }
  372 
  373 int
  374 malo_intr(void *arg)
  375 {
  376         struct malo_softc *sc = arg;
  377         struct malo_hal *mh = sc->malo_mh;
  378         uint32_t status;
  379 
  380         if (sc->malo_invalid) {
  381                 /*
  382                  * The hardware is not ready/present, don't touch anything.
  383                  * Note this can happen early on if the IRQ is shared.
  384                  */
  385                 DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid; ignored\n", __func__);
  386                 return (FILTER_STRAY);
  387         }
  388 
  389         /*
  390          * Figure out the reason(s) for the interrupt.
  391          */
  392         malo_hal_getisr(mh, &status);           /* NB: clears ISR too */
  393         if (status == 0)                        /* must be a shared irq */
  394                 return (FILTER_STRAY);
  395 
  396         DPRINTF(sc, MALO_DEBUG_INTR, "%s: status 0x%x imask 0x%x\n",
  397             __func__, status, sc->malo_imask);
  398 
  399         if (status & MALO_A2HRIC_BIT_RX_RDY)
  400                 taskqueue_enqueue(sc->malo_tq, &sc->malo_rxtask);
  401         if (status & MALO_A2HRIC_BIT_TX_DONE)
  402                 taskqueue_enqueue(sc->malo_tq, &sc->malo_txtask);
  403         if (status & MALO_A2HRIC_BIT_OPC_DONE)
  404                 malo_hal_cmddone(mh);
  405         if (status & MALO_A2HRIC_BIT_MAC_EVENT)
  406                 ;
  407         if (status & MALO_A2HRIC_BIT_RX_PROBLEM)
  408                 ;
  409         if (status & MALO_A2HRIC_BIT_ICV_ERROR) {
  410                 /* TKIP ICV error */
  411                 sc->malo_stats.mst_rx_badtkipicv++;
  412         }
  413 #ifdef MALO_DEBUG
  414         if (((status | sc->malo_imask) ^ sc->malo_imask) != 0)
  415                 DPRINTF(sc, MALO_DEBUG_INTR,
  416                     "%s: can't handle interrupt status 0x%x\n",
  417                     __func__, status);
  418 #endif
  419         return (FILTER_HANDLED);
  420 }
  421 
  422 static void
  423 malo_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
  424 {
  425         bus_addr_t *paddr = (bus_addr_t*) arg;
  426 
  427         KASSERT(error == 0, ("error %u on bus_dma callback", error));
  428 
  429         *paddr = segs->ds_addr;
  430 }
  431 
  432 static int
  433 malo_desc_setup(struct malo_softc *sc, const char *name,
  434     struct malo_descdma *dd,
  435     int nbuf, size_t bufsize, int ndesc, size_t descsize)
  436 {
  437         int error;
  438         uint8_t *ds;
  439 
  440         DPRINTF(sc, MALO_DEBUG_RESET,
  441             "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n",
  442             __func__, name, nbuf, (uintmax_t) bufsize,
  443             ndesc, (uintmax_t) descsize);
  444         
  445         dd->dd_name = name;
  446         dd->dd_desc_len = nbuf * ndesc * descsize;
  447 
  448         /*
  449          * Setup DMA descriptor area.
  450          */
  451         error = bus_dma_tag_create(bus_get_dma_tag(sc->malo_dev),/* parent */
  452                        PAGE_SIZE, 0,            /* alignment, bounds */
  453                        BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
  454                        BUS_SPACE_MAXADDR,       /* highaddr */
  455                        NULL, NULL,              /* filter, filterarg */
  456                        dd->dd_desc_len,         /* maxsize */
  457                        1,                       /* nsegments */
  458                        dd->dd_desc_len,         /* maxsegsize */
  459                        BUS_DMA_ALLOCNOW,        /* flags */
  460                        NULL,                    /* lockfunc */
  461                        NULL,                    /* lockarg */
  462                        &dd->dd_dmat);
  463         if (error != 0) {
  464                 device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n",
  465                     dd->dd_name);
  466                 return error;
  467         }
  468         
  469         /* allocate descriptors */
  470         error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
  471             BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap);
  472         if (error != 0) {
  473                 device_printf(sc->malo_dev,
  474                     "unable to alloc memory for %u %s descriptors, "
  475                     "error %u\n", nbuf * ndesc, dd->dd_name, error);
  476                 goto fail1;
  477         }
  478 
  479         error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap,
  480             dd->dd_desc, dd->dd_desc_len,
  481             malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT);
  482         if (error != 0) {
  483                 device_printf(sc->malo_dev,
  484                     "unable to map %s descriptors, error %u\n",
  485                     dd->dd_name, error);
  486                 goto fail2;
  487         }
  488         
  489         ds = dd->dd_desc;
  490         memset(ds, 0, dd->dd_desc_len);
  491         DPRINTF(sc, MALO_DEBUG_RESET,
  492             "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n",
  493             __func__, dd->dd_name, ds, (u_long) dd->dd_desc_len,
  494             (uintmax_t) dd->dd_desc_paddr, /*XXX*/ (u_long) dd->dd_desc_len);
  495 
  496         return 0;
  497 fail2:
  498         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
  499 fail1:
  500         bus_dma_tag_destroy(dd->dd_dmat);
  501         memset(dd, 0, sizeof(*dd));
  502         return error;
  503 }
  504 
  505 #define DS2PHYS(_dd, _ds) \
  506         ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
  507 
  508 static int
  509 malo_rxdma_setup(struct malo_softc *sc)
  510 {
  511         int error, bsize, i;
  512         struct malo_rxbuf *bf;
  513         struct malo_rxdesc *ds;
  514 
  515         error = malo_desc_setup(sc, "rx", &sc->malo_rxdma,
  516             malo_rxbuf, sizeof(struct malo_rxbuf),
  517             1, sizeof(struct malo_rxdesc));
  518         if (error != 0)
  519                 return error;
  520 
  521         /*
  522          * Allocate rx buffers and set them up.
  523          */
  524         bsize = malo_rxbuf * sizeof(struct malo_rxbuf);
  525         bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
  526         if (bf == NULL) {
  527                 device_printf(sc->malo_dev,
  528                     "malloc of %u rx buffers failed\n", bsize);
  529                 return error;
  530         }
  531         sc->malo_rxdma.dd_bufptr = bf;
  532         
  533         STAILQ_INIT(&sc->malo_rxbuf);
  534         ds = sc->malo_rxdma.dd_desc;
  535         for (i = 0; i < malo_rxbuf; i++, bf++, ds++) {
  536                 bf->bf_desc = ds;
  537                 bf->bf_daddr = DS2PHYS(&sc->malo_rxdma, ds);
  538                 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
  539                     &bf->bf_dmamap);
  540                 if (error != 0) {
  541                         device_printf(sc->malo_dev,
  542                             "%s: unable to dmamap for rx buffer, error %d\n",
  543                             __func__, error);
  544                         return error;
  545                 }
  546                 /* NB: tail is intentional to preserve descriptor order */
  547                 STAILQ_INSERT_TAIL(&sc->malo_rxbuf, bf, bf_list);
  548         }
  549         return 0;
  550 }
  551 
  552 static int
  553 malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
  554 {
  555         int error, bsize, i;
  556         struct malo_txbuf *bf;
  557         struct malo_txdesc *ds;
  558 
  559         error = malo_desc_setup(sc, "tx", &txq->dma,
  560             malo_txbuf, sizeof(struct malo_txbuf),
  561             MALO_TXDESC, sizeof(struct malo_txdesc));
  562         if (error != 0)
  563                 return error;
  564         
  565         /* allocate and setup tx buffers */
  566         bsize = malo_txbuf * sizeof(struct malo_txbuf);
  567         bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
  568         if (bf == NULL) {
  569                 device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n",
  570                     malo_txbuf);
  571                 return ENOMEM;
  572         }
  573         txq->dma.dd_bufptr = bf;
  574         
  575         STAILQ_INIT(&txq->free);
  576         txq->nfree = 0;
  577         ds = txq->dma.dd_desc;
  578         for (i = 0; i < malo_txbuf; i++, bf++, ds += MALO_TXDESC) {
  579                 bf->bf_desc = ds;
  580                 bf->bf_daddr = DS2PHYS(&txq->dma, ds);
  581                 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
  582                     &bf->bf_dmamap);
  583                 if (error != 0) {
  584                         device_printf(sc->malo_dev,
  585                             "unable to create dmamap for tx "
  586                             "buffer %u, error %u\n", i, error);
  587                         return error;
  588                 }
  589                 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
  590                 txq->nfree++;
  591         }
  592 
  593         return 0;
  594 }
  595 
  596 static void
  597 malo_desc_cleanup(struct malo_softc *sc, struct malo_descdma *dd)
  598 {
  599         bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap);
  600         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
  601         bus_dma_tag_destroy(dd->dd_dmat);
  602 
  603         memset(dd, 0, sizeof(*dd));
  604 }
  605 
  606 static void
  607 malo_rxdma_cleanup(struct malo_softc *sc)
  608 {
  609         struct malo_rxbuf *bf;
  610 
  611         STAILQ_FOREACH(bf, &sc->malo_rxbuf, bf_list) {
  612                 if (bf->bf_m != NULL) {
  613                         m_freem(bf->bf_m);
  614                         bf->bf_m = NULL;
  615                 }
  616                 if (bf->bf_dmamap != NULL) {
  617                         bus_dmamap_destroy(sc->malo_dmat, bf->bf_dmamap);
  618                         bf->bf_dmamap = NULL;
  619                 }
  620         }
  621         STAILQ_INIT(&sc->malo_rxbuf);
  622         if (sc->malo_rxdma.dd_bufptr != NULL) {
  623                 free(sc->malo_rxdma.dd_bufptr, M_MALODEV);
  624                 sc->malo_rxdma.dd_bufptr = NULL;
  625         }
  626         if (sc->malo_rxdma.dd_desc_len != 0)
  627                 malo_desc_cleanup(sc, &sc->malo_rxdma);
  628 }
  629 
  630 static void
  631 malo_txdma_cleanup(struct malo_softc *sc, struct malo_txq *txq)
  632 {
  633         struct malo_txbuf *bf;
  634         struct ieee80211_node *ni;
  635 
  636         STAILQ_FOREACH(bf, &txq->free, bf_list) {
  637                 if (bf->bf_m != NULL) {
  638                         m_freem(bf->bf_m);
  639                         bf->bf_m = NULL;
  640                 }
  641                 ni = bf->bf_node;
  642                 bf->bf_node = NULL;
  643                 if (ni != NULL) {
  644                         /*
  645                          * Reclaim node reference.
  646                          */
  647                         ieee80211_free_node(ni);
  648                 }
  649                 if (bf->bf_dmamap != NULL) {
  650                         bus_dmamap_destroy(sc->malo_dmat, bf->bf_dmamap);
  651                         bf->bf_dmamap = NULL;
  652                 }
  653         }
  654         STAILQ_INIT(&txq->free);
  655         txq->nfree = 0;
  656         if (txq->dma.dd_bufptr != NULL) {
  657                 free(txq->dma.dd_bufptr, M_MALODEV);
  658                 txq->dma.dd_bufptr = NULL;
  659         }
  660         if (txq->dma.dd_desc_len != 0)
  661                 malo_desc_cleanup(sc, &txq->dma);
  662 }
  663 
  664 static void
  665 malo_dma_cleanup(struct malo_softc *sc)
  666 {
  667         int i;
  668 
  669         for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
  670                 malo_txdma_cleanup(sc, &sc->malo_txq[i]);
  671 
  672         malo_rxdma_cleanup(sc);
  673 }
  674 
  675 static int
  676 malo_dma_setup(struct malo_softc *sc)
  677 {
  678         int error, i;
  679 
  680         /* rxdma initializing.  */
  681         error = malo_rxdma_setup(sc);
  682         if (error != 0)
  683                 return error;
  684 
  685         /* NB: we just have 1 tx queue now.  */
  686         for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
  687                 error = malo_txdma_setup(sc, &sc->malo_txq[i]);
  688                 if (error != 0) {
  689                         malo_dma_cleanup(sc);
  690 
  691                         return error;
  692                 }
  693 
  694                 malo_txq_init(sc, &sc->malo_txq[i], i);
  695         }
  696 
  697         return 0;
  698 }
  699 
  700 static void
  701 malo_hal_set_rxtxdma(struct malo_softc *sc)
  702 {
  703         int i;
  704 
  705         malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read,
  706             sc->malo_hwdma.rxdesc_read);
  707         malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_write,
  708             sc->malo_hwdma.rxdesc_read);
  709 
  710         for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
  711                 malo_bar0_write4(sc,
  712                     sc->malo_hwspecs.wcbbase[i], sc->malo_hwdma.wcbbase[i]);
  713         }
  714 }
  715 
  716 /*
  717  * Inform firmware of our tx/rx dma setup.  The BAR 0 writes below are
  718  * for compatibility with older firmware.  For current firmware we send
  719  * this information with a cmd block via malo_hal_sethwdma.
  720  */
  721 static int
  722 malo_setup_hwdma(struct malo_softc *sc)
  723 {
  724         int i;
  725         struct malo_txq *txq;
  726 
  727         sc->malo_hwdma.rxdesc_read = sc->malo_rxdma.dd_desc_paddr;
  728 
  729         for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
  730                 txq = &sc->malo_txq[i];
  731                 sc->malo_hwdma.wcbbase[i] = txq->dma.dd_desc_paddr;
  732         }
  733         sc->malo_hwdma.maxnum_txwcb = malo_txbuf;
  734         sc->malo_hwdma.maxnum_wcb = MALO_NUM_TX_QUEUES;
  735 
  736         malo_hal_set_rxtxdma(sc);
  737 
  738         return 0;
  739 }
  740 
  741 static void
  742 malo_txq_init(struct malo_softc *sc, struct malo_txq *txq, int qnum)
  743 {
  744         struct malo_txbuf *bf, *bn;
  745         struct malo_txdesc *ds;
  746 
  747         MALO_TXQ_LOCK_INIT(sc, txq);
  748         txq->qnum = qnum;
  749         txq->txpri = 0; /* XXX */
  750 
  751         STAILQ_FOREACH(bf, &txq->free, bf_list) {
  752                 bf->bf_txq = txq;
  753 
  754                 ds = bf->bf_desc;
  755                 bn = STAILQ_NEXT(bf, bf_list);
  756                 if (bn == NULL)
  757                         bn = STAILQ_FIRST(&txq->free);
  758                 ds->physnext = htole32(bn->bf_daddr);
  759         }
  760         STAILQ_INIT(&txq->active);
  761 }
  762 
  763 /*
  764  * Reclaim resources for a setup queue.
  765  */
  766 static void
  767 malo_tx_cleanupq(struct malo_softc *sc, struct malo_txq *txq)
  768 {
  769         /* XXX hal work? */
  770         MALO_TXQ_LOCK_DESTROY(txq);
  771 }
  772 
  773 /*
  774  * Allocate a tx buffer for sending a frame.
  775  */
  776 static struct malo_txbuf *
  777 malo_getbuf(struct malo_softc *sc, struct malo_txq *txq)
  778 {
  779         struct malo_txbuf *bf;
  780 
  781         MALO_TXQ_LOCK(txq);
  782         bf = STAILQ_FIRST(&txq->free);
  783         if (bf != NULL) {
  784                 STAILQ_REMOVE_HEAD(&txq->free, bf_list);
  785                 txq->nfree--;
  786         }
  787         MALO_TXQ_UNLOCK(txq);
  788         if (bf == NULL) {
  789                 DPRINTF(sc, MALO_DEBUG_XMIT,
  790                     "%s: out of xmit buffers on q %d\n", __func__, txq->qnum);
  791                 sc->malo_stats.mst_tx_qstop++;
  792         }
  793         return bf;
  794 }
  795 
  796 static int
  797 malo_tx_dmasetup(struct malo_softc *sc, struct malo_txbuf *bf, struct mbuf *m0)
  798 {
  799         struct mbuf *m;
  800         int error;
  801 
  802         /*
  803          * Load the DMA map so any coalescing is done.  This also calculates
  804          * the number of descriptors we need.
  805          */
  806         error = bus_dmamap_load_mbuf_sg(sc->malo_dmat, bf->bf_dmamap, m0,
  807                                      bf->bf_segs, &bf->bf_nseg,
  808                                      BUS_DMA_NOWAIT);
  809         if (error == EFBIG) {
  810                 /* XXX packet requires too many descriptors */
  811                 bf->bf_nseg = MALO_TXDESC + 1;
  812         } else if (error != 0) {
  813                 sc->malo_stats.mst_tx_busdma++;
  814                 m_freem(m0);
  815                 return error;
  816         }
  817         /*
  818          * Discard null packets and check for packets that require too many
  819          * TX descriptors.  We try to convert the latter to a cluster.
  820          */
  821         if (error == EFBIG) {           /* too many desc's, linearize */
  822                 sc->malo_stats.mst_tx_linear++;
  823                 m = m_defrag(m0, M_NOWAIT);
  824                 if (m == NULL) {
  825                         m_freem(m0);
  826                         sc->malo_stats.mst_tx_nombuf++;
  827                         return ENOMEM;
  828                 }
  829                 m0 = m;
  830                 error = bus_dmamap_load_mbuf_sg(sc->malo_dmat, bf->bf_dmamap, m0,
  831                                              bf->bf_segs, &bf->bf_nseg,
  832                                              BUS_DMA_NOWAIT);
  833                 if (error != 0) {
  834                         sc->malo_stats.mst_tx_busdma++;
  835                         m_freem(m0);
  836                         return error;
  837                 }
  838                 KASSERT(bf->bf_nseg <= MALO_TXDESC,
  839                     ("too many segments after defrag; nseg %u", bf->bf_nseg));
  840         } else if (bf->bf_nseg == 0) {          /* null packet, discard */
  841                 sc->malo_stats.mst_tx_nodata++;
  842                 m_freem(m0);
  843                 return EIO;
  844         }
  845         DPRINTF(sc, MALO_DEBUG_XMIT, "%s: m %p len %u\n",
  846                 __func__, m0, m0->m_pkthdr.len);
  847         bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
  848         bf->bf_m = m0;
  849 
  850         return 0;
  851 }
  852 
  853 #ifdef MALO_DEBUG
  854 static void
  855 malo_printrxbuf(const struct malo_rxbuf *bf, u_int ix)
  856 {
  857         const struct malo_rxdesc *ds = bf->bf_desc;
  858         uint32_t status = le32toh(ds->status);
  859         
  860         printf("R[%2u] (DS.V:%p DS.P:0x%jx) NEXT:%08x DATA:%08x RC:%02x%s\n"
  861             "      STAT:%02x LEN:%04x SNR:%02x NF:%02x CHAN:%02x"
  862             " RATE:%02x QOS:%04x\n", ix, ds, (uintmax_t)bf->bf_daddr,
  863             le32toh(ds->physnext), le32toh(ds->physbuffdata),
  864             ds->rxcontrol, 
  865             ds->rxcontrol != MALO_RXD_CTRL_DRIVER_OWN ?
  866                 "" : (status & MALO_RXD_STATUS_OK) ? " *" : " !",
  867             ds->status, le16toh(ds->pktlen), ds->snr, ds->nf, ds->channel,
  868             ds->rate, le16toh(ds->qosctrl));
  869 }
  870 
  871 static void
  872 malo_printtxbuf(const struct malo_txbuf *bf, u_int qnum, u_int ix)
  873 {
  874         const struct malo_txdesc *ds = bf->bf_desc;
  875         uint32_t status = le32toh(ds->status);
  876         
  877         printf("Q%u[%3u]", qnum, ix);
  878         printf(" (DS.V:%p DS.P:0x%jx)\n", ds, (uintmax_t)bf->bf_daddr);
  879         printf("    NEXT:%08x DATA:%08x LEN:%04x STAT:%08x%s\n",
  880             le32toh(ds->physnext),
  881             le32toh(ds->pktptr), le16toh(ds->pktlen), status,
  882             status & MALO_TXD_STATUS_USED ?
  883             "" : (status & 3) != 0 ? " *" : " !");
  884         printf("    RATE:%02x PRI:%x QOS:%04x SAP:%08x FORMAT:%04x\n",
  885             ds->datarate, ds->txpriority, le16toh(ds->qosctrl),
  886             le32toh(ds->sap_pktinfo), le16toh(ds->format));
  887 #if 0
  888         {
  889                 const uint8_t *cp = (const uint8_t *) ds;
  890                 int i;
  891                 for (i = 0; i < sizeof(struct malo_txdesc); i++) {
  892                         printf("%02x ", cp[i]);
  893                         if (((i+1) % 16) == 0)
  894                                 printf("\n");
  895                 }
  896                 printf("\n");
  897         }
  898 #endif
  899 }
  900 #endif /* MALO_DEBUG */
  901 
  902 static __inline void
  903 malo_updatetxrate(struct ieee80211_node *ni, int rix)
  904 {
  905         static const int ieeerates[] =
  906             { 2, 4, 11, 22, 44, 12, 18, 24, 36, 48, 96, 108 };
  907         if (rix < nitems(ieeerates))
  908                 ni->ni_txrate = ieeerates[rix];
  909 }
  910 
  911 static int
  912 malo_fix2rate(int fix_rate)
  913 {
  914         static const int rates[] =
  915             { 2, 4, 11, 22, 12, 18, 24, 36, 48, 96, 108 };
  916         return (fix_rate < nitems(rates) ? rates[fix_rate] : 0);
  917 }
  918 
  919 /* idiomatic shorthands: MS = mask+shift, SM = shift+mask */
  920 #define MS(v,x)                 (((v) & x) >> x##_S)
  921 #define SM(v,x)                 (((v) << x##_S) & x)
  922 
  923 /*
  924  * Process completed xmit descriptors from the specified queue.
  925  */
  926 static int
  927 malo_tx_processq(struct malo_softc *sc, struct malo_txq *txq)
  928 {
  929         struct malo_txbuf *bf;
  930         struct malo_txdesc *ds;
  931         struct ieee80211_node *ni;
  932         int nreaped;
  933         uint32_t status;
  934 
  935         DPRINTF(sc, MALO_DEBUG_TX_PROC, "%s: tx queue %u\n",
  936             __func__, txq->qnum);
  937         for (nreaped = 0;; nreaped++) {
  938                 MALO_TXQ_LOCK(txq);
  939                 bf = STAILQ_FIRST(&txq->active);
  940                 if (bf == NULL) {
  941                         MALO_TXQ_UNLOCK(txq);
  942                         break;
  943                 }
  944                 ds = bf->bf_desc;
  945                 MALO_TXDESC_SYNC(txq, ds,
  946                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  947                 if (ds->status & htole32(MALO_TXD_STATUS_FW_OWNED)) {
  948                         MALO_TXQ_UNLOCK(txq);
  949                         break;
  950                 }
  951                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
  952                 MALO_TXQ_UNLOCK(txq);
  953 
  954 #ifdef MALO_DEBUG
  955                 if (sc->malo_debug & MALO_DEBUG_XMIT_DESC)
  956                         malo_printtxbuf(bf, txq->qnum, nreaped);
  957 #endif
  958                 ni = bf->bf_node;
  959                 if (ni != NULL) {
  960                         status = le32toh(ds->status);
  961                         if (status & MALO_TXD_STATUS_OK) {
  962                                 uint16_t format = le16toh(ds->format);
  963                                 uint8_t txant = MS(format, MALO_TXD_ANTENNA);
  964 
  965                                 sc->malo_stats.mst_ant_tx[txant]++;
  966                                 if (status & MALO_TXD_STATUS_OK_RETRY)
  967                                         sc->malo_stats.mst_tx_retries++;
  968                                 if (status & MALO_TXD_STATUS_OK_MORE_RETRY)
  969                                         sc->malo_stats.mst_tx_mretries++;
  970                                 malo_updatetxrate(ni, ds->datarate);
  971                                 sc->malo_stats.mst_tx_rate = ds->datarate;
  972                         } else {
  973                                 if (status & MALO_TXD_STATUS_FAILED_LINK_ERROR)
  974                                         sc->malo_stats.mst_tx_linkerror++;
  975                                 if (status & MALO_TXD_STATUS_FAILED_XRETRY)
  976                                         sc->malo_stats.mst_tx_xretries++;
  977                                 if (status & MALO_TXD_STATUS_FAILED_AGING)
  978                                         sc->malo_stats.mst_tx_aging++;
  979                         }
  980                         /* XXX strip fw len in case header inspected */
  981                         m_adj(bf->bf_m, sizeof(uint16_t));
  982                         ieee80211_tx_complete(ni, bf->bf_m, 
  983                             (status & MALO_TXD_STATUS_OK) == 0);
  984                 } else
  985                         m_freem(bf->bf_m);
  986 
  987                 ds->status = htole32(MALO_TXD_STATUS_IDLE);
  988                 ds->pktlen = htole32(0);
  989 
  990                 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
  991                     BUS_DMASYNC_POSTWRITE);
  992                 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
  993                 bf->bf_m = NULL;
  994                 bf->bf_node = NULL;
  995 
  996                 MALO_TXQ_LOCK(txq);
  997                 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
  998                 txq->nfree++;
  999                 MALO_TXQ_UNLOCK(txq);
 1000         }
 1001         return nreaped;
 1002 }
 1003 
 1004 /*
 1005  * Deferred processing of transmit interrupt.
 1006  */
 1007 static void
 1008 malo_tx_proc(void *arg, int npending)
 1009 {
 1010         struct malo_softc *sc = arg;
 1011         int i, nreaped;
 1012 
 1013         /*
 1014          * Process each active queue.
 1015          */
 1016         nreaped = 0;
 1017         MALO_LOCK(sc);
 1018         for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
 1019                 if (!STAILQ_EMPTY(&sc->malo_txq[i].active))
 1020                         nreaped += malo_tx_processq(sc, &sc->malo_txq[i]);
 1021         }
 1022 
 1023         if (nreaped != 0) {
 1024                 sc->malo_timer = 0;
 1025                 malo_start(sc);
 1026         }
 1027         MALO_UNLOCK(sc);
 1028 }
 1029 
 1030 static int
 1031 malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
 1032     struct malo_txbuf *bf, struct mbuf *m0)
 1033 {
 1034 #define IS_DATA_FRAME(wh)                                               \
 1035         ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA)
 1036         int error, ismcast, iswep;
 1037         int copyhdrlen, hdrlen, pktlen;
 1038         struct ieee80211_frame *wh;
 1039         struct ieee80211com *ic = &sc->malo_ic;
 1040         struct ieee80211vap *vap = ni->ni_vap;
 1041         struct malo_txdesc *ds;
 1042         struct malo_txrec *tr;
 1043         struct malo_txq *txq;
 1044         uint16_t qos;
 1045 
 1046         wh = mtod(m0, struct ieee80211_frame *);
 1047         iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;
 1048         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
 1049         copyhdrlen = hdrlen = ieee80211_anyhdrsize(wh);
 1050         pktlen = m0->m_pkthdr.len;
 1051         if (IEEE80211_QOS_HAS_SEQ(wh)) {
 1052                 if (IEEE80211_IS_DSTODS(wh)) {
 1053                         qos = *(uint16_t *)
 1054                             (((struct ieee80211_qosframe_addr4 *) wh)->i_qos);
 1055                         copyhdrlen -= sizeof(qos);
 1056                 } else
 1057                         qos = *(uint16_t *)
 1058                             (((struct ieee80211_qosframe *) wh)->i_qos);
 1059         } else
 1060                 qos = 0;
 1061 
 1062         if (iswep) {
 1063                 struct ieee80211_key *k;
 1064 
 1065                 /*
 1066                  * Construct the 802.11 header+trailer for an encrypted
 1067                  * frame. The only reason this can fail is because of an
 1068                  * unknown or unsupported cipher/key type.
 1069                  *
 1070                  * NB: we do this even though the firmware will ignore
 1071                  *     what we've done for WEP and TKIP as we need the
 1072                  *     ExtIV filled in for CCMP and this also adjusts
 1073                  *     the headers which simplifies our work below.
 1074                  */
 1075                 k = ieee80211_crypto_encap(ni, m0);
 1076                 if (k == NULL) {
 1077                         /*
 1078                          * This can happen when the key is yanked after the
 1079                          * frame was queued.  Just discard the frame; the
 1080                          * 802.11 layer counts failures and provides
 1081                          * debugging/diagnostics.
 1082                          */
 1083                         m_freem(m0);
 1084                         return EIO;
 1085                 }
 1086 
 1087                 /*
 1088                  * Adjust the packet length for the crypto additions
 1089                  * done during encap and any other bits that the f/w
 1090                  * will add later on.
 1091                  */
 1092                 pktlen = m0->m_pkthdr.len;
 1093 
 1094                 /* packet header may have moved, reset our local pointer */
 1095                 wh = mtod(m0, struct ieee80211_frame *);
 1096         }
 1097 
 1098         if (ieee80211_radiotap_active_vap(vap)) {
 1099                 sc->malo_tx_th.wt_flags = 0;    /* XXX */
 1100                 if (iswep)
 1101                         sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 1102                 sc->malo_tx_th.wt_txpower = ni->ni_txpower;
 1103                 sc->malo_tx_th.wt_antenna = sc->malo_txantenna;
 1104 
 1105                 ieee80211_radiotap_tx(vap, m0);
 1106         }
 1107 
 1108         /*
 1109          * Copy up/down the 802.11 header; the firmware requires
 1110          * we present a 2-byte payload length followed by a
 1111          * 4-address header (w/o QoS), followed (optionally) by
 1112          * any WEP/ExtIV header (but only filled in for CCMP).
 1113          * We are assured the mbuf has sufficient headroom to
 1114          * prepend in-place by the setup of ic_headroom in
 1115          * malo_attach.
 1116          */
 1117         if (hdrlen < sizeof(struct malo_txrec)) {
 1118                 const int space = sizeof(struct malo_txrec) - hdrlen;
 1119                 if (M_LEADINGSPACE(m0) < space) {
 1120                         /* NB: should never happen */
 1121                         device_printf(sc->malo_dev,
 1122                             "not enough headroom, need %d found %zd, "
 1123                             "m_flags 0x%x m_len %d\n",
 1124                             space, M_LEADINGSPACE(m0), m0->m_flags, m0->m_len);
 1125                         ieee80211_dump_pkt(ic,
 1126                             mtod(m0, const uint8_t *), m0->m_len, 0, -1);
 1127                         m_freem(m0);
 1128                         /* XXX stat */
 1129                         return EIO;
 1130                 }
 1131                 M_PREPEND(m0, space, M_NOWAIT);
 1132         }
 1133         tr = mtod(m0, struct malo_txrec *);
 1134         if (wh != (struct ieee80211_frame *) &tr->wh)
 1135                 ovbcopy(wh, &tr->wh, hdrlen);
 1136         /*
 1137          * Note: the "firmware length" is actually the length of the fully
 1138          * formed "802.11 payload".  That is, it's everything except for
 1139          * the 802.11 header.  In particular this includes all crypto
 1140          * material including the MIC!
 1141          */
 1142         tr->fwlen = htole16(pktlen - hdrlen);
 1143 
 1144         /*
 1145          * Load the DMA map so any coalescing is done.  This
 1146          * also calculates the number of descriptors we need.
 1147          */
 1148         error = malo_tx_dmasetup(sc, bf, m0);
 1149         if (error != 0)
 1150                 return error;
 1151         bf->bf_node = ni;                       /* NB: held reference */
 1152         m0 = bf->bf_m;                          /* NB: may have changed */
 1153         tr = mtod(m0, struct malo_txrec *);
 1154         wh = (struct ieee80211_frame *)&tr->wh;
 1155 
 1156         /*
 1157          * Formulate tx descriptor.
 1158          */
 1159         ds = bf->bf_desc;
 1160         txq = bf->bf_txq;
 1161 
 1162         ds->qosctrl = qos;                      /* NB: already little-endian */
 1163         ds->pktptr = htole32(bf->bf_segs[0].ds_addr);
 1164         ds->pktlen = htole16(bf->bf_segs[0].ds_len);
 1165         /* NB: pPhysNext setup once, don't touch */
 1166         ds->datarate = IS_DATA_FRAME(wh) ? 1 : 0;
 1167         ds->sap_pktinfo = 0;
 1168         ds->format = 0;
 1169 
 1170         /*
 1171          * Select transmit rate.
 1172          */
 1173         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
 1174         case IEEE80211_FC0_TYPE_MGT:
 1175                 sc->malo_stats.mst_tx_mgmt++;
 1176                 /* fall thru... */
 1177         case IEEE80211_FC0_TYPE_CTL:
 1178                 ds->txpriority = 1;
 1179                 break;
 1180         case IEEE80211_FC0_TYPE_DATA:
 1181                 ds->txpriority = txq->qnum;
 1182                 break;
 1183         default:
 1184                 device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n",
 1185                         wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
 1186                 /* XXX statistic */
 1187                 m_freem(m0);
 1188                 return EIO;
 1189         }
 1190 
 1191 #ifdef MALO_DEBUG
 1192         if (IFF_DUMPPKTS_XMIT(sc))
 1193                 ieee80211_dump_pkt(ic,
 1194                     mtod(m0, const uint8_t *)+sizeof(uint16_t),
 1195                     m0->m_len - sizeof(uint16_t), ds->datarate, -1);
 1196 #endif
 1197 
 1198         MALO_TXQ_LOCK(txq);
 1199         if (!IS_DATA_FRAME(wh))
 1200                 ds->status |= htole32(1);
 1201         ds->status |= htole32(MALO_TXD_STATUS_FW_OWNED);
 1202         STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
 1203         MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1204 
 1205         sc->malo_timer = 5;
 1206         MALO_TXQ_UNLOCK(txq);
 1207         return 0;
 1208 }
 1209 
 1210 static int
 1211 malo_transmit(struct ieee80211com *ic, struct mbuf *m)
 1212 {
 1213         struct malo_softc *sc = ic->ic_softc;
 1214         int error;
 1215 
 1216         MALO_LOCK(sc);
 1217         if (!sc->malo_running) {
 1218                 MALO_UNLOCK(sc);
 1219                 return (ENXIO);
 1220         }
 1221         error = mbufq_enqueue(&sc->malo_snd, m);
 1222         if (error) {
 1223                 MALO_UNLOCK(sc);
 1224                 return (error);
 1225         }
 1226         malo_start(sc);
 1227         MALO_UNLOCK(sc);
 1228         return (0);
 1229 }
 1230 
 1231 static void
 1232 malo_start(struct malo_softc *sc)
 1233 {
 1234         struct ieee80211_node *ni;
 1235         struct malo_txq *txq = &sc->malo_txq[0];
 1236         struct malo_txbuf *bf = NULL;
 1237         struct mbuf *m;
 1238         int nqueued = 0;
 1239 
 1240         MALO_LOCK_ASSERT(sc);
 1241 
 1242         if (!sc->malo_running || sc->malo_invalid)
 1243                 return;
 1244 
 1245         while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) {
 1246                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
 1247                 bf = malo_getbuf(sc, txq);
 1248                 if (bf == NULL) {
 1249                         mbufq_prepend(&sc->malo_snd, m);
 1250                         sc->malo_stats.mst_tx_qstop++;
 1251                         break;
 1252                 }
 1253                 /*
 1254                  * Pass the frame to the h/w for transmission.
 1255                  */
 1256                 if (malo_tx_start(sc, ni, bf, m)) {
 1257                         if_inc_counter(ni->ni_vap->iv_ifp,
 1258                             IFCOUNTER_OERRORS, 1);
 1259                         if (bf != NULL) {
 1260                                 bf->bf_m = NULL;
 1261                                 bf->bf_node = NULL;
 1262                                 MALO_TXQ_LOCK(txq);
 1263                                 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
 1264                                 MALO_TXQ_UNLOCK(txq);
 1265                         }
 1266                         ieee80211_free_node(ni);
 1267                         continue;
 1268                 }
 1269                 nqueued++;
 1270 
 1271                 if (nqueued >= malo_txcoalesce) {
 1272                         /*
 1273                          * Poke the firmware to process queued frames;
 1274                          * see below about (lack of) locking.
 1275                          */
 1276                         nqueued = 0;
 1277                         malo_hal_txstart(sc->malo_mh, 0/*XXX*/);
 1278                 }
 1279         }
 1280 
 1281         if (nqueued) {
 1282                 /*
 1283                  * NB: We don't need to lock against tx done because
 1284                  * this just prods the firmware to check the transmit
 1285                  * descriptors.  The firmware will also start fetching
 1286                  * descriptors by itself if it notices new ones are
 1287                  * present when it goes to deliver a tx done interrupt
 1288                  * to the host. So if we race with tx done processing
 1289                  * it's ok.  Delivering the kick here rather than in
 1290                  * malo_tx_start is an optimization to avoid poking the
 1291                  * firmware for each packet.
 1292                  *
 1293                  * NB: the queue id isn't used so 0 is ok.
 1294                  */
 1295                 malo_hal_txstart(sc->malo_mh, 0/*XXX*/);
 1296         }
 1297 }
 1298 
 1299 static void
 1300 malo_watchdog(void *arg)
 1301 {
 1302         struct malo_softc *sc = arg;
 1303 
 1304         callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
 1305         if (sc->malo_timer == 0 || --sc->malo_timer > 0)
 1306                 return;
 1307 
 1308         if (sc->malo_running && !sc->malo_invalid) {
 1309                 device_printf(sc->malo_dev, "watchdog timeout\n");
 1310 
 1311                 /* XXX no way to reset h/w. now  */
 1312 
 1313                 counter_u64_add(sc->malo_ic.ic_oerrors, 1);
 1314                 sc->malo_stats.mst_watchdog++;
 1315         }
 1316 }
 1317 
 1318 static int
 1319 malo_hal_reset(struct malo_softc *sc)
 1320 {
 1321         static int first = 0;
 1322         struct ieee80211com *ic = &sc->malo_ic;
 1323         struct malo_hal *mh = sc->malo_mh;
 1324 
 1325         if (first == 0) {
 1326                 /*
 1327                  * NB: when the device firstly is initialized, sometimes
 1328                  * firmware could override rx/tx dma registers so we re-set
 1329                  * these values once.
 1330                  */
 1331                 malo_hal_set_rxtxdma(sc);
 1332                 first = 1;
 1333         }
 1334 
 1335         malo_hal_setantenna(mh, MHA_ANTENNATYPE_RX, sc->malo_rxantenna);
 1336         malo_hal_setantenna(mh, MHA_ANTENNATYPE_TX, sc->malo_txantenna);
 1337         malo_hal_setradio(mh, 1, MHP_AUTO_PREAMBLE);
 1338         malo_chan_set(sc, ic->ic_curchan);
 1339 
 1340         /* XXX needs other stuffs?  */
 1341 
 1342         return 1;
 1343 }
 1344 
 1345 static __inline struct mbuf *
 1346 malo_getrxmbuf(struct malo_softc *sc, struct malo_rxbuf *bf)
 1347 {
 1348         struct mbuf *m;
 1349         bus_addr_t paddr;
 1350         int error;
 1351 
 1352         /* XXX don't need mbuf, just dma buffer */
 1353         m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 1354         if (m == NULL) {
 1355                 sc->malo_stats.mst_rx_nombuf++; /* XXX */
 1356                 return NULL;
 1357         }
 1358         error = bus_dmamap_load(sc->malo_dmat, bf->bf_dmamap,
 1359             mtod(m, caddr_t), MJUMPAGESIZE,
 1360             malo_load_cb, &paddr, BUS_DMA_NOWAIT);
 1361         if (error != 0) {
 1362                 device_printf(sc->malo_dev,
 1363                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
 1364                 m_freem(m);
 1365                 return NULL;
 1366         }
 1367         bf->bf_data = paddr;
 1368         bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
 1369 
 1370         return m;
 1371 }
 1372 
 1373 static int
 1374 malo_rxbuf_init(struct malo_softc *sc, struct malo_rxbuf *bf)
 1375 {
 1376         struct malo_rxdesc *ds;
 1377 
 1378         ds = bf->bf_desc;
 1379         if (bf->bf_m == NULL) {
 1380                 bf->bf_m = malo_getrxmbuf(sc, bf);
 1381                 if (bf->bf_m == NULL) {
 1382                         /* mark descriptor to be skipped */
 1383                         ds->rxcontrol = MALO_RXD_CTRL_OS_OWN;
 1384                         /* NB: don't need PREREAD */
 1385                         MALO_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREWRITE);
 1386                         return ENOMEM;
 1387                 }
 1388         }
 1389 
 1390         /*
 1391          * Setup descriptor.
 1392          */
 1393         ds->qosctrl = 0;
 1394         ds->snr = 0;
 1395         ds->status = MALO_RXD_STATUS_IDLE;
 1396         ds->channel = 0;
 1397         ds->pktlen = htole16(MALO_RXSIZE);
 1398         ds->nf = 0;
 1399         ds->physbuffdata = htole32(bf->bf_data);
 1400         /* NB: don't touch pPhysNext, set once */
 1401         ds->rxcontrol = MALO_RXD_CTRL_DRIVER_OWN;
 1402         MALO_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1403 
 1404         return 0;
 1405 }
 1406 
 1407 /*
 1408  * Setup the rx data structures.  This should only be done once or we may get
 1409  * out of sync with the firmware.
 1410  */
 1411 static int
 1412 malo_startrecv(struct malo_softc *sc)
 1413 {
 1414         struct malo_rxbuf *bf, *prev;
 1415         struct malo_rxdesc *ds;
 1416         
 1417         if (sc->malo_recvsetup == 1) {
 1418                 malo_mode_init(sc);             /* set filters, etc. */
 1419                 return 0;
 1420         }
 1421         
 1422         prev = NULL;
 1423         STAILQ_FOREACH(bf, &sc->malo_rxbuf, bf_list) {
 1424                 int error = malo_rxbuf_init(sc, bf);
 1425                 if (error != 0) {
 1426                         DPRINTF(sc, MALO_DEBUG_RECV,
 1427                             "%s: malo_rxbuf_init failed %d\n",
 1428                             __func__, error);
 1429                         return error;
 1430                 }
 1431                 if (prev != NULL) {
 1432                         ds = prev->bf_desc;
 1433                         ds->physnext = htole32(bf->bf_daddr);
 1434                 }
 1435                 prev = bf;
 1436         }
 1437         if (prev != NULL) {
 1438                 ds = prev->bf_desc;
 1439                 ds->physnext =
 1440                     htole32(STAILQ_FIRST(&sc->malo_rxbuf)->bf_daddr);
 1441         }
 1442 
 1443         sc->malo_recvsetup = 1;
 1444 
 1445         malo_mode_init(sc);             /* set filters, etc. */
 1446         
 1447         return 0;
 1448 }
 1449 
 1450 static void
 1451 malo_init_locked(struct malo_softc *sc)
 1452 {
 1453         struct malo_hal *mh = sc->malo_mh;
 1454         int error;
 1455         
 1456         MALO_LOCK_ASSERT(sc);
 1457         
 1458         /*
 1459          * Stop anything previously setup.  This is safe whether this is
 1460          * the first time through or not.
 1461          */
 1462         malo_stop(sc);
 1463 
 1464         /*
 1465          * Push state to the firmware.
 1466          */
 1467         if (!malo_hal_reset(sc)) {
 1468                 device_printf(sc->malo_dev,
 1469                     "%s: unable to reset hardware\n", __func__);
 1470                 return;
 1471         }
 1472 
 1473         /*
 1474          * Setup recv (once); transmit is already good to go.
 1475          */
 1476         error = malo_startrecv(sc);
 1477         if (error != 0) {
 1478                 device_printf(sc->malo_dev,
 1479                     "%s: unable to start recv logic, error %d\n",
 1480                     __func__, error);
 1481                 return;
 1482         }
 1483 
 1484         /*
 1485          * Enable interrupts.
 1486          */
 1487         sc->malo_imask = MALO_A2HRIC_BIT_RX_RDY
 1488             | MALO_A2HRIC_BIT_TX_DONE
 1489             | MALO_A2HRIC_BIT_OPC_DONE
 1490             | MALO_A2HRIC_BIT_MAC_EVENT
 1491             | MALO_A2HRIC_BIT_RX_PROBLEM
 1492             | MALO_A2HRIC_BIT_ICV_ERROR
 1493             | MALO_A2HRIC_BIT_RADAR_DETECT
 1494             | MALO_A2HRIC_BIT_CHAN_SWITCH;
 1495 
 1496         sc->malo_running = 1;
 1497         malo_hal_intrset(mh, sc->malo_imask);
 1498         callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
 1499 }
 1500 
 1501 static void
 1502 malo_init(void *arg)
 1503 {
 1504         struct malo_softc *sc = (struct malo_softc *) arg;
 1505         struct ieee80211com *ic = &sc->malo_ic;
 1506         
 1507         MALO_LOCK(sc);
 1508         malo_init_locked(sc);
 1509         MALO_UNLOCK(sc);
 1510 
 1511         if (sc->malo_running)
 1512                 ieee80211_start_all(ic);        /* start all vap's */
 1513 }
 1514 
 1515 /*
 1516  * Set the multicast filter contents into the hardware.
 1517  */
 1518 static void
 1519 malo_setmcastfilter(struct malo_softc *sc)
 1520 {
 1521         struct ieee80211com *ic = &sc->malo_ic;
 1522         struct ieee80211vap *vap;
 1523         uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX];
 1524         uint8_t *mp;
 1525         int nmc;
 1526 
 1527         mp = macs;
 1528         nmc = 0;
 1529 
 1530         if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
 1531             ic->ic_promisc > 0)
 1532                 goto all;
 1533 
 1534         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1535                 struct ifnet *ifp;
 1536                 struct ifmultiaddr *ifma;
 1537 
 1538                 ifp = vap->iv_ifp;
 1539                 if_maddr_rlock(ifp);
 1540                 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 1541                         if (ifma->ifma_addr->sa_family != AF_LINK)
 1542                                 continue;
 1543 
 1544                         if (nmc == MALO_HAL_MCAST_MAX) {
 1545                                 ifp->if_flags |= IFF_ALLMULTI;
 1546                                 if_maddr_runlock(ifp);
 1547                                 goto all;
 1548                         }
 1549                         IEEE80211_ADDR_COPY(mp,
 1550                             LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
 1551 
 1552                         mp += IEEE80211_ADDR_LEN, nmc++;
 1553                 }
 1554                 if_maddr_runlock(ifp);
 1555         }
 1556 
 1557         malo_hal_setmcast(sc->malo_mh, nmc, macs);
 1558 
 1559 all:
 1560         /*
 1561          * XXX we don't know how to set the f/w for supporting
 1562          * IFF_ALLMULTI | IFF_PROMISC cases
 1563          */
 1564         return;
 1565 }
 1566 
 1567 static int
 1568 malo_mode_init(struct malo_softc *sc)
 1569 {
 1570         struct ieee80211com *ic = &sc->malo_ic;
 1571         struct malo_hal *mh = sc->malo_mh;
 1572 
 1573         malo_hal_setpromisc(mh, ic->ic_promisc > 0);
 1574         malo_setmcastfilter(sc);
 1575 
 1576         return ENXIO;
 1577 }
 1578 
 1579 static void
 1580 malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)
 1581 {
 1582         struct ieee80211_node *ni;
 1583         struct malo_txbuf *bf;
 1584         u_int ix;
 1585         
 1586         /*
 1587          * NB: this assumes output has been stopped and
 1588          *     we do not need to block malo_tx_tasklet
 1589          */
 1590         for (ix = 0;; ix++) {
 1591                 MALO_TXQ_LOCK(txq);
 1592                 bf = STAILQ_FIRST(&txq->active);
 1593                 if (bf == NULL) {
 1594                         MALO_TXQ_UNLOCK(txq);
 1595                         break;
 1596                 }
 1597                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
 1598                 MALO_TXQ_UNLOCK(txq);
 1599 #ifdef MALO_DEBUG
 1600                 if (sc->malo_debug & MALO_DEBUG_RESET) {
 1601                         struct ieee80211com *ic = &sc->malo_ic;
 1602                         const struct malo_txrec *tr =
 1603                             mtod(bf->bf_m, const struct malo_txrec *);
 1604                         malo_printtxbuf(bf, txq->qnum, ix);
 1605                         ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh,
 1606                             bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1);
 1607                 }
 1608 #endif /* MALO_DEBUG */
 1609                 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
 1610                 ni = bf->bf_node;
 1611                 bf->bf_node = NULL;
 1612                 if (ni != NULL) {
 1613                         /*
 1614                          * Reclaim node reference.
 1615                          */
 1616                         ieee80211_free_node(ni);
 1617                 }
 1618                 m_freem(bf->bf_m);
 1619                 bf->bf_m = NULL;
 1620                 
 1621                 MALO_TXQ_LOCK(txq);
 1622                 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
 1623                 txq->nfree++;
 1624                 MALO_TXQ_UNLOCK(txq);
 1625         }
 1626 }
 1627 
 1628 static void
 1629 malo_stop(struct malo_softc *sc)
 1630 {
 1631         struct malo_hal *mh = sc->malo_mh;
 1632         int i;
 1633 
 1634         DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n",
 1635             __func__, sc->malo_invalid, sc->malo_running);
 1636 
 1637         MALO_LOCK_ASSERT(sc);
 1638 
 1639         if (!sc->malo_running)
 1640                 return;
 1641 
 1642         /*
 1643          * Shutdown the hardware and driver:
 1644          *    disable interrupts
 1645          *    turn off the radio
 1646          *    drain and release tx queues
 1647          *
 1648          * Note that some of this work is not possible if the hardware
 1649          * is gone (invalid).
 1650          */
 1651         sc->malo_running = 0;
 1652         callout_stop(&sc->malo_watchdog_timer);
 1653         sc->malo_timer = 0;
 1654         /* disable interrupt.  */
 1655         malo_hal_intrset(mh, 0);
 1656         /* turn off the radio.  */
 1657         malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE);
 1658 
 1659         /* drain and release tx queues.  */
 1660         for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
 1661                 malo_tx_draintxq(sc, &sc->malo_txq[i]);
 1662 }
 1663 
 1664 static void
 1665 malo_parent(struct ieee80211com *ic)
 1666 {
 1667         struct malo_softc *sc = ic->ic_softc;
 1668         int startall = 0;
 1669 
 1670         MALO_LOCK(sc);
 1671         if (ic->ic_nrunning > 0) {
 1672                 /*
 1673                  * Beware of being called during attach/detach
 1674                  * to reset promiscuous mode.  In that case we
 1675                  * will still be marked UP but not RUNNING.
 1676                  * However trying to re-init the interface
 1677                  * is the wrong thing to do as we've already
 1678                  * torn down much of our state.  There's
 1679                  * probably a better way to deal with this.
 1680                  */
 1681                 if (!sc->malo_running && !sc->malo_invalid) {
 1682                         malo_init(sc);
 1683                         startall = 1;
 1684                 }
 1685                 /*
 1686                  * To avoid rescanning another access point,
 1687                  * do not call malo_init() here.  Instead,
 1688                  * only reflect promisc mode settings.
 1689                  */
 1690                 malo_mode_init(sc);
 1691         } else if (sc->malo_running)
 1692                 malo_stop(sc);
 1693         MALO_UNLOCK(sc);
 1694         if (startall)
 1695                 ieee80211_start_all(ic);
 1696 }
 1697 
 1698 /*
 1699  * Callback from the 802.11 layer to update the slot time
 1700  * based on the current setting.  We use it to notify the
 1701  * firmware of ERP changes and the f/w takes care of things
 1702  * like slot time and preamble.
 1703  */
 1704 static void
 1705 malo_updateslot(struct ieee80211com *ic)
 1706 {
 1707         struct malo_softc *sc = ic->ic_softc;
 1708         struct malo_hal *mh = sc->malo_mh;
 1709         int error;
 1710         
 1711         /* NB: can be called early; suppress needless cmds */
 1712         if (!sc->malo_running)
 1713                 return;
 1714 
 1715         DPRINTF(sc, MALO_DEBUG_RESET,
 1716             "%s: chan %u MHz/flags 0x%x %s slot, (ic_flags 0x%x)\n",
 1717             __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
 1718             ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags);
 1719 
 1720         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1721                 error = malo_hal_set_slot(mh, 1);
 1722         else
 1723                 error = malo_hal_set_slot(mh, 0);
 1724 
 1725         if (error != 0)
 1726                 device_printf(sc->malo_dev, "setting %s slot failed\n",
 1727                         ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long");
 1728 }
 1729 
 1730 static int
 1731 malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 1732 {
 1733         struct ieee80211com *ic = vap->iv_ic;
 1734         struct malo_softc *sc = ic->ic_softc;
 1735         struct malo_hal *mh = sc->malo_mh;
 1736         int error;
 1737 
 1738         DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__,
 1739             ieee80211_state_name[vap->iv_state],
 1740             ieee80211_state_name[nstate]);
 1741 
 1742         /*
 1743          * Invoke the net80211 layer first so iv_bss is setup.
 1744          */
 1745         error = MALO_VAP(vap)->malo_newstate(vap, nstate, arg);
 1746         if (error != 0)
 1747                 return error;
 1748 
 1749         if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
 1750                 struct ieee80211_node *ni = vap->iv_bss;
 1751                 enum ieee80211_phymode mode = ieee80211_chan2mode(ni->ni_chan);
 1752                 const struct ieee80211_txparam *tp = &vap->iv_txparms[mode];
 1753 
 1754                 DPRINTF(sc, MALO_DEBUG_STATE,
 1755                     "%s: %s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
 1756                     "capinfo 0x%04x chan %d associd 0x%x mode %d rate %d\n",
 1757                     vap->iv_ifp->if_xname, __func__, vap->iv_flags,
 1758                     ni->ni_intval, ether_sprintf(ni->ni_bssid), ni->ni_capinfo,
 1759                     ieee80211_chan2ieee(ic, ic->ic_curchan),
 1760                     ni->ni_associd, mode, tp->ucastrate);
 1761 
 1762                 malo_hal_setradio(mh, 1,
 1763                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ?
 1764                         MHP_SHORT_PREAMBLE : MHP_LONG_PREAMBLE);
 1765                 malo_hal_setassocid(sc->malo_mh, ni->ni_bssid, ni->ni_associd);
 1766                 malo_hal_set_rate(mh, mode, 
 1767                    tp->ucastrate == IEEE80211_FIXED_RATE_NONE ?
 1768                        0 : malo_fix2rate(tp->ucastrate));
 1769         }
 1770         return 0;
 1771 }
 1772 
 1773 static int
 1774 malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 1775         const struct ieee80211_bpf_params *params)
 1776 {
 1777         struct ieee80211com *ic = ni->ni_ic;
 1778         struct malo_softc *sc = ic->ic_softc;
 1779         struct malo_txbuf *bf;
 1780         struct malo_txq *txq;
 1781 
 1782         if (!sc->malo_running || sc->malo_invalid) {
 1783                 m_freem(m);
 1784                 return ENETDOWN;
 1785         }
 1786 
 1787         /*
 1788          * Grab a TX buffer and associated resources.  Note that we depend
 1789          * on the classification by the 802.11 layer to get to the right h/w
 1790          * queue.  Management frames must ALWAYS go on queue 1 but we
 1791          * cannot just force that here because we may receive non-mgt frames.
 1792          */
 1793         txq = &sc->malo_txq[0];
 1794         bf = malo_getbuf(sc, txq);
 1795         if (bf == NULL) {
 1796                 m_freem(m);
 1797                 return ENOBUFS;
 1798         }
 1799 
 1800         /*
 1801          * Pass the frame to the h/w for transmission.
 1802          */
 1803         if (malo_tx_start(sc, ni, bf, m) != 0) {
 1804                 bf->bf_m = NULL;
 1805                 bf->bf_node = NULL;
 1806                 MALO_TXQ_LOCK(txq);
 1807                 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
 1808                 txq->nfree++;
 1809                 MALO_TXQ_UNLOCK(txq);
 1810 
 1811                 return EIO;             /* XXX */
 1812         }
 1813 
 1814         /*
 1815          * NB: We don't need to lock against tx done because this just
 1816          * prods the firmware to check the transmit descriptors.  The firmware
 1817          * will also start fetching descriptors by itself if it notices
 1818          * new ones are present when it goes to deliver a tx done interrupt
 1819          * to the host. So if we race with tx done processing it's ok.
 1820          * Delivering the kick here rather than in malo_tx_start is
 1821          * an optimization to avoid poking the firmware for each packet.
 1822          *
 1823          * NB: the queue id isn't used so 0 is ok.
 1824          */
 1825         malo_hal_txstart(sc->malo_mh, 0/*XXX*/);
 1826 
 1827         return 0;
 1828 }
 1829 
 1830 static void
 1831 malo_sysctlattach(struct malo_softc *sc)
 1832 {
 1833 #ifdef  MALO_DEBUG
 1834         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->malo_dev);
 1835         struct sysctl_oid *tree = device_get_sysctl_tree(sc->malo_dev);
 1836 
 1837         sc->malo_debug = malo_debug;
 1838         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 1839                 "debug", CTLFLAG_RW, &sc->malo_debug, 0,
 1840                 "control debugging printfs");
 1841 #endif
 1842 }
 1843 
 1844 static void
 1845 malo_announce(struct malo_softc *sc)
 1846 {
 1847 
 1848         device_printf(sc->malo_dev,
 1849                 "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
 1850                 sc->malo_hwspecs.hwversion,
 1851                 (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff,
 1852                 (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff,
 1853                 (sc->malo_hwspecs.fw_releasenum >> 8) & 0xff,
 1854                 (sc->malo_hwspecs.fw_releasenum >> 0) & 0xff,
 1855                 sc->malo_hwspecs.regioncode);
 1856 
 1857         if (bootverbose || malo_rxbuf != MALO_RXBUF)
 1858                 device_printf(sc->malo_dev,
 1859                     "using %u rx buffers\n", malo_rxbuf);
 1860         if (bootverbose || malo_txbuf != MALO_TXBUF)
 1861                 device_printf(sc->malo_dev,
 1862                     "using %u tx buffers\n", malo_txbuf);
 1863 }
 1864 
 1865 /*
 1866  * Convert net80211 channel to a HAL channel.
 1867  */
 1868 static void
 1869 malo_mapchan(struct malo_hal_channel *hc, const struct ieee80211_channel *chan)
 1870 {
 1871         hc->channel = chan->ic_ieee;
 1872 
 1873         *(uint32_t *)&hc->flags = 0;
 1874         if (IEEE80211_IS_CHAN_2GHZ(chan))
 1875                 hc->flags.freqband = MALO_FREQ_BAND_2DOT4GHZ;
 1876 }
 1877 
 1878 /*
 1879  * Set/change channels.  If the channel is really being changed,
 1880  * it's done by reseting the chip.  To accomplish this we must
 1881  * first cleanup any pending DMA, then restart stuff after a la
 1882  * malo_init.
 1883  */
 1884 static int
 1885 malo_chan_set(struct malo_softc *sc, struct ieee80211_channel *chan)
 1886 {
 1887         struct malo_hal *mh = sc->malo_mh;
 1888         struct malo_hal_channel hchan;
 1889 
 1890         DPRINTF(sc, MALO_DEBUG_RESET, "%s: chan %u MHz/flags 0x%x\n",
 1891             __func__, chan->ic_freq, chan->ic_flags);
 1892 
 1893         /*
 1894          * Convert to a HAL channel description with the flags constrained
 1895          * to reflect the current operating mode.
 1896          */
 1897         malo_mapchan(&hchan, chan);
 1898         malo_hal_intrset(mh, 0);                /* disable interrupts */
 1899         malo_hal_setchannel(mh, &hchan);
 1900         malo_hal_settxpower(mh, &hchan);
 1901 
 1902         /*
 1903          * Update internal state.
 1904          */
 1905         sc->malo_tx_th.wt_chan_freq = htole16(chan->ic_freq);
 1906         sc->malo_rx_th.wr_chan_freq = htole16(chan->ic_freq);
 1907         if (IEEE80211_IS_CHAN_ANYG(chan)) {
 1908                 sc->malo_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_G);
 1909                 sc->malo_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_G);
 1910         } else {
 1911                 sc->malo_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_B);
 1912                 sc->malo_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_B);
 1913         }
 1914         sc->malo_curchan = hchan;
 1915         malo_hal_intrset(mh, sc->malo_imask);
 1916 
 1917         return 0;
 1918 }
 1919 
 1920 static void
 1921 malo_scan_start(struct ieee80211com *ic)
 1922 {
 1923         struct malo_softc *sc = ic->ic_softc;
 1924 
 1925         DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
 1926 }
 1927 
 1928 static void
 1929 malo_scan_end(struct ieee80211com *ic)
 1930 {
 1931         struct malo_softc *sc = ic->ic_softc;
 1932 
 1933         DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
 1934 }
 1935 
 1936 static void
 1937 malo_set_channel(struct ieee80211com *ic)
 1938 {
 1939         struct malo_softc *sc = ic->ic_softc;
 1940 
 1941         (void) malo_chan_set(sc, ic->ic_curchan);
 1942 }
 1943 
 1944 static void
 1945 malo_rx_proc(void *arg, int npending)
 1946 {
 1947         struct malo_softc *sc = arg;
 1948         struct ieee80211com *ic = &sc->malo_ic;
 1949         struct malo_rxbuf *bf;
 1950         struct malo_rxdesc *ds;
 1951         struct mbuf *m, *mnew;
 1952         struct ieee80211_qosframe *wh;
 1953         struct ieee80211_qosframe_addr4 *wh4;
 1954         struct ieee80211_node *ni;
 1955         int off, len, hdrlen, pktlen, rssi, ntodo;
 1956         uint8_t *data, status;
 1957         uint32_t readptr, writeptr;
 1958 
 1959         DPRINTF(sc, MALO_DEBUG_RX_PROC,
 1960             "%s: pending %u rdptr(0x%x) 0x%x wrptr(0x%x) 0x%x\n",
 1961             __func__, npending,
 1962             sc->malo_hwspecs.rxdesc_read,
 1963             malo_bar0_read4(sc, sc->malo_hwspecs.rxdesc_read),
 1964             sc->malo_hwspecs.rxdesc_write,
 1965             malo_bar0_read4(sc, sc->malo_hwspecs.rxdesc_write));
 1966 
 1967         readptr = malo_bar0_read4(sc, sc->malo_hwspecs.rxdesc_read);
 1968         writeptr = malo_bar0_read4(sc, sc->malo_hwspecs.rxdesc_write);
 1969         if (readptr == writeptr)
 1970                 return;
 1971 
 1972         bf = sc->malo_rxnext;
 1973         for (ntodo = malo_rxquota; ntodo > 0 && readptr != writeptr; ntodo--) {
 1974                 if (bf == NULL) {
 1975                         bf = STAILQ_FIRST(&sc->malo_rxbuf);
 1976                         break;
 1977                 }
 1978                 ds = bf->bf_desc;
 1979                 if (bf->bf_m == NULL) {
 1980                         /*
 1981                          * If data allocation failed previously there
 1982                          * will be no buffer; try again to re-populate it.
 1983                          * Note the firmware will not advance to the next
 1984                          * descriptor with a dma buffer so we must mimic
 1985                          * this or we'll get out of sync.
 1986                          */ 
 1987                         DPRINTF(sc, MALO_DEBUG_ANY,
 1988                             "%s: rx buf w/o dma memory\n", __func__);
 1989                         (void)malo_rxbuf_init(sc, bf);
 1990                         break;
 1991                 }
 1992                 MALO_RXDESC_SYNC(sc, ds,
 1993                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1994                 if (ds->rxcontrol != MALO_RXD_CTRL_DMA_OWN)
 1995                         break;
 1996 
 1997                 readptr = le32toh(ds->physnext);
 1998 
 1999 #ifdef MALO_DEBUG
 2000                 if (sc->malo_debug & MALO_DEBUG_RECV_DESC)
 2001                         malo_printrxbuf(bf, 0);
 2002 #endif
 2003                 status = ds->status;
 2004                 if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) {
 2005                         counter_u64_add(ic->ic_ierrors, 1);
 2006                         goto rx_next;
 2007                 }
 2008                 /*
 2009                  * Sync the data buffer.
 2010                  */
 2011                 len = le16toh(ds->pktlen);
 2012                 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
 2013                     BUS_DMASYNC_POSTREAD);
 2014                 /*
 2015                  * The 802.11 header is provided all or in part at the front;
 2016                  * use it to calculate the true size of the header that we'll
 2017                  * construct below.  We use this to figure out where to copy
 2018                  * payload prior to constructing the header.
 2019                  */
 2020                 m = bf->bf_m;
 2021                 data = mtod(m, uint8_t *);
 2022                 hdrlen = ieee80211_anyhdrsize(data + sizeof(uint16_t));
 2023                 off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4);
 2024 
 2025                 /*
 2026                  * Calculate RSSI. XXX wrong
 2027                  */
 2028                 rssi = 2 * ((int) ds->snr - ds->nf);    /* NB: .5 dBm  */
 2029                 if (rssi > 100)
 2030                         rssi = 100;
 2031 
 2032                 pktlen = hdrlen + (len - off);
 2033                 /*
 2034                  * NB: we know our frame is at least as large as
 2035                  * IEEE80211_MIN_LEN because there is a 4-address frame at
 2036                  * the front.  Hence there's no need to vet the packet length.
 2037                  * If the frame in fact is too small it should be discarded
 2038                  * at the net80211 layer.
 2039                  */
 2040 
 2041                 /* XXX don't need mbuf, just dma buffer */
 2042                 mnew = malo_getrxmbuf(sc, bf);
 2043                 if (mnew == NULL) {
 2044                         counter_u64_add(ic->ic_ierrors, 1);
 2045                         goto rx_next;
 2046                 }
 2047                 /*
 2048                  * Attach the dma buffer to the mbuf; malo_rxbuf_init will
 2049                  * re-setup the rx descriptor using the replacement dma
 2050                  * buffer we just installed above.
 2051                  */
 2052                 bf->bf_m = mnew;
 2053                 m->m_data += off - hdrlen;
 2054                 m->m_pkthdr.len = m->m_len = pktlen;
 2055 
 2056                 /*
 2057                  * Piece 802.11 header together.
 2058                  */
 2059                 wh = mtod(m, struct ieee80211_qosframe *);
 2060                 /* NB: don't need to do this sometimes but ... */
 2061                 /* XXX special case so we can memcpy after m_devget? */
 2062                 ovbcopy(data + sizeof(uint16_t), wh, hdrlen);
 2063                 if (IEEE80211_QOS_HAS_SEQ(wh)) {
 2064                         if (IEEE80211_IS_DSTODS(wh)) {
 2065                                 wh4 = mtod(m,
 2066                                     struct ieee80211_qosframe_addr4*);
 2067                                 *(uint16_t *)wh4->i_qos = ds->qosctrl;
 2068                         } else {
 2069                                 *(uint16_t *)wh->i_qos = ds->qosctrl;
 2070                         }
 2071                 }
 2072                 if (ieee80211_radiotap_active(ic)) {
 2073                         sc->malo_rx_th.wr_flags = 0;
 2074                         sc->malo_rx_th.wr_rate = ds->rate;
 2075                         sc->malo_rx_th.wr_antsignal = rssi;
 2076                         sc->malo_rx_th.wr_antnoise = ds->nf;
 2077                 }
 2078 #ifdef MALO_DEBUG
 2079                 if (IFF_DUMPPKTS_RECV(sc, wh)) {
 2080                         ieee80211_dump_pkt(ic, mtod(m, caddr_t),
 2081                             len, ds->rate, rssi);
 2082                 }
 2083 #endif
 2084                 /* dispatch */
 2085                 ni = ieee80211_find_rxnode(ic,
 2086                     (struct ieee80211_frame_min *)wh);
 2087                 if (ni != NULL) {
 2088                         (void) ieee80211_input(ni, m, rssi, ds->nf);
 2089                         ieee80211_free_node(ni);
 2090                 } else
 2091                         (void) ieee80211_input_all(ic, m, rssi, ds->nf);
 2092 rx_next:
 2093                 /* NB: ignore ENOMEM so we process more descriptors */
 2094                 (void) malo_rxbuf_init(sc, bf);
 2095                 bf = STAILQ_NEXT(bf, bf_list);
 2096         }
 2097         
 2098         malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr);
 2099         sc->malo_rxnext = bf;
 2100 
 2101         if (mbufq_first(&sc->malo_snd) != NULL)
 2102                 malo_start(sc);
 2103 }
 2104 
 2105 /*
 2106  * Reclaim all tx queue resources.
 2107  */
 2108 static void
 2109 malo_tx_cleanup(struct malo_softc *sc)
 2110 {
 2111         int i;
 2112 
 2113         for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
 2114                 malo_tx_cleanupq(sc, &sc->malo_txq[i]);
 2115 }
 2116 
 2117 int
 2118 malo_detach(struct malo_softc *sc)
 2119 {
 2120         struct ieee80211com *ic = &sc->malo_ic;
 2121 
 2122         malo_stop(sc);
 2123 
 2124         if (sc->malo_tq != NULL) {
 2125                 taskqueue_drain(sc->malo_tq, &sc->malo_rxtask);
 2126                 taskqueue_drain(sc->malo_tq, &sc->malo_txtask);
 2127                 taskqueue_free(sc->malo_tq);
 2128                 sc->malo_tq = NULL;
 2129         }
 2130 
 2131         /*
 2132          * NB: the order of these is important:
 2133          * o call the 802.11 layer before detaching the hal to
 2134          *   insure callbacks into the driver to delete global
 2135          *   key cache entries can be handled
 2136          * o reclaim the tx queue data structures after calling
 2137          *   the 802.11 layer as we'll get called back to reclaim
 2138          *   node state and potentially want to use them
 2139          * o to cleanup the tx queues the hal is called, so detach
 2140          *   it last
 2141          * Other than that, it's straightforward...
 2142          */
 2143         ieee80211_ifdetach(ic);
 2144         callout_drain(&sc->malo_watchdog_timer);
 2145         malo_dma_cleanup(sc);
 2146         malo_tx_cleanup(sc);
 2147         malo_hal_detach(sc->malo_mh);
 2148         mbufq_drain(&sc->malo_snd);
 2149         MALO_LOCK_DESTROY(sc);
 2150 
 2151         return 0;
 2152 }
 2153 
 2154 void
 2155 malo_shutdown(struct malo_softc *sc)
 2156 {
 2157 
 2158         malo_stop(sc);
 2159 }
 2160 
 2161 void
 2162 malo_suspend(struct malo_softc *sc)
 2163 {
 2164 
 2165         malo_stop(sc);
 2166 }
 2167 
 2168 void
 2169 malo_resume(struct malo_softc *sc)
 2170 {
 2171 
 2172         if (sc->malo_ic.ic_nrunning > 0)
 2173                 malo_init(sc);
 2174 }

Cache object: 372b90e9b462508ad69a864081de164a


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