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