2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
39 #include <sys/param.h>
41 #include <sys/endian.h>
43 #include <sys/malloc.h>
45 #include <sys/mutex.h>
46 #include <sys/rwlock.h>
48 #include <sys/systm.h>
50 #include <machine/bus.h>
51 #include <machine/endian.h>
53 #define EFSYS_HAS_UINT64 1
54 #if defined(__x86_64__)
55 #define EFSYS_USE_UINT64 1
57 #define EFSYS_USE_UINT64 0
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
66 #include "efx_types.h"
68 /* Common code requires this */
69 #if __FreeBSD_version < 800068
70 #define memmove(d, s, l) bcopy(s, d, l)
73 /* FreeBSD equivalents of Solaris things */
86 #define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
90 #define P2ROUNDUP(x, align) (-(-(x) & -(align)))
94 #define ISP2(x) (((x) & ((x) - 1)) == 0)
97 #define ENOTACTIVE EINVAL
99 /* Memory type to use on FreeBSD */
100 MALLOC_DECLARE(M_SFXGE);
102 /* Machine dependend prefetch wrappers */
103 #if defined(__i386__) || defined(__amd64__)
105 prefetch_read_many(void *addr)
115 prefetch_read_once(void *addr)
123 #elif defined(__sparc64__)
125 prefetch_read_many(void *addr)
135 prefetch_read_once(void *addr)
145 prefetch_read_many(void *addr)
151 prefetch_read_once(void *addr)
157 #if defined(__i386__) || defined(__amd64__)
162 sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
163 struct mbuf *m, bus_dma_segment_t *seg)
165 #if defined(__i386__) || defined(__amd64__)
166 seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t));
167 seg->ds_len = m->m_len;
171 bus_dmamap_load_mbuf_sg(tag, map, m, seg, &nsegstmp, 0);
175 /* Modifiers used for DOS builds */
179 /* Modifiers used for Windows builds */
182 #define __in_ecount(_n)
183 #define __in_ecount_opt(_n)
184 #define __in_bcount(_n)
185 #define __in_bcount_opt(_n)
189 #define __out_ecount(_n)
190 #define __out_ecount_opt(_n)
191 #define __out_bcount(_n)
192 #define __out_bcount_opt(_n)
198 #define __inout_ecount(_n)
199 #define __inout_ecount_opt(_n)
200 #define __inout_bcount(_n)
201 #define __inout_bcount_opt(_n)
202 #define __inout_bcount_full_opt(_n)
204 #define __deref_out_bcount_opt(n)
206 #define __checkReturn
208 #define __drv_when(_p, _c)
210 /* Code inclusion options */
213 #define EFSYS_OPT_NAMES 1
215 #define EFSYS_OPT_FALCON 0
216 #define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0
217 #define EFSYS_OPT_SIENA 1
219 #define EFSYS_OPT_CHECK_REG 1
221 #define EFSYS_OPT_CHECK_REG 0
224 #define EFSYS_OPT_MCDI 1
226 #define EFSYS_OPT_MAC_FALCON_GMAC 0
227 #define EFSYS_OPT_MAC_FALCON_XMAC 0
228 #define EFSYS_OPT_MAC_STATS 1
230 #define EFSYS_OPT_LOOPBACK 0
232 #define EFSYS_OPT_MON_NULL 0
233 #define EFSYS_OPT_MON_LM87 0
234 #define EFSYS_OPT_MON_MAX6647 0
235 #define EFSYS_OPT_MON_SIENA 0
236 #define EFSYS_OPT_MON_STATS 0
238 #define EFSYS_OPT_PHY_NULL 0
239 #define EFSYS_OPT_PHY_QT2022C2 0
240 #define EFSYS_OPT_PHY_SFX7101 0
241 #define EFSYS_OPT_PHY_TXC43128 0
242 #define EFSYS_OPT_PHY_PM8358 0
243 #define EFSYS_OPT_PHY_SFT9001 0
244 #define EFSYS_OPT_PHY_QT2025C 0
245 #define EFSYS_OPT_PHY_STATS 1
246 #define EFSYS_OPT_PHY_PROPS 0
247 #define EFSYS_OPT_PHY_BIST 1
248 #define EFSYS_OPT_PHY_LED_CONTROL 1
249 #define EFSYS_OPT_PHY_FLAGS 0
251 #define EFSYS_OPT_VPD 1
252 #define EFSYS_OPT_NVRAM 1
253 #define EFSYS_OPT_NVRAM_FALCON_BOOTROM 0
254 #define EFSYS_OPT_NVRAM_SFT9001 0
255 #define EFSYS_OPT_NVRAM_SFX7101 0
256 #define EFSYS_OPT_BOOTCFG 0
258 #define EFSYS_OPT_PCIE_TUNE 0
259 #define EFSYS_OPT_DIAG 0
260 #define EFSYS_OPT_WOL 1
261 #define EFSYS_OPT_RX_SCALE 1
262 #define EFSYS_OPT_QSTATS 1
263 #define EFSYS_OPT_FILTER 0
264 #define EFSYS_OPT_RX_SCATTER 0
265 #define EFSYS_OPT_RX_HDR_SPLIT 0
267 #define EFSYS_OPT_EV_PREFETCH 0
269 #define EFSYS_OPT_DECODE_INTR_FATAL 1
273 typedef struct __efsys_identifier_s efsys_identifier_t;
277 #ifndef KDTRACE_HOOKS
279 #define EFSYS_PROBE(_name)
281 #define EFSYS_PROBE1(_name, _type1, _arg1)
283 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)
285 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \
288 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \
289 _type3, _arg3, _type4, _arg4)
291 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
292 _type3, _arg3, _type4, _arg4, _type5, _arg5)
294 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
295 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
298 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \
299 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
300 _type6, _arg6, _type7, _arg7)
302 #else /* KDTRACE_HOOKS */
304 #define EFSYS_PROBE(_name) \
307 #define EFSYS_PROBE1(_name, _type1, _arg1) \
308 DTRACE_PROBE1(_name, _type1, _arg1)
310 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \
311 DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2)
313 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \
315 DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2, \
318 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \
319 _type3, _arg3, _type4, _arg4) \
320 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \
321 _type3, _arg3, _type4, _arg4)
324 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
325 _type3, _arg3, _type4, _arg4, _type5, _arg5) \
326 DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
327 _type3, _arg3, _type4, _arg4, _type5, _arg5)
329 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
330 _type3, _arg3, _type4, _arg4, _type5, _arg5) \
331 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \
332 _type3, _arg3, _type4, _arg4)
336 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
337 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
339 DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
340 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
343 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
344 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
346 EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
347 _type3, _arg3, _type4, _arg4, _type5, _arg5)
351 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \
352 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
353 _type6, _arg6, _type7, _arg7) \
354 DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2, \
355 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
356 _type6, _arg6, _type7, _arg7)
358 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \
359 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
360 _type6, _arg6, _type7, _arg7) \
361 EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
362 _type3, _arg3, _type4, _arg4, _type5, _arg5, \
366 #endif /* KDTRACE_HOOKS */
370 typedef uint64_t efsys_dma_addr_t;
372 typedef struct efsys_mem_s {
373 bus_dma_tag_t esm_tag;
374 bus_dmamap_t esm_map;
376 efsys_dma_addr_t esm_addr;
380 #define EFSYS_MEM_ZERO(_esmp, _size) \
382 (void) memset((_esmp)->esm_base, 0, (_size)); \
384 _NOTE(CONSTANTCONDITION) \
387 #define EFSYS_MEM_READD(_esmp, _offset, _edp) \
391 _NOTE(CONSTANTCONDITION) \
392 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \
393 ("not power of 2 aligned")); \
395 addr = (void *)((_esmp)->esm_base + (_offset)); \
397 (_edp)->ed_u32[0] = *addr; \
399 EFSYS_PROBE2(mem_readd, unsigned int, (_offset), \
400 uint32_t, (_edp)->ed_u32[0]); \
402 _NOTE(CONSTANTCONDITION) \
405 #if defined(__x86_64__)
406 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \
410 _NOTE(CONSTANTCONDITION) \
411 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
412 ("not power of 2 aligned")); \
414 addr = (void *)((_esmp)->esm_base + (_offset)); \
416 (_eqp)->eq_u64[0] = *addr; \
418 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \
419 uint32_t, (_eqp)->eq_u32[1], \
420 uint32_t, (_eqp)->eq_u32[0]); \
422 _NOTE(CONSTANTCONDITION) \
425 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \
429 _NOTE(CONSTANTCONDITION) \
430 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
431 ("not power of 2 aligned")); \
433 addr = (void *)((_esmp)->esm_base + (_offset)); \
435 (_eqp)->eq_u32[0] = *addr++; \
436 (_eqp)->eq_u32[1] = *addr; \
438 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \
439 uint32_t, (_eqp)->eq_u32[1], \
440 uint32_t, (_eqp)->eq_u32[0]); \
442 _NOTE(CONSTANTCONDITION) \
446 #if defined(__x86_64__)
447 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \
451 _NOTE(CONSTANTCONDITION) \
452 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
453 ("not power of 2 aligned")); \
455 addr = (void *)((_esmp)->esm_base + (_offset)); \
457 (_eop)->eo_u64[0] = *addr++; \
458 (_eop)->eo_u64[1] = *addr; \
460 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \
461 uint32_t, (_eop)->eo_u32[3], \
462 uint32_t, (_eop)->eo_u32[2], \
463 uint32_t, (_eop)->eo_u32[1], \
464 uint32_t, (_eop)->eo_u32[0]); \
466 _NOTE(CONSTANTCONDITION) \
469 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \
473 _NOTE(CONSTANTCONDITION) \
474 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
475 ("not power of 2 aligned")); \
477 addr = (void *)((_esmp)->esm_base + (_offset)); \
479 (_eop)->eo_u32[0] = *addr++; \
480 (_eop)->eo_u32[1] = *addr++; \
481 (_eop)->eo_u32[2] = *addr++; \
482 (_eop)->eo_u32[3] = *addr; \
484 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \
485 uint32_t, (_eop)->eo_u32[3], \
486 uint32_t, (_eop)->eo_u32[2], \
487 uint32_t, (_eop)->eo_u32[1], \
488 uint32_t, (_eop)->eo_u32[0]); \
490 _NOTE(CONSTANTCONDITION) \
494 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \
498 _NOTE(CONSTANTCONDITION) \
499 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \
500 ("not power of 2 aligned")); \
502 EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \
503 uint32_t, (_edp)->ed_u32[0]); \
505 addr = (void *)((_esmp)->esm_base + (_offset)); \
507 *addr = (_edp)->ed_u32[0]; \
509 _NOTE(CONSTANTCONDITION) \
512 #if defined(__x86_64__)
513 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \
517 _NOTE(CONSTANTCONDITION) \
518 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
519 ("not power of 2 aligned")); \
521 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \
522 uint32_t, (_eqp)->eq_u32[1], \
523 uint32_t, (_eqp)->eq_u32[0]); \
525 addr = (void *)((_esmp)->esm_base + (_offset)); \
527 *addr = (_eqp)->eq_u64[0]; \
529 _NOTE(CONSTANTCONDITION) \
533 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \
537 _NOTE(CONSTANTCONDITION) \
538 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
539 ("not power of 2 aligned")); \
541 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \
542 uint32_t, (_eqp)->eq_u32[1], \
543 uint32_t, (_eqp)->eq_u32[0]); \
545 addr = (void *)((_esmp)->esm_base + (_offset)); \
547 *addr++ = (_eqp)->eq_u32[0]; \
548 *addr = (_eqp)->eq_u32[1]; \
550 _NOTE(CONSTANTCONDITION) \
554 #if defined(__x86_64__)
555 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \
559 _NOTE(CONSTANTCONDITION) \
560 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
561 ("not power of 2 aligned")); \
563 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \
564 uint32_t, (_eop)->eo_u32[3], \
565 uint32_t, (_eop)->eo_u32[2], \
566 uint32_t, (_eop)->eo_u32[1], \
567 uint32_t, (_eop)->eo_u32[0]); \
569 addr = (void *)((_esmp)->esm_base + (_offset)); \
571 *addr++ = (_eop)->eo_u64[0]; \
572 *addr = (_eop)->eo_u64[1]; \
574 _NOTE(CONSTANTCONDITION) \
577 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \
581 _NOTE(CONSTANTCONDITION) \
582 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
583 ("not power of 2 aligned")); \
585 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \
586 uint32_t, (_eop)->eo_u32[3], \
587 uint32_t, (_eop)->eo_u32[2], \
588 uint32_t, (_eop)->eo_u32[1], \
589 uint32_t, (_eop)->eo_u32[0]); \
591 addr = (void *)((_esmp)->esm_base + (_offset)); \
593 *addr++ = (_eop)->eo_u32[0]; \
594 *addr++ = (_eop)->eo_u32[1]; \
595 *addr++ = (_eop)->eo_u32[2]; \
596 *addr = (_eop)->eo_u32[3]; \
598 _NOTE(CONSTANTCONDITION) \
602 #define EFSYS_MEM_ADDR(_esmp) \
607 #define SFXGE_LOCK_NAME_MAX 16
609 typedef struct efsys_bar_s {
611 char esb_lock_name[SFXGE_LOCK_NAME_MAX];
612 bus_space_tag_t esb_tag;
613 bus_space_handle_t esb_handle;
615 struct resource *esb_res;
618 #define SFXGE_BAR_LOCK_INIT(_esbp, _ifname) \
620 snprintf((_esbp)->esb_lock_name, \
621 sizeof((_esbp)->esb_lock_name), \
622 "%s:bar", (_ifname)); \
623 mtx_init(&(_esbp)->esb_lock, (_esbp)->esb_lock_name, \
625 _NOTE(CONSTANTCONDITION) \
627 #define SFXGE_BAR_LOCK_DESTROY(_esbp) \
628 mtx_destroy(&(_esbp)->esb_lock)
629 #define SFXGE_BAR_LOCK(_esbp) \
630 mtx_lock(&(_esbp)->esb_lock)
631 #define SFXGE_BAR_UNLOCK(_esbp) \
632 mtx_unlock(&(_esbp)->esb_lock)
634 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \
636 _NOTE(CONSTANTCONDITION) \
637 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \
638 ("not power of 2 aligned")); \
640 _NOTE(CONSTANTCONDITION) \
642 SFXGE_BAR_LOCK(_esbp); \
644 (_edp)->ed_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
645 (_esbp)->esb_handle, (_offset)); \
647 EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \
648 uint32_t, (_edp)->ed_u32[0]); \
650 _NOTE(CONSTANTCONDITION) \
652 SFXGE_BAR_UNLOCK(_esbp); \
653 _NOTE(CONSTANTCONDITION) \
656 #if defined(__x86_64__)
657 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \
659 _NOTE(CONSTANTCONDITION) \
660 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
661 ("not power of 2 aligned")); \
663 SFXGE_BAR_LOCK(_esbp); \
665 (_eqp)->eq_u64[0] = bus_space_read_8((_esbp)->esb_tag, \
666 (_esbp)->esb_handle, (_offset)); \
668 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \
669 uint32_t, (_eqp)->eq_u32[1], \
670 uint32_t, (_eqp)->eq_u32[0]); \
672 mtx_unlock(&((_esbp)->esb_lock)); \
673 _NOTE(CONSTANTCONDITION) \
676 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \
678 _NOTE(CONSTANTCONDITION) \
679 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
680 ("not power of 2 aligned")); \
682 _NOTE(CONSTANTCONDITION) \
684 mtx_lock(&((_esbp)->esb_lock)); \
686 (_eop)->eo_u64[0] = bus_space_read_8((_esbp)->esb_tag, \
687 (_esbp)->esb_handle, (_offset)); \
688 (_eop)->eo_u64[1] = bus_space_read_8((_esbp)->esb_tag, \
689 (_esbp)->esb_handle, (_offset+8)); \
691 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \
692 uint32_t, (_eop)->eo_u32[3], \
693 uint32_t, (_eop)->eo_u32[2], \
694 uint32_t, (_eop)->eo_u32[1], \
695 uint32_t, (_eop)->eo_u32[0]); \
697 _NOTE(CONSTANTCONDITION) \
699 mtx_unlock(&((_esbp)->esb_lock)); \
700 _NOTE(CONSTANTCONDITION) \
704 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \
706 _NOTE(CONSTANTCONDITION) \
707 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
708 ("not power of 2 aligned")); \
710 mtx_lock(&((_esbp)->esb_lock)); \
712 (_eqp)->eq_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
713 (_esbp)->esb_handle, (_offset)); \
714 (_eqp)->eq_u32[1] = bus_space_read_4((_esbp)->esb_tag, \
715 (_esbp)->esb_handle, (_offset+4)); \
717 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \
718 uint32_t, (_eqp)->eq_u32[1], \
719 uint32_t, (_eqp)->eq_u32[0]); \
721 SFXGE_BAR_UNLOCK(_esbp); \
722 _NOTE(CONSTANTCONDITION) \
725 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \
727 _NOTE(CONSTANTCONDITION) \
728 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
729 ("not power of 2 aligned")); \
731 _NOTE(CONSTANTCONDITION) \
733 SFXGE_BAR_LOCK(_esbp); \
735 (_eop)->eo_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
736 (_esbp)->esb_handle, (_offset)); \
737 (_eop)->eo_u32[1] = bus_space_read_4((_esbp)->esb_tag, \
738 (_esbp)->esb_handle, (_offset+4)); \
739 (_eop)->eo_u32[2] = bus_space_read_4((_esbp)->esb_tag, \
740 (_esbp)->esb_handle, (_offset+8)); \
741 (_eop)->eo_u32[3] = bus_space_read_4((_esbp)->esb_tag, \
742 (_esbp)->esb_handle, (_offset+12)); \
744 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \
745 uint32_t, (_eop)->eo_u32[3], \
746 uint32_t, (_eop)->eo_u32[2], \
747 uint32_t, (_eop)->eo_u32[1], \
748 uint32_t, (_eop)->eo_u32[0]); \
750 _NOTE(CONSTANTCONDITION) \
752 SFXGE_BAR_UNLOCK(_esbp); \
753 _NOTE(CONSTANTCONDITION) \
757 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \
759 _NOTE(CONSTANTCONDITION) \
760 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \
761 ("not power of 2 aligned")); \
763 _NOTE(CONSTANTCONDITION) \
765 SFXGE_BAR_LOCK(_esbp); \
767 EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \
768 uint32_t, (_edp)->ed_u32[0]); \
770 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
771 (_offset), (_edp)->ed_u32[0]); \
773 _NOTE(CONSTANTCONDITION) \
775 SFXGE_BAR_UNLOCK(_esbp); \
776 _NOTE(CONSTANTCONDITION) \
779 #if defined(__x86_64__)
780 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \
782 _NOTE(CONSTANTCONDITION) \
783 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
784 ("not power of 2 aligned")); \
786 SFXGE_BAR_LOCK(_esbp); \
788 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \
789 uint32_t, (_eqp)->eq_u32[1], \
790 uint32_t, (_eqp)->eq_u32[0]); \
792 bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
793 (_offset), (_eqp)->eq_u64[0]); \
795 mtx_unlock(&((_esbp)->esb_lock)); \
796 _NOTE(CONSTANTCONDITION) \
799 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \
801 _NOTE(CONSTANTCONDITION) \
802 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
803 ("not power of 2 aligned")); \
805 mtx_lock(&((_esbp)->esb_lock)); \
807 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \
808 uint32_t, (_eqp)->eq_u32[1], \
809 uint32_t, (_eqp)->eq_u32[0]); \
811 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
812 (_offset), (_eqp)->eq_u32[0]); \
813 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
814 (_offset+4), (_eqp)->eq_u32[1]); \
816 SFXGE_BAR_UNLOCK(_esbp); \
817 _NOTE(CONSTANTCONDITION) \
821 #if defined(__x86_64__)
822 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \
824 _NOTE(CONSTANTCONDITION) \
825 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
826 ("not power of 2 aligned")); \
828 _NOTE(CONSTANTCONDITION) \
830 SFXGE_BAR_LOCK(_esbp); \
832 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \
833 uint32_t, (_eop)->eo_u32[3], \
834 uint32_t, (_eop)->eo_u32[2], \
835 uint32_t, (_eop)->eo_u32[1], \
836 uint32_t, (_eop)->eo_u32[0]); \
838 bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
839 (_offset), (_eop)->eo_u64[0]); \
840 bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
841 (_offset+8), (_eop)->eo_u64[1]); \
843 _NOTE(CONSTANTCONDITION) \
845 mtx_unlock(&((_esbp)->esb_lock)); \
846 _NOTE(CONSTANTCONDITION) \
850 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \
852 _NOTE(CONSTANTCONDITION) \
853 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \
854 ("not power of 2 aligned")); \
856 _NOTE(CONSTANTCONDITION) \
858 mtx_lock(&((_esbp)->esb_lock)); \
860 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \
861 uint32_t, (_eop)->eo_u32[3], \
862 uint32_t, (_eop)->eo_u32[2], \
863 uint32_t, (_eop)->eo_u32[1], \
864 uint32_t, (_eop)->eo_u32[0]); \
866 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
867 (_offset), (_eop)->eo_u32[0]); \
868 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
869 (_offset+4), (_eop)->eo_u32[1]); \
870 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
871 (_offset+8), (_eop)->eo_u32[2]); \
872 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
873 (_offset+12), (_eop)->eo_u32[3]); \
875 _NOTE(CONSTANTCONDITION) \
877 SFXGE_BAR_UNLOCK(_esbp); \
878 _NOTE(CONSTANTCONDITION) \
884 #define EFSYS_SPIN(_us) \
887 _NOTE(CONSTANTCONDITION) \
890 #define EFSYS_SLEEP EFSYS_SPIN
894 #define EFSYS_MEM_READ_BARRIER() rmb()
895 #define EFSYS_PIO_WRITE_BARRIER()
899 typedef clock_t efsys_timestamp_t;
901 #define EFSYS_TIMESTAMP(_usp) \
906 *(_usp) = now * hz / 1000000; \
907 _NOTE(CONSTANTCONDITION) \
912 #define EFSYS_KMEM_ALLOC(_esip, _size, _p) \
915 (_p) = malloc((_size), M_SFXGE, M_WAITOK|M_ZERO); \
916 _NOTE(CONSTANTCONDITION) \
919 #define EFSYS_KMEM_FREE(_esip, _size, _p) \
923 free((_p), M_SFXGE); \
924 _NOTE(CONSTANTCONDITION) \
929 typedef struct efsys_lock_s {
931 char lock_name[SFXGE_LOCK_NAME_MAX];
934 #define SFXGE_EFSYS_LOCK_INIT(_eslp, _ifname, _label) \
936 efsys_lock_t *__eslp = (_eslp); \
938 snprintf((__eslp)->lock_name, \
939 sizeof((__eslp)->lock_name), \
940 "%s:%s", (_ifname), (_label)); \
941 mtx_init(&(__eslp)->lock, (__eslp)->lock_name, \
944 #define SFXGE_EFSYS_LOCK_DESTROY(_eslp) \
945 mtx_destroy(&(_eslp)->lock)
946 #define SFXGE_EFSYS_LOCK(_eslp) \
947 mtx_lock(&(_eslp)->lock)
948 #define SFXGE_EFSYS_UNLOCK(_eslp) \
949 mtx_unlock(&(_eslp)->lock)
950 #define SFXGE_EFSYS_LOCK_ASSERT_OWNED(_eslp) \
951 mtx_assert(&(_eslp)->lock, MA_OWNED)
953 #define EFSYS_LOCK_MAGIC 0x000010c4
955 #define EFSYS_LOCK(_lockp, _state) \
957 SFXGE_EFSYS_LOCK(_lockp); \
958 (_state) = EFSYS_LOCK_MAGIC; \
959 _NOTE(CONSTANTCONDITION) \
962 #define EFSYS_UNLOCK(_lockp, _state) \
964 if ((_state) != EFSYS_LOCK_MAGIC) \
965 KASSERT(B_FALSE, ("not locked")); \
966 SFXGE_EFSYS_UNLOCK(_lockp); \
967 _NOTE(CONSTANTCONDITION) \
972 #define EFSYS_PREEMPT_DISABLE(_state) \
974 (_state) = (_state); \
976 _NOTE(CONSTANTCONDITION) \
979 #define EFSYS_PREEMPT_ENABLE(_state) \
981 (_state) = (_state); \
982 critical_exit(_state); \
983 _NOTE(CONSTANTCONDITION) \
988 typedef uint64_t efsys_stat_t;
990 #define EFSYS_STAT_INCR(_knp, _delta) \
992 *(_knp) += (_delta); \
993 _NOTE(CONSTANTCONDITION) \
996 #define EFSYS_STAT_DECR(_knp, _delta) \
998 *(_knp) -= (_delta); \
999 _NOTE(CONSTANTCONDITION) \
1002 #define EFSYS_STAT_SET(_knp, _val) \
1005 _NOTE(CONSTANTCONDITION) \
1008 #define EFSYS_STAT_SET_QWORD(_knp, _valp) \
1010 *(_knp) = le64toh((_valp)->eq_u64[0]); \
1011 _NOTE(CONSTANTCONDITION) \
1014 #define EFSYS_STAT_SET_DWORD(_knp, _valp) \
1016 *(_knp) = le32toh((_valp)->ed_u32[0]); \
1017 _NOTE(CONSTANTCONDITION) \
1020 #define EFSYS_STAT_INCR_QWORD(_knp, _valp) \
1022 *(_knp) += le64toh((_valp)->eq_u64[0]); \
1023 _NOTE(CONSTANTCONDITION) \
1026 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \
1028 *(_knp) -= le64toh((_valp)->eq_u64[0]); \
1029 _NOTE(CONSTANTCONDITION) \
1034 extern void sfxge_err(efsys_identifier_t *, unsigned int,
1035 uint32_t, uint32_t);
1037 #if EFSYS_OPT_DECODE_INTR_FATAL
1038 #define EFSYS_ERR(_esip, _code, _dword0, _dword1) \
1040 sfxge_err((_esip), (_code), (_dword0), (_dword1)); \
1041 _NOTE(CONSTANTCONDITION) \
1047 #define EFSYS_ASSERT(_exp) do { \
1052 #define EFSYS_ASSERT3(_x, _op, _y, _t) do { \
1053 const _t __x = (_t)(_x); \
1054 const _t __y = (_t)(_y); \
1055 if (!(__x _op __y)) \
1056 panic("assertion failed at %s:%u", __FILE__, __LINE__); \
1059 #define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t)
1060 #define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t)
1061 #define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
1067 #endif /* _SYS_EFSYS_H */