1 /*
   2  * Copyright (c) 2008-2016 Solarflare Communications Inc.
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions are met:
   7  *
   8  * 1. Redistributions of source code must retain the above copyright notice,
   9  *    this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11  *    this list of conditions and the following disclaimer in the documentation
  12  *    and/or other materials provided with the distribution.
  13  *
  14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25  *
  26  * The views and conclusions contained in the software and documentation are
  27  * those of the authors and should not be interpreted as representing official
  28  * policies, either expressed or implied, of the FreeBSD Project.
  29  */
  30 
  31 #ifndef _SYS_EFSYS_H
  32 #define _SYS_EFSYS_H
  33 
  34 #ifdef  __cplusplus
  35 extern "C" {
  36 #endif
  37 
  38 #include <sys/types.h>
  39 #include <sys/sysmacros.h>
  40 #include <sys/ddi.h>
  41 #include <sys/sunddi.h>
  42 #include <sys/cpuvar.h>
  43 #include <sys/disp.h>
  44 #include <sys/sdt.h>
  45 #include <sys/kstat.h>
  46 #include <sys/crc32.h>
  47 #include <sys/note.h>
  48 #include <sys/byteorder.h>
  49 
  50 #define EFSYS_HAS_UINT64 1
  51 #define EFSYS_USE_UINT64 0
  52 #define EFSYS_HAS_SSE2_M128 0
  53 #ifdef  _BIG_ENDIAN
  54 #define EFSYS_IS_BIG_ENDIAN 1
  55 #endif
  56 #ifdef  _LITTLE_ENDIAN
  57 #define EFSYS_IS_LITTLE_ENDIAN 1
  58 #endif
  59 #include "efx_types.h"
  60 
  61 /* Modifiers used for Windows builds */
  62 #define __in
  63 #define __in_opt
  64 #define __in_ecount(_n)
  65 #define __in_ecount_opt(_n)
  66 #define __in_bcount(_n)
  67 #define __in_bcount_opt(_n)
  68 
  69 #define __out
  70 #define __out_opt
  71 #define __out_ecount(_n)
  72 #define __out_ecount_opt(_n)
  73 #define __out_bcount(_n)
  74 #define __out_bcount_opt(_n)
  75 #define __out_bcount_part(_n, _l)
  76 #define __out_bcount_part_opt(_n, _l)
  77 
  78 #define __deref_out
  79 
  80 #define __inout
  81 #define __inout_opt
  82 #define __inout_ecount(_n)
  83 #define __inout_ecount_opt(_n)
  84 #define __inout_bcount(_n)
  85 #define __inout_bcount_opt(_n)
  86 #define __inout_bcount_full_opt(_n)
  87 
  88 #define __deref_out_bcount_opt(n)
  89 
  90 #define __checkReturn
  91 #define __success(_x)
  92 
  93 #define __drv_when(_p, _c)
  94 
  95 /* Code inclusion options */
  96 
  97 
  98 #define EFSYS_OPT_NAMES 1
  99 
 100 #define EFSYS_OPT_SIENA 1
 101 #define EFSYS_OPT_HUNTINGTON 1
 102 #define EFSYS_OPT_MEDFORD 0
 103 #if DEBUG
 104 #define EFSYS_OPT_CHECK_REG 1
 105 #else
 106 #define EFSYS_OPT_CHECK_REG 0
 107 #endif
 108 
 109 #define EFSYS_OPT_MCDI 1
 110 #define EFSYS_OPT_MCDI_LOGGING 0
 111 #define EFSYS_OPT_MCDI_PROXY_AUTH 0
 112 
 113 #define EFSYS_OPT_MAC_STATS 1
 114 
 115 #define EFSYS_OPT_LOOPBACK 1
 116 
 117 #define EFSYS_OPT_MON_MCDI 1
 118 #define EFSYS_OPT_MON_STATS 1
 119 
 120 #define EFSYS_OPT_PHY_STATS 1
 121 #define EFSYS_OPT_BIST 1
 122 #define EFSYS_OPT_PHY_LED_CONTROL 1
 123 
 124 #define EFSYS_OPT_VPD 1
 125 #define EFSYS_OPT_NVRAM 1
 126 #define EFSYS_OPT_BOOTCFG 1
 127 
 128 #define EFSYS_OPT_DIAG 0
 129 #define EFSYS_OPT_WOL 1
 130 #define EFSYS_OPT_RX_SCALE 1
 131 #define EFSYS_OPT_QSTATS 1
 132 
 133 #define EFSYS_OPT_EV_PREFETCH 0
 134 
 135 #define EFSYS_OPT_DECODE_INTR_FATAL 1
 136 
 137 #define EFSYS_OPT_FILTER 1
 138 
 139 #define EFSYS_OPT_LICENSING 0
 140 
 141 /* ID */
 142 
 143 typedef struct __efsys_identifier_s     efsys_identifier_t;
 144 
 145 /* DMA */
 146 
 147 typedef uint64_t                efsys_dma_addr_t;
 148 
 149 typedef struct efsys_mem_s {
 150         ddi_dma_handle_t        esm_dma_handle; /* DMA memory allocate/bind */
 151         ddi_acc_handle_t        esm_acc_handle; /* DMA memory read/write */
 152         caddr_t                 esm_base;
 153         efsys_dma_addr_t        esm_addr;
 154         size_t                  esm_size;
 155         size_t                  esm_used;
 156 } efsys_mem_t;
 157 
 158 
 159 #define EFSYS_MEM_ZERO(_esmp, _size)                                    \
 160         (void) bzero((_esmp)->esm_base, (_size))
 161 
 162 #define EFSYS_MEM_READD(_esmp, _offset, _edp)                           \
 163         do {                                                            \
 164                 uint32_t *addr;                                         \
 165                                                                         \
 166                 _NOTE(CONSTANTCONDITION)                                \
 167                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 168                                                                         \
 169                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 170                                                                         \
 171                 (_edp)->ed_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 172                     addr);                                              \
 173                                                                         \
 174                 DTRACE_PROBE2(mem_readd, unsigned int, (_offset),       \
 175                     uint32_t, (_edp)->ed_u32[0]);                    \
 176                                                                         \
 177         _NOTE(CONSTANTCONDITION)                                        \
 178         } while (B_FALSE)
 179 
 180 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp)                           \
 181         do {                                                            \
 182                 uint32_t *addr;                                         \
 183                                                                         \
 184                 _NOTE(CONSTANTCONDITION)                                \
 185                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 186                                                                         \
 187                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 188                                                                         \
 189                 (_eqp)->eq_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 190                     addr++);                                            \
 191                 (_eqp)->eq_u32[1] = ddi_get32((_esmp)->esm_acc_handle,    \
 192                     addr);                                              \
 193                                                                         \
 194                 DTRACE_PROBE3(mem_readq, unsigned int, (_offset),       \
 195                     uint32_t, (_eqp)->eq_u32[1],                     \
 196                     uint32_t, (_eqp)->eq_u32[0]);                    \
 197                                                                         \
 198         _NOTE(CONSTANTCONDITION)                                        \
 199         } while (B_FALSE)
 200 
 201 #define EFSYS_MEM_READO(_esmp, _offset, _eop)                           \
 202         do {                                                            \
 203                 uint32_t *addr;                                         \
 204                                                                         \
 205                 _NOTE(CONSTANTCONDITION)                                \
 206                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 207                                                                         \
 208                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 209                                                                         \
 210                 (_eop)->eo_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 211                     addr++);                                            \
 212                 (_eop)->eo_u32[1] = ddi_get32((_esmp)->esm_acc_handle,    \
 213                     addr++);                                            \
 214                 (_eop)->eo_u32[2] = ddi_get32((_esmp)->esm_acc_handle,    \
 215                     addr++);                                            \
 216                 (_eop)->eo_u32[3] = ddi_get32((_esmp)->esm_acc_handle,    \
 217                     addr);                                              \
 218                                                                         \
 219                 DTRACE_PROBE5(mem_reado, unsigned int, (_offset),       \
 220                     uint32_t, (_eop)->eo_u32[3],                     \
 221                     uint32_t, (_eop)->eo_u32[2],                     \
 222                     uint32_t, (_eop)->eo_u32[1],                     \
 223                     uint32_t, (_eop)->eo_u32[0]);                    \
 224                                                                         \
 225         _NOTE(CONSTANTCONDITION)                                        \
 226         } while (B_FALSE)
 227 
 228 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp)                          \
 229         do {                                                            \
 230                 uint32_t *addr;                                         \
 231                                                                         \
 232                 _NOTE(CONSTANTCONDITION)                                \
 233                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 234                                                                         \
 235                 DTRACE_PROBE2(mem_writed, unsigned int, (_offset),      \
 236                     uint32_t, (_edp)->ed_u32[0]);                    \
 237                                                                         \
 238                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 239                                                                         \
 240                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 241                     (_edp)->ed_u32[0]);                                      \
 242                                                                         \
 243         _NOTE(CONSTANTCONDITION)                                        \
 244         } while (B_FALSE)
 245 
 246 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)                          \
 247         do {                                                            \
 248                 uint32_t *addr;                                         \
 249                                                                         \
 250                 _NOTE(CONSTANTCONDITION)                                \
 251                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 252                                                                         \
 253                 DTRACE_PROBE3(mem_writeq, unsigned int, (_offset),      \
 254                     uint32_t, (_eqp)->eq_u32[1],                     \
 255                     uint32_t, (_eqp)->eq_u32[0]);                    \
 256                                                                         \
 257                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 258                                                                         \
 259                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 260                     (_eqp)->eq_u32[0]);                                      \
 261                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 262                     (_eqp)->eq_u32[1]);                                      \
 263                                                                         \
 264         _NOTE(CONSTANTCONDITION)                                        \
 265         } while (B_FALSE)
 266 
 267 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop)                          \
 268         do {                                                            \
 269                 uint32_t *addr;                                         \
 270                                                                         \
 271                 _NOTE(CONSTANTCONDITION)                                \
 272                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 273                                                                         \
 274                 DTRACE_PROBE5(mem_writeo, unsigned int, (_offset),      \
 275                     uint32_t, (_eop)->eo_u32[3],                     \
 276                     uint32_t, (_eop)->eo_u32[2],                     \
 277                     uint32_t, (_eop)->eo_u32[1],                     \
 278                     uint32_t, (_eop)->eo_u32[0]);                    \
 279                                                                         \
 280                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 281                                                                         \
 282                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 283                     (_eop)->eo_u32[0]);                                      \
 284                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 285                     (_eop)->eo_u32[1]);                                      \
 286                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 287                     (_eop)->eo_u32[2]);                                      \
 288                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 289                     (_eop)->eo_u32[3]);                                      \
 290                                                                         \
 291         _NOTE(CONSTANTCONDITION)                                        \
 292         } while (B_FALSE)
 293 
 294 #define EFSYS_MEM_ADDR(_esmp)                                           \
 295         ((_esmp)->esm_addr)
 296 
 297 #define EFSYS_MEM_IS_NULL(_esmp)                                        \
 298         ((_esmp)->esm_base == NULL)
 299 
 300 /* BAR */
 301 
 302 typedef struct efsys_bar_s {
 303         kmutex_t                esb_lock;
 304         ddi_acc_handle_t        esb_handle;
 305         caddr_t                 esb_base;
 306 } efsys_bar_t;
 307 
 308 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock)                    \
 309         do {                                                            \
 310                 uint32_t *addr;                                         \
 311                                                                         \
 312                 _NOTE(CONSTANTCONDITION)                                \
 313                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 314                                                                         \
 315                 _NOTE(CONSTANTCONDITION)                                \
 316                 if (_lock)                                              \
 317                         mutex_enter(&((_esbp)->esb_lock));               \
 318                                                                         \
 319                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 320                                                                         \
 321                 (_edp)->ed_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 322                     addr);                                              \
 323                                                                         \
 324                 DTRACE_PROBE2(bar_readd, unsigned int, (_offset),       \
 325                     uint32_t, (_edp)->ed_u32[0]);                    \
 326                                                                         \
 327                 _NOTE(CONSTANTCONDITION)                                \
 328                 if (_lock)                                              \
 329                         mutex_exit(&((_esbp)->esb_lock));                \
 330         _NOTE(CONSTANTCONDITION)                                        \
 331         } while (B_FALSE)
 332 
 333 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp)                           \
 334         do {                                                            \
 335                 uint32_t *addr;                                         \
 336                                                                         \
 337                 _NOTE(CONSTANTCONDITION)                                \
 338                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 339                                                                         \
 340                 mutex_enter(&((_esbp)->esb_lock));                       \
 341                                                                         \
 342                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 343                                                                         \
 344                 (_eqp)->eq_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 345                     addr++);                                            \
 346                 (_eqp)->eq_u32[1] = ddi_get32((_esbp)->esb_handle,        \
 347                     addr);                                              \
 348                                                                         \
 349                 DTRACE_PROBE3(bar_readq, unsigned int, (_offset),       \
 350                     uint32_t, (_eqp)->eq_u32[1],                     \
 351                     uint32_t, (_eqp)->eq_u32[0]);                    \
 352                                                                         \
 353                 mutex_exit(&((_esbp)->esb_lock));                        \
 354         _NOTE(CONSTANTCONDITION)                                        \
 355         } while (B_FALSE)
 356 
 357 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)                    \
 358         do {                                                            \
 359                 uint32_t *addr;                                         \
 360                                                                         \
 361                 _NOTE(CONSTANTCONDITION)                                \
 362                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 363                                                                         \
 364                 _NOTE(CONSTANTCONDITION)                                \
 365                 if (_lock)                                              \
 366                         mutex_enter(&((_esbp)->esb_lock));               \
 367                                                                         \
 368                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 369                                                                         \
 370                 (_eop)->eo_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 371                     addr++);                                            \
 372                 (_eop)->eo_u32[1] = ddi_get32((_esbp)->esb_handle,        \
 373                     addr++);                                            \
 374                 (_eop)->eo_u32[2] = ddi_get32((_esbp)->esb_handle,        \
 375                     addr++);                                            \
 376                 (_eop)->eo_u32[3] = ddi_get32((_esbp)->esb_handle,        \
 377                     addr);                                              \
 378                                                                         \
 379                 DTRACE_PROBE5(bar_reado, unsigned int, (_offset),       \
 380                     uint32_t, (_eop)->eo_u32[3],                     \
 381                     uint32_t, (_eop)->eo_u32[2],                     \
 382                     uint32_t, (_eop)->eo_u32[1],                     \
 383                     uint32_t, (_eop)->eo_u32[0]);                    \
 384                                                                         \
 385                 _NOTE(CONSTANTCONDITION)                                \
 386                 if (_lock)                                              \
 387                         mutex_exit(&((_esbp)->esb_lock));                \
 388         _NOTE(CONSTANTCONDITION)                                        \
 389         } while (B_FALSE)
 390 
 391 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock)                   \
 392         do {                                                            \
 393                 uint32_t *addr;                                         \
 394                                                                         \
 395                 _NOTE(CONSTANTCONDITION)                                \
 396                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 397                                                                         \
 398                 _NOTE(CONSTANTCONDITION)                                \
 399                 if (_lock)                                              \
 400                         mutex_enter(&((_esbp)->esb_lock));               \
 401                                                                         \
 402                 DTRACE_PROBE2(bar_writed, unsigned int, (_offset),      \
 403                     uint32_t, (_edp)->ed_u32[0]);                    \
 404                                                                         \
 405                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 406                                                                         \
 407                 ddi_put32((_esbp)->esb_handle, addr,                 \
 408                     (_edp)->ed_u32[0]);                                      \
 409                                                                         \
 410                 _NOTE(CONSTANTCONDITION)                                \
 411                 if (_lock)                                              \
 412                         mutex_exit(&((_esbp)->esb_lock));                \
 413         _NOTE(CONSTANTCONDITION)                                        \
 414         } while (B_FALSE)
 415 
 416 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)                          \
 417         do {                                                            \
 418                 uint32_t *addr;                                         \
 419                                                                         \
 420                 _NOTE(CONSTANTCONDITION)                                \
 421                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 422                                                                         \
 423                 mutex_enter(&((_esbp)->esb_lock));                       \
 424                                                                         \
 425                 DTRACE_PROBE3(bar_writeq, unsigned int, (_offset),      \
 426                     uint32_t, (_eqp)->eq_u32[1],                     \
 427                     uint32_t, (_eqp)->eq_u32[0]);                    \
 428                                                                         \
 429                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 430                                                                         \
 431                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 432                     (_eqp)->eq_u32[0]);                                      \
 433                 ddi_put32((_esbp)->esb_handle, addr,                 \
 434                     (_eqp)->eq_u32[1]);                                      \
 435                                                                         \
 436                 mutex_exit(&((_esbp)->esb_lock));                        \
 437         _NOTE(CONSTANTCONDITION)                                        \
 438         } while (B_FALSE)
 439 
 440 /*
 441  * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
 442  * (required by PIO hardware)
 443  */
 444 #define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp)                       \
 445         do {                                                            \
 446                 _NOTE(CONSTANTCONDITION)                                \
 447                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 448                                                                         \
 449                 (void) (_esbp);                                         \
 450                                                                         \
 451                 /* FIXME: Perform a 64-bit write */                     \
 452                 EFSYS_ASSERT(0);                                        \
 453                                                                         \
 454         _NOTE(CONSTANTCONDITION)                                        \
 455         } while (B_FALSE)
 456 
 457 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)                   \
 458         do {                                                            \
 459                 uint32_t *addr;                                         \
 460                                                                         \
 461                 _NOTE(CONSTANTCONDITION)                                \
 462                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 463                                                                         \
 464                 _NOTE(CONSTANTCONDITION)                                \
 465                 if (_lock)                                              \
 466                         mutex_enter(&((_esbp)->esb_lock));               \
 467                                                                         \
 468                 DTRACE_PROBE5(bar_writeo, unsigned int, (_offset),      \
 469                     uint32_t, (_eop)->eo_u32[3],                     \
 470                     uint32_t, (_eop)->eo_u32[2],                     \
 471                     uint32_t, (_eop)->eo_u32[1],                     \
 472                     uint32_t, (_eop)->eo_u32[0]);                    \
 473                                                                         \
 474                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 475                                                                         \
 476                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 477                     (_eop)->eo_u32[0]);                                      \
 478                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 479                     (_eop)->eo_u32[1]);                                      \
 480                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 481                     (_eop)->eo_u32[2]);                                      \
 482                 ddi_put32((_esbp)->esb_handle, addr,                 \
 483                     (_eop)->eo_u32[3]);                                      \
 484                                                                         \
 485                 _NOTE(CONSTANTCONDITION)                                \
 486                 if (_lock)                                              \
 487                         mutex_exit(&((_esbp)->esb_lock));                \
 488         _NOTE(CONSTANTCONDITION)                                        \
 489         } while (B_FALSE)
 490 
 491 /* Use the standard octo-word write for doorbell writes */
 492 #define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop)                 \
 493         do {                                                            \
 494                 EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE);  \
 495         _NOTE(CONSTANTCONDITION)                                        \
 496         } while (B_FALSE)
 497 
 498 /* SPIN */
 499 
 500 #define EFSYS_SPIN(_us)                                                 \
 501         drv_usecwait(_us)
 502 
 503 /* TODO: Perhaps this should use delay(9F)? */
 504 #define EFSYS_SLEEP     EFSYS_SPIN
 505 
 506 /* BARRIERS */
 507 
 508 /* Strict ordering guaranteed by devacc.devacc_attr_dataorder */
 509 #define EFSYS_MEM_READ_BARRIER()        membar_consumer()
 510 /* TODO: Is ddi_put32() properly barriered? */
 511 #define EFSYS_PIO_WRITE_BARRIER()
 512 
 513 /* DMA SYNC */
 514 /*
 515  * It could be cheaper to sync entire map than calculate offset and
 516  * size. If so, below macros should be updated to ignore these arguments
 517  * and sync entire map.
 518  */
 519 #define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size)                \
 520         (void) ddi_dma_sync((_esmp)->esm_dma_handle,                 \
 521             (_offset), (_size), DDI_DMA_SYNC_FORKERNEL)
 522 
 523 #define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size)                \
 524         (void) ddi_dma_sync((_esmp)->esm_dma_handle,                 \
 525             (_offset), (_size), DDI_DMA_SYNC_FORDEV)
 526 
 527 /* TIMESTAMP */
 528 
 529 typedef clock_t efsys_timestamp_t;
 530 
 531 /* TODO: Arguably this could use gethrtime */
 532 #define EFSYS_TIMESTAMP(_usp)                                           \
 533         do {                                                            \
 534                 *(_usp) = drv_hztousec(ddi_get_lbolt());                \
 535         _NOTE(CONSTANTCONDITION)                                        \
 536         } while (B_FALSE)
 537 
 538 /* KMEM */
 539 
 540 #define EFSYS_KMEM_ALLOC(_esip, _size, _p)                              \
 541         do {                                                            \
 542                 (_esip) = (_esip);                                      \
 543                 (_p) = kmem_zalloc((_size), KM_NOSLEEP);                \
 544         _NOTE(CONSTANTCONDITION)                                        \
 545         } while (B_FALSE)
 546 
 547 #define EFSYS_KMEM_FREE(_esip, _size, _p)                               \
 548         do {                                                            \
 549                 (_esip) = (_esip);                                      \
 550                 kmem_free((_p), (_size));                               \
 551         _NOTE(CONSTANTCONDITION)                                        \
 552         } while (B_FALSE)
 553 
 554 /* LOCK */
 555 
 556 typedef kmutex_t        efsys_lock_t;
 557 
 558 #define EFSYS_LOCK_MAGIC        0x000010c4
 559 
 560 #define EFSYS_LOCK(_lockp, _state)                                      \
 561         do {                                                            \
 562                 mutex_enter(_lockp);                                    \
 563                 (_state) = EFSYS_LOCK_MAGIC;                            \
 564         _NOTE(CONSTANTCONDITION)                                        \
 565         } while (B_FALSE)
 566 
 567 #define EFSYS_UNLOCK(_lockp, _state)                                    \
 568         do {                                                            \
 569                 if ((_state) != EFSYS_LOCK_MAGIC)                       \
 570                         ASSERT(B_FALSE);                                \
 571                 mutex_exit(_lockp);                                     \
 572         _NOTE(CONSTANTCONDITION)                                        \
 573         } while (B_FALSE)
 574 
 575 /* STAT */
 576 
 577 typedef kstat_named_t           efsys_stat_t;
 578 
 579 #define EFSYS_STAT_INCR(_knp, _delta)                                   \
 580         do {                                                            \
 581                 ((_knp)->value.ui64) += (_delta);                    \
 582         _NOTE(CONSTANTCONDITION)                                        \
 583         } while (B_FALSE)
 584 
 585 #define EFSYS_STAT_DECR(_knp, _delta)                                   \
 586         do {                                                            \
 587                 ((_knp)->value.ui64) -= (_delta);                    \
 588         _NOTE(CONSTANTCONDITION)                                        \
 589         } while (B_FALSE)
 590 
 591 #define EFSYS_STAT_SET(_knp, _val)                                      \
 592         do {                                                            \
 593                 ((_knp)->value.ui64) = (_val);                               \
 594         _NOTE(CONSTANTCONDITION)                                        \
 595         } while (B_FALSE)
 596 
 597 #define EFSYS_STAT_SET_QWORD(_knp, _valp)                               \
 598         do {                                                            \
 599                 ((_knp)->value.ui64) = LE_64((_valp)->eq_u64[0]); \
 600         _NOTE(CONSTANTCONDITION)                                        \
 601         } while (B_FALSE)
 602 
 603 #define EFSYS_STAT_SET_DWORD(_knp, _valp)                               \
 604         do {                                                            \
 605                 ((_knp)->value.ui64) = LE_32((_valp)->ed_u32[0]); \
 606         _NOTE(CONSTANTCONDITION)                                        \
 607         } while (B_FALSE)
 608 
 609 #define EFSYS_STAT_INCR_QWORD(_knp, _valp)                              \
 610         do {                                                            \
 611                 ((_knp)->value.ui64) += LE_64((_valp)->eq_u64[0]);        \
 612         _NOTE(CONSTANTCONDITION)                                        \
 613         } while (B_FALSE)
 614 
 615 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp)                              \
 616         do {                                                            \
 617                 ((_knp)->value.ui64) -= LE_64((_valp)->eq_u64[0]);        \
 618         _NOTE(CONSTANTCONDITION)                                        \
 619         } while (B_FALSE)
 620 
 621 /* ERR */
 622 
 623 extern void     sfxge_err(efsys_identifier_t *, unsigned int,
 624                     uint32_t, uint32_t);
 625 
 626 #if EFSYS_OPT_DECODE_INTR_FATAL
 627 #define EFSYS_ERR(_esip, _code, _dword0, _dword1)                       \
 628         sfxge_err((_esip), (_code), (_dword0), (_dword1))
 629 #endif
 630 
 631 /* PROBE */
 632 
 633 #define EFSYS_PROBE(_name)                                              \
 634         DTRACE_PROBE(_name)
 635 
 636 #define EFSYS_PROBE1(_name, _type1, _arg1)                              \
 637         DTRACE_PROBE1(_name, _type1, _arg1)
 638 
 639 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)               \
 640         DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2)
 641 
 642 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,               \
 643             _type3, _arg3)                                              \
 644         DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2,              \
 645             _type3, _arg3)
 646 
 647 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,               \
 648             _type3, _arg3, _type4, _arg4)                               \
 649         DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2,              \
 650             _type3, _arg3, _type4, _arg4)
 651 
 652 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
 653             _type3, _arg3, _type4, _arg4, _type5, _arg5)                \
 654         DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2,              \
 655             _type3, _arg3, _type4, _arg4, _type5, _arg5)
 656 
 657 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
 658             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 659             _type6, _arg6)                                              \
 660         DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2,              \
 661             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 662             _type6, _arg6)
 663 
 664 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
 665             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 666             _type6, _arg6, _type7, _arg7)                               \
 667         DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2,              \
 668             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 669             _type6, _arg6, _type7, _arg7)
 670 
 671 /* ASSERT */
 672 
 673 #define EFSYS_ASSERT(_exp)              ASSERT(_exp)
 674 #define EFSYS_ASSERT3U(_x, _op, _y)     ASSERT3U(_x, _op, _y)
 675 #define EFSYS_ASSERT3S(_x, _op, _y)     ASSERT3S(_x, _op, _y)
 676 #define EFSYS_ASSERT3P(_x, _op, _y)     ASSERT3P(_x, _op, _y)
 677 
 678 /* ROTATE */
 679 
 680 #define EFSYS_HAS_ROTL_DWORD 0
 681 
 682 #ifdef  __cplusplus
 683 }
 684 #endif
 685 
 686 #endif  /* _SYS_EFSYS_H */