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