1 /*- 2 * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "efsys.h" 27 #include "efx.h" 28 #include "efx_types.h" 29 #include "efx_regs.h" 30 #include "efx_impl.h" 31 32 __checkReturn int 33 efx_family( 34 __in uint16_t venid, 35 __in uint16_t devid, 36 __out efx_family_t *efp) 37 { 38 #if EFSYS_OPT_FALCON 39 if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_FALCON) { 40 *efp = EFX_FAMILY_FALCON; 41 return (0); 42 } 43 #endif 44 #if EFSYS_OPT_SIENA 45 if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_BETHPAGE) { 46 *efp = EFX_FAMILY_SIENA; 47 return (0); 48 } 49 if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_SIENA) { 50 *efp = EFX_FAMILY_SIENA; 51 return (0); 52 } 53 if (venid == EFX_PCI_VENID_SFC && 54 devid == EFX_PCI_DEVID_SIENA_F1_UNINIT) { 55 *efp = EFX_FAMILY_SIENA; 56 return (0); 57 } 58 #endif 59 return (ENOTSUP); 60 } 61 62 /* 63 * To support clients which aren't provided with any PCI context infer 64 * the hardware family by inspecting the hardware. Obviously the caller 65 * must be damn sure they're really talking to a supported device. 66 */ 67 __checkReturn int 68 efx_infer_family( 69 __in efsys_bar_t *esbp, 70 __out efx_family_t *efp) 71 { 72 efx_family_t family; 73 efx_oword_t oword; 74 unsigned int portnum; 75 int rc; 76 77 EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE); 78 portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM); 79 switch (portnum) { 80 #if EFSYS_OPT_FALCON 81 case 0: 82 family = EFX_FAMILY_FALCON; 83 break; 84 #endif 85 #if EFSYS_OPT_SIENA 86 case 1: 87 case 2: 88 family = EFX_FAMILY_SIENA; 89 break; 90 #endif 91 default: 92 rc = ENOTSUP; 93 goto fail1; 94 } 95 96 if (efp != NULL) 97 *efp = family; 98 return (0); 99 100 fail1: 101 EFSYS_PROBE1(fail1, int, rc); 102 103 return (rc); 104 } 105 106 /* 107 * The built-in default value device id for port 1 of Siena is 0x0810. 108 * manftest needs to be able to cope with that. 109 */ 110 111 #define EFX_BIU_MAGIC0 0x01234567 112 #define EFX_BIU_MAGIC1 0xfedcba98 113 114 static __checkReturn int 115 efx_nic_biu_test( 116 __in efx_nic_t *enp) 117 { 118 efx_oword_t oword; 119 int rc; 120 121 /* 122 * Write magic values to scratch registers 0 and 1, then 123 * verify that the values were written correctly. Interleave 124 * the accesses to ensure that the BIU is not just reading 125 * back the cached value that was last written. 126 */ 127 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); 128 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword); 129 130 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); 131 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword); 132 133 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword); 134 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { 135 rc = EIO; 136 goto fail1; 137 } 138 139 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword); 140 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { 141 rc = EIO; 142 goto fail2; 143 } 144 145 /* 146 * Perform the same test, with the values swapped. This 147 * ensures that subsequent tests don't start with the correct 148 * values already written into the scratch registers. 149 */ 150 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); 151 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword); 152 153 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); 154 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword); 155 156 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword); 157 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { 158 rc = EIO; 159 goto fail3; 160 } 161 162 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword); 163 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { 164 rc = EIO; 165 goto fail4; 166 } 167 168 return (0); 169 170 fail4: 171 EFSYS_PROBE(fail4); 172 fail3: 173 EFSYS_PROBE(fail3); 174 fail2: 175 EFSYS_PROBE(fail2); 176 fail1: 177 EFSYS_PROBE1(fail1, int, rc); 178 179 return (rc); 180 } 181 182 #if EFSYS_OPT_FALCON 183 184 static efx_nic_ops_t __cs __efx_nic_falcon_ops = { 185 falcon_nic_probe, /* eno_probe */ 186 falcon_nic_reset, /* eno_reset */ 187 falcon_nic_init, /* eno_init */ 188 #if EFSYS_OPT_DIAG 189 falcon_sram_test, /* eno_sram_test */ 190 falcon_nic_register_test, /* eno_register_test */ 191 #endif /* EFSYS_OPT_DIAG */ 192 falcon_nic_fini, /* eno_fini */ 193 falcon_nic_unprobe, /* eno_unprobe */ 194 }; 195 196 #endif /* EFSYS_OPT_FALCON */ 197 198 #if EFSYS_OPT_SIENA 199 200 static efx_nic_ops_t __cs __efx_nic_siena_ops = { 201 siena_nic_probe, /* eno_probe */ 202 siena_nic_reset, /* eno_reset */ 203 siena_nic_init, /* eno_init */ 204 #if EFSYS_OPT_DIAG 205 siena_sram_test, /* eno_sram_test */ 206 siena_nic_register_test, /* eno_register_test */ 207 #endif /* EFSYS_OPT_DIAG */ 208 siena_nic_fini, /* eno_fini */ 209 siena_nic_unprobe, /* eno_unprobe */ 210 }; 211 212 #endif /* EFSYS_OPT_SIENA */ 213 214 __checkReturn int 215 efx_nic_create( 216 __in efx_family_t family, 217 __in efsys_identifier_t *esip, 218 __in efsys_bar_t *esbp, 219 __in efsys_lock_t *eslp, 220 __deref_out efx_nic_t **enpp) 221 { 222 efx_nic_t *enp; 223 int rc; 224 225 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID); 226 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES); 227 228 /* Allocate a NIC object */ 229 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp); 230 231 if (enp == NULL) { 232 rc = ENOMEM; 233 goto fail1; 234 } 235 236 enp->en_magic = EFX_NIC_MAGIC; 237 238 switch (family) { 239 #if EFSYS_OPT_FALCON 240 case EFX_FAMILY_FALCON: 241 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_falcon_ops; 242 enp->en_features = 0; 243 break; 244 #endif /* EFSYS_OPT_FALCON */ 245 246 #if EFSYS_OPT_SIENA 247 case EFX_FAMILY_SIENA: 248 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_siena_ops; 249 enp->en_features = EFX_FEATURE_IPV6 | 250 EFX_FEATURE_LFSR_HASH_INSERT | 251 EFX_FEATURE_LINK_EVENTS | EFX_FEATURE_PERIODIC_MAC_STATS | 252 EFX_FEATURE_WOL | EFX_FEATURE_MCDI | 253 EFX_FEATURE_LOOKAHEAD_SPLIT | EFX_FEATURE_MAC_HEADER_FILTERS; 254 break; 255 #endif /* EFSYS_OPT_SIENA */ 256 257 default: 258 rc = ENOTSUP; 259 goto fail2; 260 } 261 262 enp->en_family = family; 263 enp->en_esip = esip; 264 enp->en_esbp = esbp; 265 enp->en_eslp = eslp; 266 267 *enpp = enp; 268 269 return (0); 270 271 fail2: 272 EFSYS_PROBE(fail3); 273 274 enp->en_magic = 0; 275 276 /* Free the NIC object */ 277 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 278 279 fail1: 280 EFSYS_PROBE1(fail1, int, rc); 281 282 return (rc); 283 } 284 285 __checkReturn int 286 efx_nic_probe( 287 __in efx_nic_t *enp) 288 { 289 efx_nic_ops_t *enop; 290 efx_oword_t oword; 291 int rc; 292 293 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 294 #if EFSYS_OPT_MCDI 295 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 296 #endif /* EFSYS_OPT_MCDI */ 297 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE)); 298 299 /* Test BIU */ 300 if ((rc = efx_nic_biu_test(enp)) != 0) 301 goto fail1; 302 303 /* Clear the region register */ 304 EFX_POPULATE_OWORD_4(oword, 305 FRF_AZ_ADR_REGION0, 0, 306 FRF_AZ_ADR_REGION1, (1 << 16), 307 FRF_AZ_ADR_REGION2, (2 << 16), 308 FRF_AZ_ADR_REGION3, (3 << 16)); 309 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 310 311 enop = enp->en_enop; 312 if ((rc = enop->eno_probe(enp)) != 0) 313 goto fail2; 314 315 if ((rc = efx_phy_probe(enp)) != 0) 316 goto fail3; 317 318 enp->en_mod_flags |= EFX_MOD_PROBE; 319 320 return (0); 321 322 fail3: 323 EFSYS_PROBE(fail3); 324 325 enop->eno_unprobe(enp); 326 327 fail2: 328 EFSYS_PROBE(fail2); 329 fail1: 330 EFSYS_PROBE1(fail1, int, rc); 331 332 return (rc); 333 } 334 335 #if EFSYS_OPT_PCIE_TUNE 336 337 __checkReturn int 338 efx_nic_pcie_tune( 339 __in efx_nic_t *enp, 340 unsigned int nlanes) 341 { 342 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 343 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 344 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 345 346 #if EFSYS_OPT_FALCON 347 if (enp->en_family == EFX_FAMILY_FALCON) 348 return (falcon_nic_pcie_tune(enp, nlanes)); 349 #endif 350 return (ENOTSUP); 351 } 352 353 __checkReturn int 354 efx_nic_pcie_extended_sync( 355 __in efx_nic_t *enp) 356 { 357 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 358 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 359 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 360 361 #if EFSYS_OPT_SIENA 362 if (enp->en_family == EFX_FAMILY_SIENA) 363 return (siena_nic_pcie_extended_sync(enp)); 364 #endif 365 366 return (ENOTSUP); 367 } 368 369 #endif /* EFSYS_OPT_PCIE_TUNE */ 370 371 __checkReturn int 372 efx_nic_init( 373 __in efx_nic_t *enp) 374 { 375 efx_nic_ops_t *enop = enp->en_enop; 376 int rc; 377 378 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 379 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 380 381 if (enp->en_mod_flags & EFX_MOD_NIC) { 382 rc = EINVAL; 383 goto fail1; 384 } 385 386 if ((rc = enop->eno_init(enp)) != 0) 387 goto fail2; 388 389 enp->en_mod_flags |= EFX_MOD_NIC; 390 391 return (0); 392 393 fail2: 394 EFSYS_PROBE(fail2); 395 fail1: 396 EFSYS_PROBE1(fail1, int, rc); 397 398 return (rc); 399 } 400 401 void 402 efx_nic_fini( 403 __in efx_nic_t *enp) 404 { 405 efx_nic_ops_t *enop = enp->en_enop; 406 407 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 408 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 409 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC); 410 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 411 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 412 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 413 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 414 415 enop->eno_fini(enp); 416 417 enp->en_mod_flags &= ~EFX_MOD_NIC; 418 } 419 420 void 421 efx_nic_unprobe( 422 __in efx_nic_t *enp) 423 { 424 efx_nic_ops_t *enop = enp->en_enop; 425 426 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 427 #if EFSYS_OPT_MCDI 428 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 429 #endif /* EFSYS_OPT_MCDI */ 430 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 431 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 432 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 433 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 434 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 435 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 436 437 efx_phy_unprobe(enp); 438 439 enop->eno_unprobe(enp); 440 441 enp->en_mod_flags &= ~EFX_MOD_PROBE; 442 } 443 444 void 445 efx_nic_destroy( 446 __in efx_nic_t *enp) 447 { 448 efsys_identifier_t *esip = enp->en_esip; 449 450 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 451 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0); 452 453 enp->en_family = 0; 454 enp->en_esip = NULL; 455 enp->en_esbp = NULL; 456 enp->en_eslp = NULL; 457 458 enp->en_enop = NULL; 459 460 enp->en_magic = 0; 461 462 /* Free the NIC object */ 463 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 464 } 465 466 __checkReturn int 467 efx_nic_reset( 468 __in efx_nic_t *enp) 469 { 470 efx_nic_ops_t *enop = enp->en_enop; 471 unsigned int mod_flags; 472 int rc; 473 474 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 475 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 476 /* 477 * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we 478 * do not reset here) must have been shut down or never initialized. 479 * 480 * A rule of thumb here is: If the controller or MC reboots, is *any* 481 * state lost. If it's lost and needs reapplying, then the module 482 * *must* not be initialised during the reset. 483 */ 484 mod_flags = enp->en_mod_flags; 485 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM | 486 EFX_MOD_VPD | EFX_MOD_MON); 487 EFSYS_ASSERT3U(mod_flags, ==, 0); 488 if (mod_flags != 0) { 489 rc = EINVAL; 490 goto fail1; 491 } 492 493 if ((rc = enop->eno_reset(enp)) != 0) 494 goto fail2; 495 496 enp->en_reset_flags |= EFX_RESET_MAC; 497 498 return (0); 499 500 fail2: 501 EFSYS_PROBE(fail2); 502 fail1: 503 EFSYS_PROBE1(fail1, int, rc); 504 505 return (rc); 506 } 507 508 const efx_nic_cfg_t * 509 efx_nic_cfg_get( 510 __in efx_nic_t *enp) 511 { 512 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 513 514 return (&(enp->en_nic_cfg)); 515 } 516 517 #if EFSYS_OPT_DIAG 518 519 __checkReturn int 520 efx_nic_register_test( 521 __in efx_nic_t *enp) 522 { 523 efx_nic_ops_t *enop = enp->en_enop; 524 int rc; 525 526 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 527 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 528 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 529 530 if ((rc = enop->eno_register_test(enp)) != 0) 531 goto fail1; 532 533 return (0); 534 535 fail1: 536 EFSYS_PROBE1(fail1, int, rc); 537 538 return (rc); 539 } 540 541 __checkReturn int 542 efx_nic_test_registers( 543 __in efx_nic_t *enp, 544 __in efx_register_set_t *rsp, 545 __in size_t count) 546 { 547 unsigned int bit; 548 efx_oword_t original; 549 efx_oword_t reg; 550 efx_oword_t buf; 551 int rc; 552 553 while (count > 0) { 554 /* This function is only suitable for registers */ 555 EFSYS_ASSERT(rsp->rows == 1); 556 557 /* bit sweep on and off */ 558 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original, 559 B_TRUE); 560 for (bit = 0; bit < 128; bit++) { 561 /* Is this bit in the mask? */ 562 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit)) 563 continue; 564 565 /* Test this bit can be set in isolation */ 566 reg = original; 567 EFX_AND_OWORD(reg, rsp->mask); 568 EFX_SET_OWORD_BIT(reg, bit); 569 570 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 571 B_TRUE); 572 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 573 B_TRUE); 574 575 EFX_AND_OWORD(buf, rsp->mask); 576 if (memcmp(®, &buf, sizeof (reg))) { 577 rc = EIO; 578 goto fail1; 579 } 580 581 /* Test this bit can be cleared in isolation */ 582 EFX_OR_OWORD(reg, rsp->mask); 583 EFX_CLEAR_OWORD_BIT(reg, bit); 584 585 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 586 B_TRUE); 587 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 588 B_TRUE); 589 590 EFX_AND_OWORD(buf, rsp->mask); 591 if (memcmp(®, &buf, sizeof (reg))) { 592 rc = EIO; 593 goto fail2; 594 } 595 } 596 597 /* Restore the old value */ 598 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, 599 B_TRUE); 600 601 --count; 602 ++rsp; 603 } 604 605 return (0); 606 607 fail2: 608 EFSYS_PROBE(fail2); 609 fail1: 610 EFSYS_PROBE1(fail1, int, rc); 611 612 /* Restore the old value */ 613 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE); 614 615 return (rc); 616 } 617 618 __checkReturn int 619 efx_nic_test_tables( 620 __in efx_nic_t *enp, 621 __in efx_register_set_t *rsp, 622 __in efx_pattern_type_t pattern, 623 __in size_t count) 624 { 625 efx_sram_pattern_fn_t func; 626 unsigned int index; 627 unsigned int address; 628 efx_oword_t reg; 629 efx_oword_t buf; 630 int rc; 631 632 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES); 633 func = __efx_sram_pattern_fns[pattern]; 634 635 while (count > 0) { 636 /* Write */ 637 address = rsp->address; 638 for (index = 0; index < rsp->rows; ++index) { 639 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 640 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 641 EFX_AND_OWORD(reg, rsp->mask); 642 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE); 643 644 address += rsp->step; 645 } 646 647 /* Read */ 648 address = rsp->address; 649 for (index = 0; index < rsp->rows; ++index) { 650 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 651 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 652 EFX_AND_OWORD(reg, rsp->mask); 653 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE); 654 if (memcmp(®, &buf, sizeof (reg))) { 655 rc = EIO; 656 goto fail1; 657 } 658 659 address += rsp->step; 660 } 661 662 ++rsp; 663 --count; 664 } 665 666 return (0); 667 668 fail1: 669 EFSYS_PROBE1(fail1, int, rc); 670 671 return (rc); 672 } 673 674 #endif /* EFSYS_OPT_DIAG */ 675