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