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