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/sfxge/common/efsys.h

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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2010-2016 Solarflare Communications Inc.
    5  * All rights reserved.
    6  *
    7  * This software was developed in part by Philip Paeps under contract for
    8  * Solarflare Communications, Inc.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions are met:
   12  *
   13  * 1. Redistributions of source code must retain the above copyright notice,
   14  *    this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright notice,
   16  *    this list of conditions and the following disclaimer in the documentation
   17  *    and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * The views and conclusions contained in the software and documentation are
   32  * those of the authors and should not be interpreted as representing official
   33  * policies, either expressed or implied, of the FreeBSD Project.
   34  *
   35  * $FreeBSD$
   36  */
   37 
   38 #ifndef _SYS_EFSYS_H
   39 #define _SYS_EFSYS_H
   40 
   41 #ifdef  __cplusplus
   42 extern "C" {
   43 #endif
   44 
   45 #include <sys/param.h>
   46 #include <sys/bus.h>
   47 #include <sys/endian.h>
   48 #include <sys/lock.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/mutex.h>
   52 #include <sys/rwlock.h>
   53 #include <sys/sdt.h>
   54 #include <sys/systm.h>
   55 
   56 #include <machine/bus.h>
   57 #include <machine/endian.h>
   58 
   59 #define EFSYS_HAS_UINT64 1
   60 #if defined(__x86_64__)
   61 #define EFSYS_USE_UINT64 1
   62 #else
   63 #define EFSYS_USE_UINT64 0
   64 #endif
   65 #define EFSYS_HAS_SSE2_M128 0
   66 #if _BYTE_ORDER == _BIG_ENDIAN
   67 #define EFSYS_IS_BIG_ENDIAN 1
   68 #define EFSYS_IS_LITTLE_ENDIAN 0
   69 #elif _BYTE_ORDER == _LITTLE_ENDIAN
   70 #define EFSYS_IS_BIG_ENDIAN 0
   71 #define EFSYS_IS_LITTLE_ENDIAN 1
   72 #endif
   73 #include "efx_types.h"
   74 
   75 #ifndef B_FALSE
   76 #define B_FALSE FALSE
   77 #endif
   78 #ifndef B_TRUE
   79 #define B_TRUE  TRUE
   80 #endif
   81 
   82 #ifndef IS2P
   83 #define ISP2(x)                 (((x) & ((x) - 1)) == 0)
   84 #endif
   85 
   86 #if defined(__x86_64__)
   87 
   88 #define SFXGE_USE_BUS_SPACE_8           1
   89 
   90 #if !defined(bus_space_read_stream_8)
   91 
   92 #define bus_space_read_stream_8(t, h, o)                                \
   93         bus_space_read_8((t), (h), (o))
   94 
   95 #define bus_space_write_stream_8(t, h, o, v)                            \
   96         bus_space_write_8((t), (h), (o), (v))
   97 
   98 #endif
   99 
  100 #endif
  101 
  102 #define ENOTACTIVE EINVAL
  103 
  104 /* Memory type to use on FreeBSD */
  105 MALLOC_DECLARE(M_SFXGE);
  106 
  107 /* Machine dependend prefetch wrappers */
  108 #if defined(__i386__) || defined(__amd64__)
  109 static __inline void
  110 prefetch_read_many(void *addr)
  111 {
  112 
  113         __asm__(
  114             "prefetcht0 (%0)"
  115             :
  116             : "r" (addr));
  117 }
  118 
  119 static __inline void
  120 prefetch_read_once(void *addr)
  121 {
  122 
  123         __asm__(
  124             "prefetchnta (%0)"
  125             :
  126             : "r" (addr));
  127 }
  128 #else
  129 static __inline void
  130 prefetch_read_many(void *addr)
  131 {
  132 
  133 }
  134 
  135 static __inline void
  136 prefetch_read_once(void *addr)
  137 {
  138 
  139 }
  140 #endif
  141 
  142 #if defined(__i386__) || defined(__amd64__)
  143 #include <vm/vm.h>
  144 #include <vm/pmap.h>
  145 #endif
  146 static __inline void
  147 sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
  148                     struct mbuf *m, bus_dma_segment_t *seg)
  149 {
  150 #if defined(__i386__) || defined(__amd64__)
  151         seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t));
  152         seg->ds_len = m->m_len;
  153 #else
  154         int nsegstmp;
  155 
  156         bus_dmamap_load_mbuf_sg(tag, map, m, seg, &nsegstmp, 0);
  157 #endif
  158 }
  159 
  160 /* Code inclusion options */
  161 
  162 #define EFSYS_OPT_NAMES 1
  163 
  164 #define EFSYS_OPT_SIENA 1
  165 #define EFSYS_OPT_HUNTINGTON 1
  166 #define EFSYS_OPT_MEDFORD 1
  167 #define EFSYS_OPT_MEDFORD2 1
  168 #ifdef DEBUG
  169 #define EFSYS_OPT_CHECK_REG 1
  170 #else
  171 #define EFSYS_OPT_CHECK_REG 0
  172 #endif
  173 
  174 #define EFSYS_OPT_MCDI 1
  175 #define EFSYS_OPT_MCDI_LOGGING 0
  176 #define EFSYS_OPT_MCDI_PROXY_AUTH 0
  177 
  178 #define EFSYS_OPT_MAC_STATS 1
  179 
  180 #define EFSYS_OPT_LOOPBACK 0
  181 
  182 #define EFSYS_OPT_MON_MCDI 0
  183 #define EFSYS_OPT_MON_STATS 0
  184 
  185 #define EFSYS_OPT_PHY_STATS 1
  186 #define EFSYS_OPT_BIST 1
  187 #define EFSYS_OPT_PHY_LED_CONTROL 1
  188 #define EFSYS_OPT_PHY_FLAGS 0
  189 
  190 #define EFSYS_OPT_VPD 1
  191 #define EFSYS_OPT_NVRAM 1
  192 #define EFSYS_OPT_BOOTCFG 0
  193 #define EFSYS_OPT_IMAGE_LAYOUT 0
  194 
  195 #define EFSYS_OPT_DIAG 0
  196 #define EFSYS_OPT_RX_SCALE 1
  197 #define EFSYS_OPT_QSTATS 1
  198 #define EFSYS_OPT_FILTER 1
  199 #define EFSYS_OPT_RX_SCATTER 0
  200 
  201 #define EFSYS_OPT_EV_PREFETCH 0
  202 
  203 #define EFSYS_OPT_DECODE_INTR_FATAL 1
  204 
  205 #define EFSYS_OPT_LICENSING 0
  206 
  207 #define EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0
  208 
  209 #define EFSYS_OPT_RX_PACKED_STREAM 0
  210 
  211 #define EFSYS_OPT_RX_ES_SUPER_BUFFER 0
  212 
  213 #define EFSYS_OPT_TUNNEL 0
  214 
  215 #define EFSYS_OPT_FW_SUBVARIANT_AWARE 0
  216 
  217 /* ID */
  218 
  219 typedef struct __efsys_identifier_s     efsys_identifier_t;
  220 
  221 /* PROBE */
  222 
  223 #ifndef DTRACE_PROBE
  224 
  225 #define EFSYS_PROBE(_name)
  226 
  227 #define EFSYS_PROBE1(_name, _type1, _arg1)
  228 
  229 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)
  230 
  231 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,               \
  232             _type3, _arg3)
  233 
  234 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,               \
  235             _type3, _arg3, _type4, _arg4)
  236 
  237 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
  238             _type3, _arg3, _type4, _arg4, _type5, _arg5)
  239 
  240 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
  241             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  242             _type6, _arg6)
  243 
  244 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
  245             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  246             _type6, _arg6, _type7, _arg7)
  247 
  248 #else /* DTRACE_PROBE */
  249 
  250 #define EFSYS_PROBE(_name)                                              \
  251         DTRACE_PROBE(_name)
  252 
  253 #define EFSYS_PROBE1(_name, _type1, _arg1)                              \
  254         DTRACE_PROBE1(_name, _type1, _arg1)
  255 
  256 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)               \
  257         DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2)
  258 
  259 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,               \
  260             _type3, _arg3)                                              \
  261         DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2,              \
  262             _type3, _arg3)
  263 
  264 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,               \
  265             _type3, _arg3, _type4, _arg4)                               \
  266         DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2,              \
  267             _type3, _arg3, _type4, _arg4)
  268 
  269 #ifdef DTRACE_PROBE5
  270 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
  271             _type3, _arg3, _type4, _arg4, _type5, _arg5)                \
  272         DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2,              \
  273             _type3, _arg3, _type4, _arg4, _type5, _arg5)
  274 #else
  275 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
  276             _type3, _arg3, _type4, _arg4, _type5, _arg5)                \
  277         DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2,              \
  278             _type3, _arg3, _type4, _arg4)
  279 #endif
  280 
  281 #ifdef DTRACE_PROBE6
  282 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
  283             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  284             _type6, _arg6)                                              \
  285         DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2,              \
  286             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  287             _type6, _arg6)
  288 #else
  289 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
  290             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  291             _type6, _arg6)                                              \
  292         EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
  293             _type3, _arg3, _type4, _arg4, _type5, _arg5)
  294 #endif
  295 
  296 #ifdef DTRACE_PROBE7
  297 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
  298             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  299             _type6, _arg6, _type7, _arg7)                               \
  300         DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2,              \
  301             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  302             _type6, _arg6, _type7, _arg7)
  303 #else
  304 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
  305             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  306             _type6, _arg6, _type7, _arg7)                               \
  307         EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
  308             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
  309             _type6, _arg6)
  310 #endif
  311 
  312 #endif /* DTRACE_PROBE */
  313 
  314 /* DMA */
  315 
  316 typedef uint64_t                efsys_dma_addr_t;
  317 
  318 typedef struct efsys_mem_s {
  319         bus_dma_tag_t           esm_tag;
  320         bus_dmamap_t            esm_map;
  321         caddr_t                 esm_base;
  322         efsys_dma_addr_t        esm_addr;
  323         size_t                  esm_size;
  324 } efsys_mem_t;
  325 
  326 #define EFSYS_MEM_SIZE(_esmp)                                           \
  327         ((_esmp)->esm_size)
  328 
  329 #define EFSYS_MEM_ADDR(_esmp)                                           \
  330         ((_esmp)->esm_addr)
  331 
  332 #define EFSYS_MEM_IS_NULL(_esmp)                                        \
  333         ((_esmp)->esm_base == NULL)
  334 
  335 #define EFSYS_MEM_ZERO(_esmp, _size)                                    \
  336         do {                                                            \
  337                 (void) memset((_esmp)->esm_base, 0, (_size));           \
  338                                                                         \
  339         _NOTE(CONSTANTCONDITION)                                        \
  340         } while (B_FALSE)
  341 
  342 #define EFSYS_MEM_READD(_esmp, _offset, _edp)                           \
  343         do {                                                            \
  344                 uint32_t *addr;                                         \
  345                                                                         \
  346                 _NOTE(CONSTANTCONDITION)                                \
  347                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  348                     sizeof (efx_dword_t)),                              \
  349                     ("not power of 2 aligned"));                        \
  350                                                                         \
  351                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  352                                                                         \
  353                 (_edp)->ed_u32[0] = *addr;                              \
  354                                                                         \
  355                 EFSYS_PROBE2(mem_readd, unsigned int, (_offset),        \
  356                     uint32_t, (_edp)->ed_u32[0]);                       \
  357                                                                         \
  358         _NOTE(CONSTANTCONDITION)                                        \
  359         } while (B_FALSE)
  360 
  361 #if defined(__x86_64__)
  362 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp)                           \
  363         do {                                                            \
  364                 uint64_t *addr;                                         \
  365                                                                         \
  366                 _NOTE(CONSTANTCONDITION)                                \
  367                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  368                     sizeof (efx_qword_t)),                              \
  369                     ("not power of 2 aligned"));                        \
  370                                                                         \
  371                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  372                                                                         \
  373                 (_eqp)->eq_u64[0] = *addr;                              \
  374                                                                         \
  375                 EFSYS_PROBE3(mem_readq, unsigned int, (_offset),        \
  376                     uint32_t, (_eqp)->eq_u32[1],                        \
  377                     uint32_t, (_eqp)->eq_u32[0]);                       \
  378                                                                         \
  379         _NOTE(CONSTANTCONDITION)                                        \
  380         } while (B_FALSE)
  381 #else
  382 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp)                           \
  383         do {                                                            \
  384                 uint32_t *addr;                                         \
  385                                                                         \
  386                 _NOTE(CONSTANTCONDITION)                                \
  387                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  388                     sizeof (efx_qword_t)),                              \
  389                     ("not power of 2 aligned"));                        \
  390                                                                         \
  391                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  392                                                                         \
  393                 (_eqp)->eq_u32[0] = *addr++;                            \
  394                 (_eqp)->eq_u32[1] = *addr;                              \
  395                                                                         \
  396                 EFSYS_PROBE3(mem_readq, unsigned int, (_offset),        \
  397                     uint32_t, (_eqp)->eq_u32[1],                        \
  398                     uint32_t, (_eqp)->eq_u32[0]);                       \
  399                                                                         \
  400         _NOTE(CONSTANTCONDITION)                                        \
  401         } while (B_FALSE)
  402 #endif
  403 
  404 #if defined(__x86_64__)
  405 #define EFSYS_MEM_READO(_esmp, _offset, _eop)                           \
  406         do {                                                            \
  407                 uint64_t *addr;                                         \
  408                                                                         \
  409                 _NOTE(CONSTANTCONDITION)                                \
  410                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  411                     sizeof (efx_oword_t)),                              \
  412                     ("not power of 2 aligned"));                        \
  413                                                                         \
  414                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  415                                                                         \
  416                 (_eop)->eo_u64[0] = *addr++;                            \
  417                 (_eop)->eo_u64[1] = *addr;                              \
  418                                                                         \
  419                 EFSYS_PROBE5(mem_reado, unsigned int, (_offset),        \
  420                     uint32_t, (_eop)->eo_u32[3],                        \
  421                     uint32_t, (_eop)->eo_u32[2],                        \
  422                     uint32_t, (_eop)->eo_u32[1],                        \
  423                     uint32_t, (_eop)->eo_u32[0]);                       \
  424                                                                         \
  425         _NOTE(CONSTANTCONDITION)                                        \
  426         } while (B_FALSE)
  427 #else
  428 #define EFSYS_MEM_READO(_esmp, _offset, _eop)                           \
  429         do {                                                            \
  430                 uint32_t *addr;                                         \
  431                                                                         \
  432                 _NOTE(CONSTANTCONDITION)                                \
  433                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  434                     sizeof (efx_oword_t)),                              \
  435                     ("not power of 2 aligned"));                        \
  436                                                                         \
  437                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  438                                                                         \
  439                 (_eop)->eo_u32[0] = *addr++;                            \
  440                 (_eop)->eo_u32[1] = *addr++;                            \
  441                 (_eop)->eo_u32[2] = *addr++;                            \
  442                 (_eop)->eo_u32[3] = *addr;                              \
  443                                                                         \
  444                 EFSYS_PROBE5(mem_reado, unsigned int, (_offset),        \
  445                     uint32_t, (_eop)->eo_u32[3],                        \
  446                     uint32_t, (_eop)->eo_u32[2],                        \
  447                     uint32_t, (_eop)->eo_u32[1],                        \
  448                     uint32_t, (_eop)->eo_u32[0]);                       \
  449                                                                         \
  450         _NOTE(CONSTANTCONDITION)                                        \
  451         } while (B_FALSE)
  452 #endif
  453 
  454 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp)                          \
  455         do {                                                            \
  456                 uint32_t *addr;                                         \
  457                                                                         \
  458                 _NOTE(CONSTANTCONDITION)                                \
  459                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  460                     sizeof (efx_dword_t)),                              \
  461                     ("not power of 2 aligned"));                        \
  462                                                                         \
  463                 EFSYS_PROBE2(mem_writed, unsigned int, (_offset),       \
  464                     uint32_t, (_edp)->ed_u32[0]);                       \
  465                                                                         \
  466                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  467                                                                         \
  468                 *addr = (_edp)->ed_u32[0];                              \
  469                                                                         \
  470         _NOTE(CONSTANTCONDITION)                                        \
  471         } while (B_FALSE)
  472 
  473 #if defined(__x86_64__)
  474 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)                          \
  475         do {                                                            \
  476                 uint64_t *addr;                                         \
  477                                                                         \
  478                 _NOTE(CONSTANTCONDITION)                                \
  479                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  480                     sizeof (efx_qword_t)),                              \
  481                     ("not power of 2 aligned"));                        \
  482                                                                         \
  483                 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset),       \
  484                     uint32_t, (_eqp)->eq_u32[1],                        \
  485                     uint32_t, (_eqp)->eq_u32[0]);                       \
  486                                                                         \
  487                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  488                                                                         \
  489                 *addr   = (_eqp)->eq_u64[0];                            \
  490                                                                         \
  491         _NOTE(CONSTANTCONDITION)                                        \
  492         } while (B_FALSE)
  493 
  494 #else
  495 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)                          \
  496         do {                                                            \
  497                 uint32_t *addr;                                         \
  498                                                                         \
  499                 _NOTE(CONSTANTCONDITION)                                \
  500                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  501                     sizeof (efx_qword_t)),                              \
  502                     ("not power of 2 aligned"));                        \
  503                                                                         \
  504                 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset),       \
  505                     uint32_t, (_eqp)->eq_u32[1],                        \
  506                     uint32_t, (_eqp)->eq_u32[0]);                       \
  507                                                                         \
  508                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  509                                                                         \
  510                 *addr++ = (_eqp)->eq_u32[0];                            \
  511                 *addr   = (_eqp)->eq_u32[1];                            \
  512                                                                         \
  513         _NOTE(CONSTANTCONDITION)                                        \
  514         } while (B_FALSE)
  515 #endif
  516 
  517 #if defined(__x86_64__)
  518 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop)                          \
  519         do {                                                            \
  520                 uint64_t *addr;                                         \
  521                                                                         \
  522                 _NOTE(CONSTANTCONDITION)                                \
  523                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  524                     sizeof (efx_oword_t)),                              \
  525                     ("not power of 2 aligned"));                        \
  526                                                                         \
  527                 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset),       \
  528                     uint32_t, (_eop)->eo_u32[3],                        \
  529                     uint32_t, (_eop)->eo_u32[2],                        \
  530                     uint32_t, (_eop)->eo_u32[1],                        \
  531                     uint32_t, (_eop)->eo_u32[0]);                       \
  532                                                                         \
  533                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  534                                                                         \
  535                 *addr++ = (_eop)->eo_u64[0];                            \
  536                 *addr   = (_eop)->eo_u64[1];                            \
  537                                                                         \
  538         _NOTE(CONSTANTCONDITION)                                        \
  539         } while (B_FALSE)
  540 #else
  541 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop)                          \
  542         do {                                                            \
  543                 uint32_t *addr;                                         \
  544                                                                         \
  545                 _NOTE(CONSTANTCONDITION)                                \
  546                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  547                     sizeof (efx_oword_t)),                              \
  548                     ("not power of 2 aligned"));                        \
  549                                                                         \
  550                 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset),       \
  551                     uint32_t, (_eop)->eo_u32[3],                        \
  552                     uint32_t, (_eop)->eo_u32[2],                        \
  553                     uint32_t, (_eop)->eo_u32[1],                        \
  554                     uint32_t, (_eop)->eo_u32[0]);                       \
  555                                                                         \
  556                 addr = (void *)((_esmp)->esm_base + (_offset));         \
  557                                                                         \
  558                 *addr++ = (_eop)->eo_u32[0];                            \
  559                 *addr++ = (_eop)->eo_u32[1];                            \
  560                 *addr++ = (_eop)->eo_u32[2];                            \
  561                 *addr   = (_eop)->eo_u32[3];                            \
  562                                                                         \
  563         _NOTE(CONSTANTCONDITION)                                        \
  564         } while (B_FALSE)
  565 #endif
  566 
  567 /* BAR */
  568 
  569 #define SFXGE_LOCK_NAME_MAX     16
  570 
  571 typedef struct efsys_bar_s {
  572         struct mtx              esb_lock;
  573         char                    esb_lock_name[SFXGE_LOCK_NAME_MAX];
  574         bus_space_tag_t         esb_tag;
  575         bus_space_handle_t      esb_handle;
  576         int                     esb_rid;
  577         struct resource         *esb_res;
  578 } efsys_bar_t;
  579 
  580 #define SFXGE_BAR_LOCK_INIT(_esbp, _ifname)                             \
  581         do {                                                            \
  582                 snprintf((_esbp)->esb_lock_name,                        \
  583                          sizeof((_esbp)->esb_lock_name),                \
  584                          "%s:bar", (_ifname));                          \
  585                 mtx_init(&(_esbp)->esb_lock, (_esbp)->esb_lock_name,    \
  586                          NULL, MTX_DEF);                                \
  587         _NOTE(CONSTANTCONDITION)                                        \
  588         } while (B_FALSE)
  589 #define SFXGE_BAR_LOCK_DESTROY(_esbp)                                   \
  590         mtx_destroy(&(_esbp)->esb_lock)
  591 #define SFXGE_BAR_LOCK(_esbp)                                           \
  592         mtx_lock(&(_esbp)->esb_lock)
  593 #define SFXGE_BAR_UNLOCK(_esbp)                                         \
  594         mtx_unlock(&(_esbp)->esb_lock)
  595 
  596 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock)                    \
  597         do {                                                            \
  598                 _NOTE(CONSTANTCONDITION)                                \
  599                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  600                     sizeof (efx_dword_t)),                              \
  601                     ("not power of 2 aligned"));                        \
  602                                                                         \
  603                 _NOTE(CONSTANTCONDITION)                                \
  604                 if (_lock)                                              \
  605                         SFXGE_BAR_LOCK(_esbp);                          \
  606                                                                         \
  607                 (_edp)->ed_u32[0] = bus_space_read_stream_4(            \
  608                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  609                     (_offset));                                         \
  610                                                                         \
  611                 EFSYS_PROBE2(bar_readd, unsigned int, (_offset),        \
  612                     uint32_t, (_edp)->ed_u32[0]);                       \
  613                                                                         \
  614                 _NOTE(CONSTANTCONDITION)                                \
  615                 if (_lock)                                              \
  616                         SFXGE_BAR_UNLOCK(_esbp);                        \
  617         _NOTE(CONSTANTCONDITION)                                        \
  618         } while (B_FALSE)
  619 
  620 #if defined(SFXGE_USE_BUS_SPACE_8)
  621 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp)                           \
  622         do {                                                            \
  623                 _NOTE(CONSTANTCONDITION)                                \
  624                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  625                     sizeof (efx_qword_t)),                              \
  626                     ("not power of 2 aligned"));                        \
  627                                                                         \
  628                 SFXGE_BAR_LOCK(_esbp);                                  \
  629                                                                         \
  630                 (_eqp)->eq_u64[0] = bus_space_read_stream_8(            \
  631                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  632                     (_offset));                                         \
  633                                                                         \
  634                 EFSYS_PROBE3(bar_readq, unsigned int, (_offset),        \
  635                     uint32_t, (_eqp)->eq_u32[1],                        \
  636                     uint32_t, (_eqp)->eq_u32[0]);                       \
  637                                                                         \
  638                 SFXGE_BAR_UNLOCK(_esbp);                                \
  639         _NOTE(CONSTANTCONDITION)                                        \
  640         } while (B_FALSE)
  641 
  642 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)                    \
  643         do {                                                            \
  644                 _NOTE(CONSTANTCONDITION)                                \
  645                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  646                     sizeof (efx_oword_t)),                              \
  647                     ("not power of 2 aligned"));                        \
  648                                                                         \
  649                 _NOTE(CONSTANTCONDITION)                                \
  650                 if (_lock)                                              \
  651                         SFXGE_BAR_LOCK(_esbp);                          \
  652                                                                         \
  653                 (_eop)->eo_u64[0] = bus_space_read_stream_8(            \
  654                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  655                     (_offset));                                         \
  656                 (_eop)->eo_u64[1] = bus_space_read_stream_8(            \
  657                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  658                     (_offset) + 8);                                     \
  659                                                                         \
  660                 EFSYS_PROBE5(bar_reado, unsigned int, (_offset),        \
  661                     uint32_t, (_eop)->eo_u32[3],                        \
  662                     uint32_t, (_eop)->eo_u32[2],                        \
  663                     uint32_t, (_eop)->eo_u32[1],                        \
  664                     uint32_t, (_eop)->eo_u32[0]);                       \
  665                                                                         \
  666                 _NOTE(CONSTANTCONDITION)                                \
  667                 if (_lock)                                              \
  668                         SFXGE_BAR_UNLOCK(_esbp);                        \
  669         _NOTE(CONSTANTCONDITION)                                        \
  670         } while (B_FALSE)
  671 
  672 #else
  673 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp)                           \
  674         do {                                                            \
  675                 _NOTE(CONSTANTCONDITION)                                \
  676                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  677                     sizeof (efx_qword_t)),                              \
  678                     ("not power of 2 aligned"));                        \
  679                                                                         \
  680                 SFXGE_BAR_LOCK(_esbp);                                  \
  681                                                                         \
  682                 (_eqp)->eq_u32[0] = bus_space_read_stream_4(            \
  683                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  684                     (_offset));                                         \
  685                 (_eqp)->eq_u32[1] = bus_space_read_stream_4(            \
  686                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  687                     (_offset) + 4);                                     \
  688                                                                         \
  689                 EFSYS_PROBE3(bar_readq, unsigned int, (_offset),        \
  690                     uint32_t, (_eqp)->eq_u32[1],                        \
  691                     uint32_t, (_eqp)->eq_u32[0]);                       \
  692                                                                         \
  693                 SFXGE_BAR_UNLOCK(_esbp);                                \
  694         _NOTE(CONSTANTCONDITION)                                        \
  695         } while (B_FALSE)
  696 
  697 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)                    \
  698         do {                                                            \
  699                 _NOTE(CONSTANTCONDITION)                                \
  700                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  701                     sizeof (efx_oword_t)),                              \
  702                     ("not power of 2 aligned"));                        \
  703                                                                         \
  704                 _NOTE(CONSTANTCONDITION)                                \
  705                 if (_lock)                                              \
  706                         SFXGE_BAR_LOCK(_esbp);                          \
  707                                                                         \
  708                 (_eop)->eo_u32[0] = bus_space_read_stream_4(            \
  709                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  710                     (_offset));                                         \
  711                 (_eop)->eo_u32[1] = bus_space_read_stream_4(            \
  712                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  713                     (_offset) + 4);                                     \
  714                 (_eop)->eo_u32[2] = bus_space_read_stream_4(            \
  715                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  716                     (_offset) + 8);                                     \
  717                 (_eop)->eo_u32[3] = bus_space_read_stream_4(            \
  718                     (_esbp)->esb_tag, (_esbp)->esb_handle,              \
  719                     (_offset) + 12);                                    \
  720                                                                         \
  721                 EFSYS_PROBE5(bar_reado, unsigned int, (_offset),        \
  722                     uint32_t, (_eop)->eo_u32[3],                        \
  723                     uint32_t, (_eop)->eo_u32[2],                        \
  724                     uint32_t, (_eop)->eo_u32[1],                        \
  725                     uint32_t, (_eop)->eo_u32[0]);                       \
  726                                                                         \
  727                 _NOTE(CONSTANTCONDITION)                                \
  728                 if (_lock)                                              \
  729                         SFXGE_BAR_UNLOCK(_esbp);                        \
  730         _NOTE(CONSTANTCONDITION)                                        \
  731         } while (B_FALSE)
  732 #endif
  733 
  734 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock)                   \
  735         do {                                                            \
  736                 _NOTE(CONSTANTCONDITION)                                \
  737                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  738                     sizeof (efx_dword_t)),                              \
  739                     ("not power of 2 aligned"));                        \
  740                                                                         \
  741                 _NOTE(CONSTANTCONDITION)                                \
  742                 if (_lock)                                              \
  743                         SFXGE_BAR_LOCK(_esbp);                          \
  744                                                                         \
  745                 EFSYS_PROBE2(bar_writed, unsigned int, (_offset),       \
  746                     uint32_t, (_edp)->ed_u32[0]);                       \
  747                                                                         \
  748                 /*                                                      \
  749                  * Make sure that previous writes to the dword have     \
  750                  * been done. It should be cheaper than barrier just    \
  751                  * after the write below.                               \
  752                  */                                                     \
  753                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  754                     (_offset), sizeof (efx_dword_t),                    \
  755                     BUS_SPACE_BARRIER_WRITE);                           \
  756                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  757                     (_esbp)->esb_handle,                                \
  758                     (_offset), (_edp)->ed_u32[0]);                      \
  759                                                                         \
  760                 _NOTE(CONSTANTCONDITION)                                \
  761                 if (_lock)                                              \
  762                         SFXGE_BAR_UNLOCK(_esbp);                        \
  763         _NOTE(CONSTANTCONDITION)                                        \
  764         } while (B_FALSE)
  765 
  766 #if defined(SFXGE_USE_BUS_SPACE_8)
  767 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)                          \
  768         do {                                                            \
  769                 _NOTE(CONSTANTCONDITION)                                \
  770                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  771                     sizeof (efx_qword_t)),                              \
  772                     ("not power of 2 aligned"));                        \
  773                                                                         \
  774                 SFXGE_BAR_LOCK(_esbp);                                  \
  775                                                                         \
  776                 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset),       \
  777                     uint32_t, (_eqp)->eq_u32[1],                        \
  778                     uint32_t, (_eqp)->eq_u32[0]);                       \
  779                                                                         \
  780                 /*                                                      \
  781                  * Make sure that previous writes to the qword have     \
  782                  * been done. It should be cheaper than barrier just    \
  783                  * after the write below.                               \
  784                  */                                                     \
  785                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  786                     (_offset), sizeof (efx_qword_t),                    \
  787                     BUS_SPACE_BARRIER_WRITE);                           \
  788                 bus_space_write_stream_8((_esbp)->esb_tag,              \
  789                     (_esbp)->esb_handle,                                \
  790                     (_offset), (_eqp)->eq_u64[0]);                      \
  791                                                                         \
  792                 SFXGE_BAR_UNLOCK(_esbp);                                \
  793         _NOTE(CONSTANTCONDITION)                                        \
  794         } while (B_FALSE)
  795 #else
  796 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)                          \
  797         do {                                                            \
  798                 _NOTE(CONSTANTCONDITION)                                \
  799                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  800                     sizeof (efx_qword_t)),                              \
  801                     ("not power of 2 aligned"));                        \
  802                                                                         \
  803                 SFXGE_BAR_LOCK(_esbp);                                  \
  804                                                                         \
  805                 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset),       \
  806                     uint32_t, (_eqp)->eq_u32[1],                        \
  807                     uint32_t, (_eqp)->eq_u32[0]);                       \
  808                                                                         \
  809                 /*                                                      \
  810                  * Make sure that previous writes to the qword have     \
  811                  * been done. It should be cheaper than barrier just    \
  812                  * after the last write below.                          \
  813                  */                                                     \
  814                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  815                     (_offset), sizeof (efx_qword_t),                    \
  816                     BUS_SPACE_BARRIER_WRITE);                           \
  817                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  818                     (_esbp)->esb_handle,                                \
  819                     (_offset), (_eqp)->eq_u32[0]);                      \
  820                 /*                                                      \
  821                  * It should be guaranteed that the last dword comes    \
  822                  * the last, so barrier entire qword to be sure that    \
  823                  * neither above nor below writes are reordered.        \
  824                  */                                                     \
  825                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  826                     (_offset), sizeof (efx_qword_t),                    \
  827                     BUS_SPACE_BARRIER_WRITE);                           \
  828                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  829                     (_esbp)->esb_handle,                                \
  830                     (_offset) + 4, (_eqp)->eq_u32[1]);                  \
  831                                                                         \
  832                 SFXGE_BAR_UNLOCK(_esbp);                                \
  833         _NOTE(CONSTANTCONDITION)                                        \
  834         } while (B_FALSE)
  835 #endif
  836 
  837 /*
  838  * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
  839  * (required by PIO hardware)
  840  */
  841 #define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp)                       \
  842         do {                                                            \
  843                 _NOTE(CONSTANTCONDITION)                                \
  844                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  845                     sizeof (efx_qword_t)),                              \
  846                     ("not power of 2 aligned"));                        \
  847                                                                         \
  848                 (void) (_esbp);                                         \
  849                 (void) (_eqp);                                          \
  850                                                                         \
  851                 /* FIXME: Perform a 64-bit write */                     \
  852                 KASSERT(0, ("not implemented"));                        \
  853                                                                         \
  854         _NOTE(CONSTANTCONDITION)                                        \
  855         } while (B_FALSE)
  856 
  857 #if defined(SFXGE_USE_BUS_SPACE_8)
  858 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)                   \
  859         do {                                                            \
  860                 _NOTE(CONSTANTCONDITION)                                \
  861                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  862                     sizeof (efx_oword_t)),                              \
  863                     ("not power of 2 aligned"));                        \
  864                                                                         \
  865                 _NOTE(CONSTANTCONDITION)                                \
  866                 if (_lock)                                              \
  867                         SFXGE_BAR_LOCK(_esbp);                          \
  868                                                                         \
  869                 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset),       \
  870                     uint32_t, (_eop)->eo_u32[3],                        \
  871                     uint32_t, (_eop)->eo_u32[2],                        \
  872                     uint32_t, (_eop)->eo_u32[1],                        \
  873                     uint32_t, (_eop)->eo_u32[0]);                       \
  874                                                                         \
  875                 /*                                                      \
  876                  * Make sure that previous writes to the oword have     \
  877                  * been done. It should be cheaper than barrier just    \
  878                  * after the last write below.                          \
  879                  */                                                     \
  880                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  881                     (_offset), sizeof (efx_oword_t),                    \
  882                     BUS_SPACE_BARRIER_WRITE);                           \
  883                 bus_space_write_stream_8((_esbp)->esb_tag,              \
  884                     (_esbp)->esb_handle,                                \
  885                     (_offset), (_eop)->eo_u64[0]);                      \
  886                 /*                                                      \
  887                  * It should be guaranteed that the last qword comes    \
  888                  * the last, so barrier entire oword to be sure that    \
  889                  * neither above nor below writes are reordered.        \
  890                  */                                                     \
  891                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  892                     (_offset), sizeof (efx_oword_t),                    \
  893                     BUS_SPACE_BARRIER_WRITE);                           \
  894                 bus_space_write_stream_8((_esbp)->esb_tag,              \
  895                     (_esbp)->esb_handle,                                \
  896                     (_offset) + 8, (_eop)->eo_u64[1]);                  \
  897                                                                         \
  898                 _NOTE(CONSTANTCONDITION)                                \
  899                 if (_lock)                                              \
  900                         SFXGE_BAR_UNLOCK(_esbp);                        \
  901         _NOTE(CONSTANTCONDITION)                                        \
  902         } while (B_FALSE)
  903 
  904 #else
  905 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)                   \
  906         do {                                                            \
  907                 _NOTE(CONSTANTCONDITION)                                \
  908                 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset,               \
  909                     sizeof (efx_oword_t)),                              \
  910                     ("not power of 2 aligned"));                        \
  911                                                                         \
  912                 _NOTE(CONSTANTCONDITION)                                \
  913                 if (_lock)                                              \
  914                         SFXGE_BAR_LOCK(_esbp);                          \
  915                                                                         \
  916                 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset),       \
  917                     uint32_t, (_eop)->eo_u32[3],                        \
  918                     uint32_t, (_eop)->eo_u32[2],                        \
  919                     uint32_t, (_eop)->eo_u32[1],                        \
  920                     uint32_t, (_eop)->eo_u32[0]);                       \
  921                                                                         \
  922                 /*                                                      \
  923                  * Make sure that previous writes to the oword have     \
  924                  * been done. It should be cheaper than barrier just    \
  925                  * after the last write below.                          \
  926                  */                                                     \
  927                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  928                     (_offset), sizeof (efx_oword_t),                    \
  929                     BUS_SPACE_BARRIER_WRITE);                           \
  930                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  931                     (_esbp)->esb_handle,                                \
  932                     (_offset), (_eop)->eo_u32[0]);                      \
  933                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  934                     (_esbp)->esb_handle,                                \
  935                     (_offset) + 4, (_eop)->eo_u32[1]);                  \
  936                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  937                     (_esbp)->esb_handle,                                \
  938                     (_offset) + 8, (_eop)->eo_u32[2]);                  \
  939                 /*                                                      \
  940                  * It should be guaranteed that the last dword comes    \
  941                  * the last, so barrier entire oword to be sure that    \
  942                  * neither above nor below writes are reordered.        \
  943                  */                                                     \
  944                 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\
  945                     (_offset), sizeof (efx_oword_t),                    \
  946                     BUS_SPACE_BARRIER_WRITE);                           \
  947                 bus_space_write_stream_4((_esbp)->esb_tag,              \
  948                     (_esbp)->esb_handle,                                \
  949                     (_offset) + 12, (_eop)->eo_u32[3]);                 \
  950                                                                         \
  951                 _NOTE(CONSTANTCONDITION)                                \
  952                 if (_lock)                                              \
  953                         SFXGE_BAR_UNLOCK(_esbp);                        \
  954         _NOTE(CONSTANTCONDITION)                                        \
  955         } while (B_FALSE)
  956 #endif
  957 
  958 /* Use the standard octo-word write for doorbell writes */
  959 #define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop)                 \
  960         do {                                                            \
  961                 EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE);  \
  962         _NOTE(CONSTANTCONDITION)                                        \
  963         } while (B_FALSE)
  964 
  965 /* SPIN */
  966 
  967 #define EFSYS_SPIN(_us)                                                 \
  968         do {                                                            \
  969                 DELAY(_us);                                             \
  970         _NOTE(CONSTANTCONDITION)                                        \
  971         } while (B_FALSE)
  972 
  973 #define EFSYS_SLEEP     EFSYS_SPIN
  974 
  975 /* BARRIERS */
  976 
  977 #define EFSYS_MEM_READ_BARRIER()        rmb()
  978 #define EFSYS_PIO_WRITE_BARRIER()
  979 
  980 /* DMA SYNC */
  981 #define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size)                \
  982         do {                                                            \
  983                 bus_dmamap_sync((_esmp)->esm_tag,                       \
  984                     (_esmp)->esm_map,                                   \
  985                     BUS_DMASYNC_POSTREAD);                              \
  986         _NOTE(CONSTANTCONDITION)                                        \
  987         } while (B_FALSE)
  988 
  989 #define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size)                \
  990         do {                                                            \
  991                 bus_dmamap_sync((_esmp)->esm_tag,                       \
  992                     (_esmp)->esm_map,                                   \
  993                     BUS_DMASYNC_PREWRITE);                              \
  994         _NOTE(CONSTANTCONDITION)                                        \
  995         } while (B_FALSE)
  996 
  997 /* TIMESTAMP */
  998 
  999 typedef clock_t efsys_timestamp_t;
 1000 
 1001 #define EFSYS_TIMESTAMP(_usp)                                           \
 1002         do {                                                            \
 1003                 clock_t now;                                            \
 1004                                                                         \
 1005                 now = ticks;                                            \
 1006                 *(_usp) = now * hz / 1000000;                           \
 1007         _NOTE(CONSTANTCONDITION)                                        \
 1008         } while (B_FALSE)
 1009 
 1010 /* KMEM */
 1011 
 1012 #define EFSYS_KMEM_ALLOC(_esip, _size, _p)                              \
 1013         do {                                                            \
 1014                 (_esip) = (_esip);                                      \
 1015                 /*                                                      \
 1016                  * The macro is used in non-sleepable contexts, for     \
 1017                  * example, holding a mutex.                            \
 1018                  */                                                     \
 1019                 (_p) = malloc((_size), M_SFXGE, M_NOWAIT|M_ZERO);       \
 1020         _NOTE(CONSTANTCONDITION)                                        \
 1021         } while (B_FALSE)
 1022 
 1023 #define EFSYS_KMEM_FREE(_esip, _size, _p)                               \
 1024         do {                                                            \
 1025                 (void) (_esip);                                         \
 1026                 (void) (_size);                                         \
 1027                 free((_p), M_SFXGE);                                    \
 1028         _NOTE(CONSTANTCONDITION)                                        \
 1029         } while (B_FALSE)
 1030 
 1031 /* LOCK */
 1032 
 1033 typedef struct efsys_lock_s {
 1034         struct mtx      lock;
 1035         char            lock_name[SFXGE_LOCK_NAME_MAX];
 1036 } efsys_lock_t;
 1037 
 1038 #define SFXGE_EFSYS_LOCK_INIT(_eslp, _ifname, _label)                   \
 1039         do {                                                            \
 1040                 efsys_lock_t *__eslp = (_eslp);                         \
 1041                                                                         \
 1042                 snprintf((__eslp)->lock_name,                           \
 1043                          sizeof((__eslp)->lock_name),                   \
 1044                          "%s:%s", (_ifname), (_label));                 \
 1045                 mtx_init(&(__eslp)->lock, (__eslp)->lock_name,          \
 1046                          NULL, MTX_DEF);                                \
 1047         } while (B_FALSE)
 1048 #define SFXGE_EFSYS_LOCK_DESTROY(_eslp)                                 \
 1049         mtx_destroy(&(_eslp)->lock)
 1050 #define SFXGE_EFSYS_LOCK(_eslp)                                         \
 1051         mtx_lock(&(_eslp)->lock)
 1052 #define SFXGE_EFSYS_UNLOCK(_eslp)                                       \
 1053         mtx_unlock(&(_eslp)->lock)
 1054 #define SFXGE_EFSYS_LOCK_ASSERT_OWNED(_eslp)                            \
 1055         mtx_assert(&(_eslp)->lock, MA_OWNED)
 1056 
 1057 typedef int efsys_lock_state_t;
 1058 
 1059 #define EFSYS_LOCK_MAGIC        0x000010c4
 1060 
 1061 #define EFSYS_LOCK(_lockp, _state)                                      \
 1062         do {                                                            \
 1063                 SFXGE_EFSYS_LOCK(_lockp);                               \
 1064                 (_state) = EFSYS_LOCK_MAGIC;                            \
 1065         _NOTE(CONSTANTCONDITION)                                        \
 1066         } while (B_FALSE)
 1067 
 1068 #define EFSYS_UNLOCK(_lockp, _state)                                    \
 1069         do {                                                            \
 1070                 if ((_state) != EFSYS_LOCK_MAGIC)                       \
 1071                         KASSERT(B_FALSE, ("not locked"));               \
 1072                 SFXGE_EFSYS_UNLOCK(_lockp);                             \
 1073         _NOTE(CONSTANTCONDITION)                                        \
 1074         } while (B_FALSE)
 1075 
 1076 /* STAT */
 1077 
 1078 typedef uint64_t                efsys_stat_t;
 1079 
 1080 #define EFSYS_STAT_INCR(_knp, _delta)                                   \
 1081         do {                                                            \
 1082                 *(_knp) += (_delta);                                    \
 1083         _NOTE(CONSTANTCONDITION)                                        \
 1084         } while (B_FALSE)
 1085 
 1086 #define EFSYS_STAT_DECR(_knp, _delta)                                   \
 1087         do {                                                            \
 1088                 *(_knp) -= (_delta);                                    \
 1089         _NOTE(CONSTANTCONDITION)                                        \
 1090         } while (B_FALSE)
 1091 
 1092 #define EFSYS_STAT_SET(_knp, _val)                                      \
 1093         do {                                                            \
 1094                 *(_knp) = (_val);                                       \
 1095         _NOTE(CONSTANTCONDITION)                                        \
 1096         } while (B_FALSE)
 1097 
 1098 #define EFSYS_STAT_SET_QWORD(_knp, _valp)                               \
 1099         do {                                                            \
 1100                 *(_knp) = le64toh((_valp)->eq_u64[0]);                  \
 1101         _NOTE(CONSTANTCONDITION)                                        \
 1102         } while (B_FALSE)
 1103 
 1104 #define EFSYS_STAT_SET_DWORD(_knp, _valp)                               \
 1105         do {                                                            \
 1106                 *(_knp) = le32toh((_valp)->ed_u32[0]);                  \
 1107         _NOTE(CONSTANTCONDITION)                                        \
 1108         } while (B_FALSE)
 1109 
 1110 #define EFSYS_STAT_INCR_QWORD(_knp, _valp)                              \
 1111         do {                                                            \
 1112                 *(_knp) += le64toh((_valp)->eq_u64[0]);                 \
 1113         _NOTE(CONSTANTCONDITION)                                        \
 1114         } while (B_FALSE)
 1115 
 1116 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp)                              \
 1117         do {                                                            \
 1118                 *(_knp) -= le64toh((_valp)->eq_u64[0]);                 \
 1119         _NOTE(CONSTANTCONDITION)                                        \
 1120         } while (B_FALSE)
 1121 
 1122 /* ERR */
 1123 
 1124 extern void     sfxge_err(efsys_identifier_t *, unsigned int,
 1125                     uint32_t, uint32_t);
 1126 
 1127 #if EFSYS_OPT_DECODE_INTR_FATAL
 1128 #define EFSYS_ERR(_esip, _code, _dword0, _dword1)                       \
 1129         do {                                                            \
 1130                 sfxge_err((_esip), (_code), (_dword0), (_dword1));      \
 1131         _NOTE(CONSTANTCONDITION)                                        \
 1132         } while (B_FALSE)
 1133 #endif
 1134 
 1135 /* ASSERT */
 1136 
 1137 #define EFSYS_ASSERT(_exp) do {                                         \
 1138         if (!(_exp))                                                    \
 1139                 panic("%s", #_exp);                                     \
 1140         } while (0)
 1141 
 1142 #define EFSYS_ASSERT3(_x, _op, _y, _t) do {                             \
 1143         const _t __x = (_t)(_x);                                        \
 1144         const _t __y = (_t)(_y);                                        \
 1145         if (!(__x _op __y))                                             \
 1146                 panic("assertion failed at %s:%u", __FILE__, __LINE__); \
 1147         } while(0)
 1148 
 1149 #define EFSYS_ASSERT3U(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, uint64_t)
 1150 #define EFSYS_ASSERT3S(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, int64_t)
 1151 #define EFSYS_ASSERT3P(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
 1152 
 1153 /* ROTATE */
 1154 
 1155 #define EFSYS_HAS_ROTL_DWORD 0
 1156 
 1157 #ifdef  __cplusplus
 1158 }
 1159 #endif
 1160 
 1161 #endif  /* _SYS_EFSYS_H */

Cache object: b37d3eeb83ab448abec4f0e161ea11d6


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