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