xref: /illumos-gate/usr/src/uts/common/io/sfxge/efsys.h (revision 49ef7e06)
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 */
687