33 34#include "efx.h" 35#include "efx_impl.h" 36 37 __checkReturn efx_rc_t 38efx_family( 39 __in uint16_t venid, 40 __in uint16_t devid, 41 __out efx_family_t *efp) 42{ 43 if (venid == EFX_PCI_VENID_SFC) { 44 switch (devid) { 45#if EFSYS_OPT_FALCON 46 case EFX_PCI_DEVID_FALCON: 47 *efp = EFX_FAMILY_FALCON; 48 return (0); 49#endif /* EFSYS_OPT_FALCON */ 50 51#if EFSYS_OPT_SIENA 52 case EFX_PCI_DEVID_SIENA_F1_UNINIT: 53 /* 54 * Hardware default for PF0 of uninitialised Siena. 55 * manftest must be able to cope with this device id. 56 */ 57 *efp = EFX_FAMILY_SIENA; 58 return (0); 59 60 case EFX_PCI_DEVID_BETHPAGE: 61 case EFX_PCI_DEVID_SIENA: 62 *efp = EFX_FAMILY_SIENA; 63 return (0); 64#endif /* EFSYS_OPT_SIENA */ 65 66#if EFSYS_OPT_HUNTINGTON 67 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT: 68 /* 69 * Hardware default for PF0 of uninitialised Huntington. 70 * manftest must be able to cope with this device id. 71 */ 72 *efp = EFX_FAMILY_HUNTINGTON; 73 return (0); 74 75 case EFX_PCI_DEVID_FARMINGDALE: 76 case EFX_PCI_DEVID_GREENPORT: 77 *efp = EFX_FAMILY_HUNTINGTON; 78 return (0); 79 80 case EFX_PCI_DEVID_FARMINGDALE_VF: 81 case EFX_PCI_DEVID_GREENPORT_VF: 82 *efp = EFX_FAMILY_HUNTINGTON; 83 return (0); 84#endif /* EFSYS_OPT_HUNTINGTON */ 85 86#if EFSYS_OPT_MEDFORD 87 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT: 88 /* 89 * Hardware default for PF0 of uninitialised Medford. 90 * manftest must be able to cope with this device id. 91 */ 92 *efp = EFX_FAMILY_MEDFORD; 93 return (0); 94 95 case EFX_PCI_DEVID_MEDFORD: 96 *efp = EFX_FAMILY_MEDFORD; 97 return (0); 98 99 case EFX_PCI_DEVID_MEDFORD_VF: 100 *efp = EFX_FAMILY_MEDFORD; 101 return (0); 102#endif /* EFSYS_OPT_MEDFORD */ 103 104 default: 105 break; 106 } 107 } 108 109 *efp = EFX_FAMILY_INVALID; 110 return (ENOTSUP); 111} 112 113/* 114 * To support clients which aren't provided with any PCI context infer 115 * the hardware family by inspecting the hardware. Obviously the caller 116 * must be damn sure they're really talking to a supported device. 117 */ 118 __checkReturn efx_rc_t 119efx_infer_family( 120 __in efsys_bar_t *esbp, 121 __out efx_family_t *efp) 122{ 123 efx_family_t family; 124 efx_oword_t oword; 125 unsigned int portnum; 126 efx_rc_t rc; 127 128 EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE); 129 portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM); 130 if ((portnum == 1) || (portnum == 2)) { 131#if EFSYS_OPT_SIENA 132 family = EFX_FAMILY_SIENA; 133 goto out; 134#endif 135 } else if (portnum == 0) { 136 efx_dword_t dword; 137 uint32_t hw_rev; 138 139 EFSYS_BAR_READD(esbp, ER_DZ_BIU_HW_REV_ID_REG_OFST, &dword, 140 B_TRUE); 141 hw_rev = EFX_DWORD_FIELD(dword, ERF_DZ_HW_REV_ID); 142 if (hw_rev == ER_DZ_BIU_HW_REV_ID_REG_RESET) { 143#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 144 /* 145 * BIU_HW_REV_ID is the same for Huntington and Medford. 146 * Assume Huntington, as Medford is very similar. 147 */ 148 family = EFX_FAMILY_HUNTINGTON; 149 goto out; 150#endif 151 } else { 152#if EFSYS_OPT_FALCON 153 family = EFX_FAMILY_FALCON; 154 goto out; 155#endif 156 } 157 } 158 rc = ENOTSUP; 159 goto fail1; 160 161out: 162 if (efp != NULL) 163 *efp = family; 164 return (0); 165 166fail1: 167 EFSYS_PROBE1(fail1, efx_rc_t, rc); 168 169 return (rc); 170} 171 172#define EFX_BIU_MAGIC0 0x01234567 173#define EFX_BIU_MAGIC1 0xfedcba98 174 175 __checkReturn efx_rc_t 176efx_nic_biu_test( 177 __in efx_nic_t *enp) 178{ 179 efx_oword_t oword; 180 efx_rc_t rc; 181 182 /* 183 * Write magic values to scratch registers 0 and 1, then 184 * verify that the values were written correctly. Interleave 185 * the accesses to ensure that the BIU is not just reading 186 * back the cached value that was last written. 187 */ 188 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); 189 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 190 191 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); 192 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 193 194 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 195 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { 196 rc = EIO; 197 goto fail1; 198 } 199 200 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 201 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { 202 rc = EIO; 203 goto fail2; 204 } 205 206 /* 207 * Perform the same test, with the values swapped. This 208 * ensures that subsequent tests don't start with the correct 209 * values already written into the scratch registers. 210 */ 211 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); 212 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 213 214 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); 215 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 216 217 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 218 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { 219 rc = EIO; 220 goto fail3; 221 } 222 223 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 224 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { 225 rc = EIO; 226 goto fail4; 227 } 228 229 return (0); 230 231fail4: 232 EFSYS_PROBE(fail4); 233fail3: 234 EFSYS_PROBE(fail3); 235fail2: 236 EFSYS_PROBE(fail2); 237fail1: 238 EFSYS_PROBE1(fail1, efx_rc_t, rc); 239 240 return (rc); 241} 242 243#if EFSYS_OPT_FALCON 244 245static efx_nic_ops_t __efx_nic_falcon_ops = { 246 falcon_nic_probe, /* eno_probe */ 247 NULL, /* eno_board_cfg */ 248 NULL, /* eno_set_drv_limits */ 249 falcon_nic_reset, /* eno_reset */ 250 falcon_nic_init, /* eno_init */ 251 NULL, /* eno_get_vi_pool */ 252 NULL, /* eno_get_bar_region */ 253#if EFSYS_OPT_DIAG 254 falcon_sram_test, /* eno_sram_test */ 255 falcon_nic_register_test, /* eno_register_test */ 256#endif /* EFSYS_OPT_DIAG */ 257 falcon_nic_fini, /* eno_fini */ 258 falcon_nic_unprobe, /* eno_unprobe */ 259}; 260 261#endif /* EFSYS_OPT_FALCON */ 262 263#if EFSYS_OPT_SIENA 264 265static efx_nic_ops_t __efx_nic_siena_ops = { 266 siena_nic_probe, /* eno_probe */ 267 NULL, /* eno_board_cfg */ 268 NULL, /* eno_set_drv_limits */ 269 siena_nic_reset, /* eno_reset */ 270 siena_nic_init, /* eno_init */ 271 NULL, /* eno_get_vi_pool */ 272 NULL, /* eno_get_bar_region */ 273#if EFSYS_OPT_DIAG 274 siena_sram_test, /* eno_sram_test */ 275 siena_nic_register_test, /* eno_register_test */ 276#endif /* EFSYS_OPT_DIAG */ 277 siena_nic_fini, /* eno_fini */ 278 siena_nic_unprobe, /* eno_unprobe */ 279}; 280 281#endif /* EFSYS_OPT_SIENA */ 282 283#if EFSYS_OPT_HUNTINGTON 284 285static efx_nic_ops_t __efx_nic_hunt_ops = { 286 ef10_nic_probe, /* eno_probe */ 287 hunt_board_cfg, /* eno_board_cfg */ 288 ef10_nic_set_drv_limits, /* eno_set_drv_limits */ 289 ef10_nic_reset, /* eno_reset */ 290 ef10_nic_init, /* eno_init */ 291 ef10_nic_get_vi_pool, /* eno_get_vi_pool */ 292 ef10_nic_get_bar_region, /* eno_get_bar_region */ 293#if EFSYS_OPT_DIAG 294 ef10_sram_test, /* eno_sram_test */ 295 ef10_nic_register_test, /* eno_register_test */ 296#endif /* EFSYS_OPT_DIAG */ 297 ef10_nic_fini, /* eno_fini */ 298 ef10_nic_unprobe, /* eno_unprobe */ 299}; 300 301#endif /* EFSYS_OPT_HUNTINGTON */ 302 303#if EFSYS_OPT_MEDFORD 304 305static efx_nic_ops_t __efx_nic_medford_ops = { 306 ef10_nic_probe, /* eno_probe */ 307 medford_board_cfg, /* eno_board_cfg */ 308 ef10_nic_set_drv_limits, /* eno_set_drv_limits */ 309 ef10_nic_reset, /* eno_reset */ 310 ef10_nic_init, /* eno_init */ 311 ef10_nic_get_vi_pool, /* eno_get_vi_pool */ 312 ef10_nic_get_bar_region, /* eno_get_bar_region */ 313#if EFSYS_OPT_DIAG 314 ef10_sram_test, /* eno_sram_test */ 315 ef10_nic_register_test, /* eno_register_test */ 316#endif /* EFSYS_OPT_DIAG */ 317 ef10_nic_fini, /* eno_fini */ 318 ef10_nic_unprobe, /* eno_unprobe */ 319}; 320 321#endif /* EFSYS_OPT_MEDFORD */ 322 323 324 __checkReturn efx_rc_t 325efx_nic_create( 326 __in efx_family_t family, 327 __in efsys_identifier_t *esip, 328 __in efsys_bar_t *esbp, 329 __in efsys_lock_t *eslp, 330 __deref_out efx_nic_t **enpp) 331{ 332 efx_nic_t *enp; 333 efx_rc_t rc; 334 335 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID); 336 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES); 337 338 /* Allocate a NIC object */ 339 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp); 340 341 if (enp == NULL) { 342 rc = ENOMEM; 343 goto fail1; 344 } 345 346 enp->en_magic = EFX_NIC_MAGIC; 347 348 switch (family) { 349#if EFSYS_OPT_FALCON 350 case EFX_FAMILY_FALCON: 351 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_falcon_ops; 352 enp->en_features = 0; 353 break; 354#endif /* EFSYS_OPT_FALCON */ 355 356#if EFSYS_OPT_SIENA 357 case EFX_FAMILY_SIENA: 358 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_siena_ops; 359 enp->en_features = 360 EFX_FEATURE_IPV6 | 361 EFX_FEATURE_LFSR_HASH_INSERT | 362 EFX_FEATURE_LINK_EVENTS | 363 EFX_FEATURE_PERIODIC_MAC_STATS | 364 EFX_FEATURE_WOL | 365 EFX_FEATURE_MCDI | 366 EFX_FEATURE_LOOKAHEAD_SPLIT | 367 EFX_FEATURE_MAC_HEADER_FILTERS | 368 EFX_FEATURE_TX_SRC_FILTERS; 369 break; 370#endif /* EFSYS_OPT_SIENA */ 371 372#if EFSYS_OPT_HUNTINGTON 373 case EFX_FAMILY_HUNTINGTON: 374 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_hunt_ops; 375 /* FIXME: Add WOL support */ 376 enp->en_features = 377 EFX_FEATURE_IPV6 | 378 EFX_FEATURE_LINK_EVENTS | 379 EFX_FEATURE_PERIODIC_MAC_STATS | 380 EFX_FEATURE_MCDI | 381 EFX_FEATURE_MAC_HEADER_FILTERS | 382 EFX_FEATURE_MCDI_DMA | 383 EFX_FEATURE_PIO_BUFFERS |
|
386 break; 387#endif /* EFSYS_OPT_HUNTINGTON */ 388 389#if EFSYS_OPT_MEDFORD 390 case EFX_FAMILY_MEDFORD: 391 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_medford_ops; 392 /* 393 * FW_ASSISTED_TSO ommitted as Medford only supports firmware 394 * assisted TSO version 2, not the v1 scheme used on Huntington. 395 */ 396 enp->en_features = 397 EFX_FEATURE_IPV6 | 398 EFX_FEATURE_LINK_EVENTS | 399 EFX_FEATURE_PERIODIC_MAC_STATS | 400 EFX_FEATURE_MCDI | 401 EFX_FEATURE_MAC_HEADER_FILTERS | 402 EFX_FEATURE_MCDI_DMA | 403 EFX_FEATURE_PIO_BUFFERS; 404 break; 405#endif /* EFSYS_OPT_MEDFORD */ 406 407 default: 408 rc = ENOTSUP; 409 goto fail2; 410 } 411 412 enp->en_family = family; 413 enp->en_esip = esip; 414 enp->en_esbp = esbp; 415 enp->en_eslp = eslp; 416 417 *enpp = enp; 418 419 return (0); 420 421fail2: 422 EFSYS_PROBE(fail2); 423 424 enp->en_magic = 0; 425 426 /* Free the NIC object */ 427 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 428 429fail1: 430 EFSYS_PROBE1(fail1, efx_rc_t, rc); 431 432 return (rc); 433} 434 435 __checkReturn efx_rc_t 436efx_nic_probe( 437 __in efx_nic_t *enp) 438{ 439 efx_nic_ops_t *enop; 440 efx_rc_t rc; 441 442 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 443#if EFSYS_OPT_MCDI 444 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 445#endif /* EFSYS_OPT_MCDI */ 446 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE)); 447 448 enop = enp->en_enop; 449 if ((rc = enop->eno_probe(enp)) != 0) 450 goto fail1; 451 452 if ((rc = efx_phy_probe(enp)) != 0) 453 goto fail2; 454 455 enp->en_mod_flags |= EFX_MOD_PROBE; 456 457 return (0); 458 459fail2: 460 EFSYS_PROBE(fail2); 461 462 enop->eno_unprobe(enp); 463 464fail1: 465 EFSYS_PROBE1(fail1, efx_rc_t, rc); 466 467 return (rc); 468} 469 470#if EFSYS_OPT_PCIE_TUNE 471 472 __checkReturn efx_rc_t 473efx_nic_pcie_tune( 474 __in efx_nic_t *enp, 475 unsigned int nlanes) 476{ 477 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 478 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 479 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 480 481#if EFSYS_OPT_FALCON 482 if (enp->en_family == EFX_FAMILY_FALCON) 483 return (falcon_nic_pcie_tune(enp, nlanes)); 484#endif 485 return (ENOTSUP); 486} 487 488 __checkReturn efx_rc_t 489efx_nic_pcie_extended_sync( 490 __in efx_nic_t *enp) 491{ 492 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 493 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 494 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 495 496#if EFSYS_OPT_SIENA 497 if (enp->en_family == EFX_FAMILY_SIENA) 498 return (siena_nic_pcie_extended_sync(enp)); 499#endif 500 501 return (ENOTSUP); 502} 503 504#endif /* EFSYS_OPT_PCIE_TUNE */ 505 506 __checkReturn efx_rc_t 507efx_nic_set_drv_limits( 508 __inout efx_nic_t *enp, 509 __in efx_drv_limits_t *edlp) 510{ 511 efx_nic_ops_t *enop = enp->en_enop; 512 efx_rc_t rc; 513 514 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 515 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 516 517 if (enop->eno_set_drv_limits != NULL) { 518 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0) 519 goto fail1; 520 } 521 522 return (0); 523 524fail1: 525 EFSYS_PROBE1(fail1, efx_rc_t, rc); 526 527 return (rc); 528} 529 530 __checkReturn efx_rc_t 531efx_nic_get_bar_region( 532 __in efx_nic_t *enp, 533 __in efx_nic_region_t region, 534 __out uint32_t *offsetp, 535 __out size_t *sizep) 536{ 537 efx_nic_ops_t *enop = enp->en_enop; 538 efx_rc_t rc; 539 540 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 541 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 542 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 543 544 if (enop->eno_get_bar_region == NULL) { 545 rc = ENOTSUP; 546 goto fail1; 547 } 548 if ((rc = (enop->eno_get_bar_region)(enp, 549 region, offsetp, sizep)) != 0) { 550 goto fail2; 551 } 552 553 return (0); 554 555fail2: 556 EFSYS_PROBE(fail2); 557 558fail1: 559 EFSYS_PROBE1(fail1, efx_rc_t, rc); 560 561 return (rc); 562} 563 564 565 __checkReturn efx_rc_t 566efx_nic_get_vi_pool( 567 __in efx_nic_t *enp, 568 __out uint32_t *evq_countp, 569 __out uint32_t *rxq_countp, 570 __out uint32_t *txq_countp) 571{ 572 efx_nic_ops_t *enop = enp->en_enop; 573 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 574 efx_rc_t rc; 575 576 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 577 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 578 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 579 580 if (enop->eno_get_vi_pool != NULL) { 581 uint32_t vi_count = 0; 582 583 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0) 584 goto fail1; 585 586 *evq_countp = vi_count; 587 *rxq_countp = vi_count; 588 *txq_countp = vi_count; 589 } else { 590 /* Use NIC limits as default value */ 591 *evq_countp = encp->enc_evq_limit; 592 *rxq_countp = encp->enc_rxq_limit; 593 *txq_countp = encp->enc_txq_limit; 594 } 595 596 return (0); 597 598fail1: 599 EFSYS_PROBE1(fail1, efx_rc_t, rc); 600 601 return (rc); 602} 603 604 605 __checkReturn efx_rc_t 606efx_nic_init( 607 __in efx_nic_t *enp) 608{ 609 efx_nic_ops_t *enop = enp->en_enop; 610 efx_rc_t rc; 611 612 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 613 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 614 615 if (enp->en_mod_flags & EFX_MOD_NIC) { 616 rc = EINVAL; 617 goto fail1; 618 } 619 620 if ((rc = enop->eno_init(enp)) != 0) 621 goto fail2; 622 623 enp->en_mod_flags |= EFX_MOD_NIC; 624 625 return (0); 626 627fail2: 628 EFSYS_PROBE(fail2); 629fail1: 630 EFSYS_PROBE1(fail1, efx_rc_t, rc); 631 632 return (rc); 633} 634 635 void 636efx_nic_fini( 637 __in efx_nic_t *enp) 638{ 639 efx_nic_ops_t *enop = enp->en_enop; 640 641 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 642 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 643 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC); 644 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 645 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 646 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 647 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 648 649 enop->eno_fini(enp); 650 651 enp->en_mod_flags &= ~EFX_MOD_NIC; 652} 653 654 void 655efx_nic_unprobe( 656 __in efx_nic_t *enp) 657{ 658 efx_nic_ops_t *enop = enp->en_enop; 659 660 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 661#if EFSYS_OPT_MCDI 662 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 663#endif /* EFSYS_OPT_MCDI */ 664 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 665 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 666 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 667 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 668 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 669 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 670 671 efx_phy_unprobe(enp); 672 673 enop->eno_unprobe(enp); 674 675 enp->en_mod_flags &= ~EFX_MOD_PROBE; 676} 677 678 void 679efx_nic_destroy( 680 __in efx_nic_t *enp) 681{ 682 efsys_identifier_t *esip = enp->en_esip; 683 684 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 685 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0); 686 687 enp->en_family = 0; 688 enp->en_esip = NULL; 689 enp->en_esbp = NULL; 690 enp->en_eslp = NULL; 691 692 enp->en_enop = NULL; 693 694 enp->en_magic = 0; 695 696 /* Free the NIC object */ 697 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 698} 699 700 __checkReturn efx_rc_t 701efx_nic_reset( 702 __in efx_nic_t *enp) 703{ 704 efx_nic_ops_t *enop = enp->en_enop; 705 unsigned int mod_flags; 706 efx_rc_t rc; 707 708 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 709 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 710 /* 711 * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we 712 * do not reset here) must have been shut down or never initialized. 713 * 714 * A rule of thumb here is: If the controller or MC reboots, is *any* 715 * state lost. If it's lost and needs reapplying, then the module 716 * *must* not be initialised during the reset. 717 */ 718 mod_flags = enp->en_mod_flags; 719 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM | 720 EFX_MOD_VPD | EFX_MOD_MON); 721 EFSYS_ASSERT3U(mod_flags, ==, 0); 722 if (mod_flags != 0) { 723 rc = EINVAL; 724 goto fail1; 725 } 726 727 if ((rc = enop->eno_reset(enp)) != 0) 728 goto fail2; 729 730 enp->en_reset_flags |= EFX_RESET_MAC; 731 732 return (0); 733 734fail2: 735 EFSYS_PROBE(fail2); 736fail1: 737 EFSYS_PROBE1(fail1, efx_rc_t, rc); 738 739 return (rc); 740} 741 742 const efx_nic_cfg_t * 743efx_nic_cfg_get( 744 __in efx_nic_t *enp) 745{ 746 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 747 748 return (&(enp->en_nic_cfg)); 749} 750 751#if EFSYS_OPT_DIAG 752 753 __checkReturn efx_rc_t 754efx_nic_register_test( 755 __in efx_nic_t *enp) 756{ 757 efx_nic_ops_t *enop = enp->en_enop; 758 efx_rc_t rc; 759 760 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 761 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 762 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 763 764 if ((rc = enop->eno_register_test(enp)) != 0) 765 goto fail1; 766 767 return (0); 768 769fail1: 770 EFSYS_PROBE1(fail1, efx_rc_t, rc); 771 772 return (rc); 773} 774 775 __checkReturn efx_rc_t 776efx_nic_test_registers( 777 __in efx_nic_t *enp, 778 __in efx_register_set_t *rsp, 779 __in size_t count) 780{ 781 unsigned int bit; 782 efx_oword_t original; 783 efx_oword_t reg; 784 efx_oword_t buf; 785 efx_rc_t rc; 786 787 while (count > 0) { 788 /* This function is only suitable for registers */ 789 EFSYS_ASSERT(rsp->rows == 1); 790 791 /* bit sweep on and off */ 792 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original, 793 B_TRUE); 794 for (bit = 0; bit < 128; bit++) { 795 /* Is this bit in the mask? */ 796 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit)) 797 continue; 798 799 /* Test this bit can be set in isolation */ 800 reg = original; 801 EFX_AND_OWORD(reg, rsp->mask); 802 EFX_SET_OWORD_BIT(reg, bit); 803 804 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 805 B_TRUE); 806 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 807 B_TRUE); 808 809 EFX_AND_OWORD(buf, rsp->mask); 810 if (memcmp(®, &buf, sizeof (reg))) { 811 rc = EIO; 812 goto fail1; 813 } 814 815 /* Test this bit can be cleared in isolation */ 816 EFX_OR_OWORD(reg, rsp->mask); 817 EFX_CLEAR_OWORD_BIT(reg, bit); 818 819 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 820 B_TRUE); 821 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 822 B_TRUE); 823 824 EFX_AND_OWORD(buf, rsp->mask); 825 if (memcmp(®, &buf, sizeof (reg))) { 826 rc = EIO; 827 goto fail2; 828 } 829 } 830 831 /* Restore the old value */ 832 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, 833 B_TRUE); 834 835 --count; 836 ++rsp; 837 } 838 839 return (0); 840 841fail2: 842 EFSYS_PROBE(fail2); 843fail1: 844 EFSYS_PROBE1(fail1, efx_rc_t, rc); 845 846 /* Restore the old value */ 847 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE); 848 849 return (rc); 850} 851 852 __checkReturn efx_rc_t 853efx_nic_test_tables( 854 __in efx_nic_t *enp, 855 __in efx_register_set_t *rsp, 856 __in efx_pattern_type_t pattern, 857 __in size_t count) 858{ 859 efx_sram_pattern_fn_t func; 860 unsigned int index; 861 unsigned int address; 862 efx_oword_t reg; 863 efx_oword_t buf; 864 efx_rc_t rc; 865 866 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES); 867 func = __efx_sram_pattern_fns[pattern]; 868 869 while (count > 0) { 870 /* Write */ 871 address = rsp->address; 872 for (index = 0; index < rsp->rows; ++index) { 873 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 874 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 875 EFX_AND_OWORD(reg, rsp->mask); 876 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE); 877 878 address += rsp->step; 879 } 880 881 /* Read */ 882 address = rsp->address; 883 for (index = 0; index < rsp->rows; ++index) { 884 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 885 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 886 EFX_AND_OWORD(reg, rsp->mask); 887 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE); 888 if (memcmp(®, &buf, sizeof (reg))) { 889 rc = EIO; 890 goto fail1; 891 } 892 893 address += rsp->step; 894 } 895 896 ++rsp; 897 --count; 898 } 899 900 return (0); 901 902fail1: 903 EFSYS_PROBE1(fail1, efx_rc_t, rc); 904 905 return (rc); 906} 907 908#endif /* EFSYS_OPT_DIAG */ 909 910#if EFSYS_OPT_LOOPBACK 911 912extern void 913efx_loopback_mask( 914 __in efx_loopback_kind_t loopback_kind, 915 __out efx_qword_t *maskp) 916{ 917 efx_qword_t mask; 918 919 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS); 920 EFSYS_ASSERT(maskp != NULL); 921 922 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ 923 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); 924 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); 925 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); 926 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); 927 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); 928 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); 929 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); 930 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); 931 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); 932 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); 933 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); 934 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); 935 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); 936 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); 937 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); 938 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); 939 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); 940 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); 941 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT); 942 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS); 943 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS); 944 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR == 945 EFX_LOOPBACK_XAUI_WS_FAR); 946 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR == 947 EFX_LOOPBACK_XAUI_WS_NEAR); 948 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS); 949 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS); 950 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR == 951 EFX_LOOPBACK_XFI_WS_FAR); 952 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS); 953 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT); 954 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR); 955 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR); 956 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS == 957 EFX_LOOPBACK_PMA_INT_WS); 958 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS == 959 EFX_LOOPBACK_SD_FEP2_WS); 960 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS == 961 EFX_LOOPBACK_SD_FEP1_5_WS); 962 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS); 963 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS); 964 965 /* Build bitmask of possible loopback types */ 966 EFX_ZERO_QWORD(mask); 967 968 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) || 969 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 970 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF); 971 } 972 973 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) || 974 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 975 /* 976 * The "MAC" grouping has historically been used by drivers to 977 * mean loopbacks supported by on-chip hardware. Keep that 978 * meaning here, and include on-chip PHY layer loopbacks. 979 */ 980 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA); 981 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC); 982 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII); 983 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS); 984 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI); 985 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII); 986 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII); 987 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR); 988 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI); 989 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR); 990 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR); 991 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR); 992 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR); 993 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT); 994 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR); 995 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR); 996 } 997 998 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) || 999 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 1000 /* 1001 * The "PHY" grouping has historically been used by drivers to 1002 * mean loopbacks supported by off-chip hardware. Keep that 1003 * meaning here. 1004 */ 1005 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY); 1006 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS); 1007 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS); 1008 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD); 1009 } 1010 1011 *maskp = mask; 1012} 1013 1014 __checkReturn efx_rc_t 1015efx_mcdi_get_loopback_modes( 1016 __in efx_nic_t *enp) 1017{ 1018 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1019 efx_mcdi_req_t req; 1020 uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN, 1021 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)]; 1022 efx_qword_t mask; 1023 efx_qword_t modes; 1024 efx_rc_t rc; 1025 1026 (void) memset(payload, 0, sizeof (payload)); 1027 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES; 1028 req.emr_in_buf = payload; 1029 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN; 1030 req.emr_out_buf = payload; 1031 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN; 1032 1033 efx_mcdi_execute(enp, &req); 1034 1035 if (req.emr_rc != 0) { 1036 rc = req.emr_rc; 1037 goto fail1; 1038 } 1039 1040 if (req.emr_out_length_used < 1041 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST + 1042 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) { 1043 rc = EMSGSIZE; 1044 goto fail2; 1045 } 1046 1047 /* 1048 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree 1049 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link(). 1050 */ 1051 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask); 1052 1053 EFX_AND_QWORD(mask, 1054 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED)); 1055 1056 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M); 1057 EFX_AND_QWORD(modes, mask); 1058 encp->enc_loopback_types[EFX_LINK_100FDX] = modes; 1059 1060 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G); 1061 EFX_AND_QWORD(modes, mask); 1062 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes; 1063 1064 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G); 1065 EFX_AND_QWORD(modes, mask); 1066 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes; 1067 1068 if (req.emr_out_length_used >= 1069 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST + 1070 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) { 1071 /* Response includes 40G loopback modes */ 1072 modes = 1073 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G); 1074 EFX_AND_QWORD(modes, mask); 1075 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes; 1076 } 1077 1078 EFX_ZERO_QWORD(modes); 1079 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF); 1080 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]); 1081 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]); 1082 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]); 1083 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]); 1084 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes; 1085 1086 return (0); 1087 1088fail2: 1089 EFSYS_PROBE(fail2); 1090fail1: 1091 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1092 1093 return (rc); 1094} 1095 1096#endif /* EFSYS_OPT_LOOPBACK */
|