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 30#ifndef _SYS_EFSYS_H 31#define _SYS_EFSYS_H 32 33//#include <sys/cdefs.h> 34//__FBSDID("$FreeBSD$"); 35 36#include "bf_support.h" 37 38#ifdef __cplusplus 39extern "C" { 40#endif 41 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 58#define EFSYS_HAS_UINT64 1 59#define EFSYS_USE_UINT64 0 60#if _BYTE_ORDER == _BIG_ENDIAN 61#define EFSYS_IS_BIG_ENDIAN 1 62#define EFSYS_IS_LITTLE_ENDIAN 0 63#elif _BYTE_ORDER == _LITTLE_ENDIAN 64#define EFSYS_IS_BIG_ENDIAN 0 65#define EFSYS_IS_LITTLE_ENDIAN 1 66#endif 67#include "efx_types.h" 68 69 70/* Common code requires this */ 71#if __FreeBSD_version < 800068 72#define memmove(d, s, l) bcopy(s, d, l) 73#endif 74 75/* FreeBSD equivalents of Solaris things */ 76#ifndef _NOTE 77#define _NOTE(s) 78#endif 79 80#ifndef B_FALSE 81#define B_FALSE FALSE 82#endif 83#ifndef B_TRUE 84#define B_TRUE TRUE 85#endif 86 87#ifndef IS_P2ALIGNED 88#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) 89#endif 90 91#ifndef P2ROUNDUP 92#define P2ROUNDUP(x, align) (-(-(x) & -(align))) 93#endif 94 95#ifndef IS2P 96#define ISP2(x) (((x) & ((x) - 1)) == 0) 97#endif 98 99#define ENOTACTIVE EINVAL 100 101/* Memory type to use on FreeBSD */ 102// MALLOC_DECLARE(M_SFXGE); 103 104/* Machine dependend prefetch wrappers */ 105#if defined(__i386) || defined(__amd64) 106static __inline void 107prefetch_read_many(void *addr) 108{ 109 __asm__( 110 "prefetcht0 (%0)" 111 : 112 : "r" (addr)); 113} 114 115static __inline void 116prefetch_read_once(void *addr) 117{ 118 __asm__( 119 "prefetchnta (%0)" 120 : 121 : "r" (addr)); 122} 123#endif 124 125#if 0 126#if defined(__i386__) || defined(__amd64__) 127#include <vm/vm.h> 128#include <vm/pmap.h> 129#endif 130static __inline void 131sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map, 132 struct mbuf *m, bus_dma_segment_t *seg) 133{ 134#if defined(__i386__) || defined(__amd64__) 135 seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t)); 136 seg->ds_len = m->m_len; 137#else 138 int nsegstmp; 139 140 bus_dmamap_load_mbuf_sg(tag, map, m, seg, &nsegstmp, 0); 141#endif 142} 143#endif // 0 144 145/* Modifiers used for DOS builds */ 146#define __cs 147#define __far 148 149/* Modifiers used for Windows builds */ 150#define __in 151#define __in_opt 152#define __in_ecount(_n) 153#define __in_ecount_opt(_n) 154#define __in_bcount(_n) 155#define __in_bcount_opt(_n) 156 157#define __out 158#define __out_opt 159#define __out_ecount(_n) 160#define __out_ecount_opt(_n) 161#define __out_bcount(_n) 162#define __out_bcount_opt(_n) 163 164#define __deref_out 165 166#define __inout 167#define __inout_opt 168#define __inout_ecount(_n) 169#define __inout_ecount_opt(_n) 170#define __inout_bcount(_n) 171#define __inout_bcount_opt(_n) 172#define __inout_bcount_full_opt(_n) 173 174#define __deref_out_bcount_opt(n) 175 176#define __checkReturn 177 178#define __drv_when(_p, _c) 179 180/* Code inclusion options */ 181 182 183#define EFSYS_OPT_NAMES 1 184 185#define EFSYS_OPT_FALCON 0 186#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0 187#define EFSYS_OPT_SIENA 1 188#ifdef DEBUG 189#define EFSYS_OPT_CHECK_REG 1 190#else 191#define EFSYS_OPT_CHECK_REG 0 192#endif 193 194#define EFSYS_OPT_MCDI 1 195 196#define EFSYS_OPT_MAC_FALCON_GMAC 0 197#define EFSYS_OPT_MAC_FALCON_XMAC 0 198#define EFSYS_OPT_MAC_STATS 1 199 200#define EFSYS_OPT_LOOPBACK 0 201 202#define EFSYS_OPT_MON_NULL 0 203#define EFSYS_OPT_MON_LM87 0 204#define EFSYS_OPT_MON_MAX6647 0 205#define EFSYS_OPT_MON_SIENA 0 206#define EFSYS_OPT_MON_STATS 0 207 208#define EFSYS_OPT_PHY_NULL 0 209#define EFSYS_OPT_PHY_QT2022C2 0 210#define EFSYS_OPT_PHY_SFX7101 0 211#define EFSYS_OPT_PHY_TXC43128 0 212#define EFSYS_OPT_PHY_PM8358 0 213#define EFSYS_OPT_PHY_SFT9001 0 214#define EFSYS_OPT_PHY_QT2025C 0 215#define EFSYS_OPT_PHY_STATS 1 216#define EFSYS_OPT_PHY_PROPS 0 217#define EFSYS_OPT_PHY_BIST 1 218#define EFSYS_OPT_PHY_LED_CONTROL 1 219#define EFSYS_OPT_PHY_FLAGS 0 220 221#define EFSYS_OPT_VPD 1 222#define EFSYS_OPT_NVRAM 1 223#define EFSYS_OPT_NVRAM_FALCON_BOOTROM 0 224#define EFSYS_OPT_NVRAM_SFT9001 0 225#define EFSYS_OPT_NVRAM_SFX7101 0 226#define EFSYS_OPT_BOOTCFG 0 227 228#define EFSYS_OPT_PCIE_TUNE 0 229#define EFSYS_OPT_DIAG 0 230#define EFSYS_OPT_WOL 1 231#define EFSYS_OPT_RX_SCALE 1 232#define EFSYS_OPT_QSTATS 1 233#define EFSYS_OPT_FILTER 0 234#define EFSYS_OPT_RX_SCATTER 0 235#define EFSYS_OPT_RX_HDR_SPLIT 0 236 237#define EFSYS_OPT_EV_PREFETCH 0 238 239#define EFSYS_OPT_DECODE_INTR_FATAL 1 240 241/* ID */ 242 243typedef struct __efsys_identifier_s efsys_identifier_t; 244 245/* PROBE */ 246 247#ifndef KDTRACE_HOOKS 248 249#define EFSYS_PROBE(_name) 250 251#define EFSYS_PROBE1(_name, _type1, _arg1) 252 253#define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) 254 255#define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 256 _type3, _arg3) 257 258#define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 259 _type3, _arg3, _type4, _arg4) 260 261#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 262 _type3, _arg3, _type4, _arg4, _type5, _arg5) 263 264#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 265 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 266 _type6, _arg6) 267 268#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 269 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 270 _type6, _arg6, _type7, _arg7) 271 272#else /* KDTRACE_HOOKS */ 273 274#define EFSYS_PROBE(_name) \ 275 DTRACE_PROBE(_name) 276 277#define EFSYS_PROBE1(_name, _type1, _arg1) \ 278 DTRACE_PROBE1(_name, _type1, _arg1) 279 280#define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \ 281 DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2) 282 283#define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 284 _type3, _arg3) \ 285 DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 286 _type3, _arg3) 287 288#define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 289 _type3, _arg3, _type4, _arg4) \ 290 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 291 _type3, _arg3, _type4, _arg4) 292 293#ifdef DTRACE_PROBE5 294#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 295 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 296 DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 297 _type3, _arg3, _type4, _arg4, _type5, _arg5) 298#else 299#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 300 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 301 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 302 _type3, _arg3, _type4, _arg4) 303#endif 304 305#ifdef DTRACE_PROBE6 306#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 307 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 308 _type6, _arg6) \ 309 DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 310 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 311 _type6, _arg6) 312#else 313#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 314 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 315 _type6, _arg6) \ 316 EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 317 _type3, _arg3, _type4, _arg4, _type5, _arg5) 318#endif 319 320#ifdef DTRACE_PROBE7 321#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 322 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 323 _type6, _arg6, _type7, _arg7) \ 324 DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 325 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 326 _type6, _arg6, _type7, _arg7) 327#else 328#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 329 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 330 _type6, _arg6, _type7, _arg7) \ 331 EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 332 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 333 _type6, _arg6) 334#endif 335 336#endif /* KDTRACE_HOOKS */ 337 338/* DMA */ 339 340typedef uint64_t efsys_dma_addr_t; 341 342typedef struct efsys_mem_s { 343// bus_dma_tag_t esm_tag; 344// bus_dmamap_t esm_map; 345 caddr_t esm_base; 346 efsys_dma_addr_t esm_addr; 347 size_t esm_size; 348} efsys_mem_t; 349 350 351#define EFSYS_MEM_ZERO(_esmp, _size) \ 352 do { \ 353 (void) memset((_esmp)->esm_base, 0, (_size)); \ 354 \ 355 _NOTE(CONSTANTCONDITION) \ 356 } while (B_FALSE) 357 358#define EFSYS_MEM_READD(_esmp, _offset, _edp) \ 359 do { \ 360 uint32_t *addr; \ 361 \ 362 _NOTE(CONSTANTCONDITION) \ 363 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ 364 ("not power of 2 aligned")); \ 365 \ 366 addr = (void *)((_esmp)->esm_base + (_offset)); \ 367 \ 368 (_edp)->ed_u32[0] = *addr; \ 369 \ 370 EFSYS_PROBE2(mem_readd, unsigned int, (_offset), \ 371 uint32_t, (_edp)->ed_u32[0]); \ 372 \ 373 _NOTE(CONSTANTCONDITION) \ 374 } while (B_FALSE) 375 376#define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ 377 do { \ 378 uint32_t *addr; \ 379 \ 380 _NOTE(CONSTANTCONDITION) \ 381 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ 382 ("not power of 2 aligned")); \ 383 \ 384 addr = (void *)((_esmp)->esm_base + (_offset)); \ 385 \ 386 (_eqp)->eq_u32[0] = *addr++; \ 387 (_eqp)->eq_u32[1] = *addr; \ 388 \ 389 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ 390 uint32_t, (_eqp)->eq_u32[1], \ 391 uint32_t, (_eqp)->eq_u32[0]); \ 392 \ 393 _NOTE(CONSTANTCONDITION) \ 394 } while (B_FALSE) 395 396#define EFSYS_MEM_READO(_esmp, _offset, _eop) \ 397 do { \ 398 uint32_t *addr; \ 399 \ 400 _NOTE(CONSTANTCONDITION) \ 401 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ 402 ("not power of 2 aligned")); \ 403 \ 404 addr = (void *)((_esmp)->esm_base + (_offset)); \ 405 \ 406 (_eop)->eo_u32[0] = *addr++; \ 407 (_eop)->eo_u32[1] = *addr++; \ 408 (_eop)->eo_u32[2] = *addr++; \ 409 (_eop)->eo_u32[3] = *addr; \ 410 \ 411 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ 412 uint32_t, (_eop)->eo_u32[3], \ 413 uint32_t, (_eop)->eo_u32[2], \ 414 uint32_t, (_eop)->eo_u32[1], \ 415 uint32_t, (_eop)->eo_u32[0]); \ 416 \ 417 _NOTE(CONSTANTCONDITION) \ 418 } while (B_FALSE) 419 420#define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \ 421 do { \ 422 uint32_t *addr; \ 423 \ 424 _NOTE(CONSTANTCONDITION) \ 425 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ 426 ("not power of 2 aligned")); \ 427 \ 428 EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \ 429 uint32_t, (_edp)->ed_u32[0]); \ 430 \ 431 addr = (void *)((_esmp)->esm_base + (_offset)); \ 432 \ 433 *addr = (_edp)->ed_u32[0]; \ 434 \ 435 _NOTE(CONSTANTCONDITION) \ 436 } while (B_FALSE) 437 438#define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ 439 do { \ 440 uint32_t *addr; \ 441 \ 442 _NOTE(CONSTANTCONDITION) \ 443 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ 444 ("not power of 2 aligned")); \ 445 \ 446 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ 447 uint32_t, (_eqp)->eq_u32[1], \ 448 uint32_t, (_eqp)->eq_u32[0]); \ 449 \ 450 addr = (void *)((_esmp)->esm_base + (_offset)); \ 451 \ 452 *addr++ = (_eqp)->eq_u32[0]; \ 453 *addr = (_eqp)->eq_u32[1]; \ 454 \ 455 _NOTE(CONSTANTCONDITION) \ 456 } while (B_FALSE) 457 458#define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ 459 do { \ 460 uint32_t *addr; \ 461 \ 462 _NOTE(CONSTANTCONDITION) \ 463 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ 464 ("not power of 2 aligned")); \ 465 \ 466 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ 467 uint32_t, (_eop)->eo_u32[3], \ 468 uint32_t, (_eop)->eo_u32[2], \ 469 uint32_t, (_eop)->eo_u32[1], \ 470 uint32_t, (_eop)->eo_u32[0]); \ 471 \ 472 addr = (void *)((_esmp)->esm_base + (_offset)); \ 473 \ 474 *addr++ = (_eop)->eo_u32[0]; \ 475 *addr++ = (_eop)->eo_u32[1]; \ 476 *addr++ = (_eop)->eo_u32[2]; \ 477 *addr = (_eop)->eo_u32[3]; \ 478 \ 479 _NOTE(CONSTANTCONDITION) \ 480 } while (B_FALSE) 481 482#define EFSYS_MEM_ADDR(_esmp) \ 483 ((_esmp)->esm_addr) 484 485 486/* BAR */ 487typedef struct efsys_bar_s { 488 struct mtx esb_lock; 489 bus_space_tag_t esb_tag; 490 bus_space_handle_t esb_handle; 491 int esb_rid; 492// struct resource *esb_res; 493} efsys_bar_t; 494 495#define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \ 496 do { \ 497 _NOTE(CONSTANTCONDITION) \ 498 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ 499 ("not power of 2 aligned")); \ 500 \ 501 _NOTE(CONSTANTCONDITION) \ 502 if (_lock) \ 503 mtx_lock(&((_esbp)->esb_lock)); \ 504 \ 505 (_edp)->ed_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ 506 (_esbp)->esb_handle, (_offset)); \ 507 \ 508 EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \ 509 uint32_t, (_edp)->ed_u32[0]); \ 510 \ 511 _NOTE(CONSTANTCONDITION) \ 512 if (_lock) \ 513 mtx_unlock(&((_esbp)->esb_lock)); \ 514 _NOTE(CONSTANTCONDITION) \ 515 } while (B_FALSE) 516 517#define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ 518 do { \ 519 _NOTE(CONSTANTCONDITION) \ 520 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ 521 ("not power of 2 aligned")); \ 522 \ 523 mtx_lock(&((_esbp)->esb_lock)); \ 524 \ 525 (_eqp)->eq_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ 526 (_esbp)->esb_handle, (_offset)); \ 527 (_eqp)->eq_u32[1] = bus_space_read_4((_esbp)->esb_tag, \ 528 (_esbp)->esb_handle, (_offset+4)); \ 529 \ 530 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ 531 uint32_t, (_eqp)->eq_u32[1], \ 532 uint32_t, (_eqp)->eq_u32[0]); \ 533 \ 534 mtx_unlock(&((_esbp)->esb_lock)); \ 535 _NOTE(CONSTANTCONDITION) \ 536 } while (B_FALSE) 537 538#define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ 539 do { \ 540 _NOTE(CONSTANTCONDITION) \ 541 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ 542 ("not power of 2 aligned")); \ 543 \ 544 _NOTE(CONSTANTCONDITION) \ 545 if (_lock) \ 546 mtx_lock(&((_esbp)->esb_lock)); \ 547 \ 548 (_eop)->eo_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ 549 (_esbp)->esb_handle, (_offset)); \ 550 (_eop)->eo_u32[1] = bus_space_read_4((_esbp)->esb_tag, \ 551 (_esbp)->esb_handle, (_offset+4)); \ 552 (_eop)->eo_u32[2] = bus_space_read_4((_esbp)->esb_tag, \ 553 (_esbp)->esb_handle, (_offset+8)); \ 554 (_eop)->eo_u32[3] = bus_space_read_4((_esbp)->esb_tag, \ 555 (_esbp)->esb_handle, (_offset+12)); \ 556 \ 557 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ 558 uint32_t, (_eop)->eo_u32[3], \ 559 uint32_t, (_eop)->eo_u32[2], \ 560 uint32_t, (_eop)->eo_u32[1], \ 561 uint32_t, (_eop)->eo_u32[0]); \ 562 \ 563 _NOTE(CONSTANTCONDITION) \ 564 if (_lock) \ 565 mtx_unlock(&((_esbp)->esb_lock)); \ 566 _NOTE(CONSTANTCONDITION) \ 567 } while (B_FALSE) 568 569#define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \ 570 do { \ 571 _NOTE(CONSTANTCONDITION) \ 572 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ 573 ("not power of 2 aligned")); \ 574 \ 575 _NOTE(CONSTANTCONDITION) \ 576 if (_lock) \ 577 mtx_lock(&((_esbp)->esb_lock)); \ 578 \ 579 EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \ 580 uint32_t, (_edp)->ed_u32[0]); \ 581 \ 582 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 583 (_offset), (_edp)->ed_u32[0]); \ 584 \ 585 _NOTE(CONSTANTCONDITION) \ 586 if (_lock) \ 587 mtx_unlock(&((_esbp)->esb_lock)); \ 588 _NOTE(CONSTANTCONDITION) \ 589 } while (B_FALSE) 590 591#define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ 592 do { \ 593 _NOTE(CONSTANTCONDITION) \ 594 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ 595 ("not power of 2 aligned")); \ 596 \ 597 mtx_lock(&((_esbp)->esb_lock)); \ 598 \ 599 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ 600 uint32_t, (_eqp)->eq_u32[1], \ 601 uint32_t, (_eqp)->eq_u32[0]); \ 602 \ 603 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 604 (_offset), (_eqp)->eq_u32[0]); \ 605 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 606 (_offset+4), (_eqp)->eq_u32[1]); \ 607 \ 608 mtx_unlock(&((_esbp)->esb_lock)); \ 609 _NOTE(CONSTANTCONDITION) \ 610 } while (B_FALSE) 611 612#define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ 613 do { \ 614 _NOTE(CONSTANTCONDITION) \ 615 KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ 616 ("not power of 2 aligned")); \ 617 \ 618 _NOTE(CONSTANTCONDITION) \ 619 if (_lock) \ 620 mtx_lock(&((_esbp)->esb_lock)); \ 621 \ 622 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ 623 uint32_t, (_eop)->eo_u32[3], \ 624 uint32_t, (_eop)->eo_u32[2], \ 625 uint32_t, (_eop)->eo_u32[1], \ 626 uint32_t, (_eop)->eo_u32[0]); \ 627 \ 628 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 629 (_offset), (_eop)->eo_u32[0]); \ 630 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 631 (_offset+4), (_eop)->eo_u32[1]); \ 632 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 633 (_offset+8), (_eop)->eo_u32[2]); \ 634 bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ 635 (_offset+12), (_eop)->eo_u32[3]); \ 636 \ 637 _NOTE(CONSTANTCONDITION) \ 638 if (_lock) \ 639 mtx_unlock(&((_esbp)->esb_lock)); \ 640 _NOTE(CONSTANTCONDITION) \ 641 } while (B_FALSE) 642 643/* SPIN */ 644 645#define EFSYS_SPIN(_us) \ 646 do { \ 647 DELAY(_us); \ 648 _NOTE(CONSTANTCONDITION) \ 649 } while (B_FALSE) 650 651#define EFSYS_SLEEP EFSYS_SPIN 652 653/* BARRIERS */ 654 655/* Strict ordering guaranteed by devacc.devacc_attr_dataorder */ 656#define EFSYS_MEM_READ_BARRIER() 657#define EFSYS_PIO_WRITE_BARRIER() 658 659/* TIMESTAMP */ 660 661typedef clock_t efsys_timestamp_t; 662 663#define EFSYS_TIMESTAMP(_usp) \ 664 do { \ 665 clock_t now; \ 666 \ 667 now = ticks; \ 668 *(_usp) = now * hz / 1000000; \ 669 _NOTE(CONSTANTCONDITION) \ 670 } while (B_FALSE) 671 672/* KMEM */ 673 674#define EFSYS_KMEM_ALLOC(_esip, _size, _p) \ 675 do { \ 676 (void) (_esip); \ 677 (_p) = malloc((_size)); \ 678 if ((_p) != NULL) { \ 679 memset((_p), 0, (_size)); \ 680 } \ 681 _NOTE(CONSTANTCONDITION) \ 682 } while (B_FALSE) 683 684#define EFSYS_KMEM_FREE(_esip, _size, _p) \ 685 do { \ 686 (void) (_esip); \ 687 (void) (_size); \ 688 free((_p)); \ 689 _NOTE(CONSTANTCONDITION) \ 690 } while (B_FALSE) 691 692/* LOCK */ 693 694typedef struct mtx efsys_lock_t; 695 696#define EFSYS_LOCK_MAGIC 0x000010c4 697 698#define EFSYS_LOCK(_lockp, _state) \ 699 do { \ 700 mtx_lock(_lockp); \ 701 (_state) = EFSYS_LOCK_MAGIC; \ 702 _NOTE(CONSTANTCONDITION) \ 703 } while (B_FALSE) 704 705#define EFSYS_UNLOCK(_lockp, _state) \ 706 do { \ 707 if ((_state) != EFSYS_LOCK_MAGIC) \ 708 KASSERT(B_FALSE, ("not locked")); \ 709 mtx_unlock(_lockp); \ 710 _NOTE(CONSTANTCONDITION) \ 711 } while (B_FALSE) 712 713/* PREEMPT */ 714 715#define EFSYS_PREEMPT_DISABLE(_state) \ 716 do { \ 717 (_state) = (_state); \ 718 critical_enter(); \ 719 _NOTE(CONSTANTCONDITION) \ 720 } while (B_FALSE) 721 722#define EFSYS_PREEMPT_ENABLE(_state) \ 723 do { \ 724 (_state) = (_state); \ 725 critical_exit(_state); \ 726 _NOTE(CONSTANTCONDITION) \ 727 } while (B_FALSE) 728 729/* STAT */ 730 731typedef uint64_t efsys_stat_t; 732 733#define EFSYS_STAT_INCR(_knp, _delta) \ 734 do { \ 735 *(_knp) += (_delta); \ 736 _NOTE(CONSTANTCONDITION) \ 737 } while (B_FALSE) 738 739#define EFSYS_STAT_DECR(_knp, _delta) \ 740 do { \ 741 *(_knp) -= (_delta); \ 742 _NOTE(CONSTANTCONDITION) \ 743 } while (B_FALSE) 744 745#define EFSYS_STAT_SET(_knp, _val) \ 746 do { \ 747 *(_knp) = (_val); \ 748 _NOTE(CONSTANTCONDITION) \ 749 } while (B_FALSE) 750 751#define EFSYS_STAT_SET_QWORD(_knp, _valp) \ 752 do { \ 753 *(_knp) = le64toh((_valp)->eq_u64[0]); \ 754 _NOTE(CONSTANTCONDITION) \ 755 } while (B_FALSE) 756 757#define EFSYS_STAT_SET_DWORD(_knp, _valp) \ 758 do { \ 759 *(_knp) = le32toh((_valp)->ed_u32[0]); \ 760 _NOTE(CONSTANTCONDITION) \ 761 } while (B_FALSE) 762 763#define EFSYS_STAT_INCR_QWORD(_knp, _valp) \ 764 do { \ 765 *(_knp) += le64toh((_valp)->eq_u64[0]); \ 766 _NOTE(CONSTANTCONDITION) \ 767 } while (B_FALSE) 768 769#define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \ 770 do { \ 771 *(_knp) -= le64toh((_valp)->eq_u64[0]); \ 772 _NOTE(CONSTANTCONDITION) \ 773 } while (B_FALSE) 774 775/* ERR */ 776 777extern void sfxge_err(efsys_identifier_t *, unsigned int, 778 uint32_t, uint32_t); 779 780#if EFSYS_OPT_DECODE_INTR_FATAL 781#define EFSYS_ERR(_esip, _code, _dword0, _dword1) \ 782 do { \ 783 sfxge_err((_esip), (_code), (_dword0), (_dword1)); \ 784 _NOTE(CONSTANTCONDITION) \ 785 } while (B_FALSE) 786#endif 787 788/* ASSERT */ 789 790#define EFSYS_ASSERT(_exp) do { \ 791 if (!(_exp)) \ 792 panic(#_exp); \ 793 } while (0) 794 795#define EFSYS_ASSERT3(_x, _op, _y, _t) do { \ 796 const _t __x = (_t)(_x); \ 797 const _t __y = (_t)(_y); \ 798 if (!(__x _op __y)) \ 799 panic("assertion failed at %s:%u", __FILE__, __LINE__); \ 800 } while(0) 801 802#define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t) 803#define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t) 804#define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t) 805 806#ifdef __cplusplus 807} 808#endif 809 810#endif /* _SYS_EFSYS_H */ 811