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