1/*- 2 * Copyright (c) 2007-2016 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: stable/10/sys/dev/sfxge/common/efx_nic.c 342524 2018-12-26 10:37:06Z arybchik $"); 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_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#if EFSYS_OPT_SIENA 109 110static const efx_nic_ops_t __efx_nic_siena_ops = { 111 siena_nic_probe, /* eno_probe */ 112 NULL, /* eno_board_cfg */ 113 NULL, /* eno_set_drv_limits */ 114 siena_nic_reset, /* eno_reset */ 115 siena_nic_init, /* eno_init */ 116 NULL, /* eno_get_vi_pool */ 117 NULL, /* eno_get_bar_region */ 118#if EFSYS_OPT_DIAG 119 siena_nic_register_test, /* eno_register_test */ 120#endif /* EFSYS_OPT_DIAG */ 121 siena_nic_fini, /* eno_fini */ 122 siena_nic_unprobe, /* eno_unprobe */ 123}; 124 125#endif /* EFSYS_OPT_SIENA */ 126 127#if EFSYS_OPT_HUNTINGTON 128 129static const efx_nic_ops_t __efx_nic_hunt_ops = { 130 ef10_nic_probe, /* eno_probe */ 131 hunt_board_cfg, /* eno_board_cfg */ 132 ef10_nic_set_drv_limits, /* eno_set_drv_limits */ 133 ef10_nic_reset, /* eno_reset */ 134 ef10_nic_init, /* eno_init */ 135 ef10_nic_get_vi_pool, /* eno_get_vi_pool */ 136 ef10_nic_get_bar_region, /* eno_get_bar_region */ 137#if EFSYS_OPT_DIAG 138 ef10_nic_register_test, /* eno_register_test */ 139#endif /* EFSYS_OPT_DIAG */ 140 ef10_nic_fini, /* eno_fini */ 141 ef10_nic_unprobe, /* eno_unprobe */ 142}; 143 144#endif /* EFSYS_OPT_HUNTINGTON */ 145 146#if EFSYS_OPT_MEDFORD 147 148static const efx_nic_ops_t __efx_nic_medford_ops = { 149 ef10_nic_probe, /* eno_probe */ 150 medford_board_cfg, /* eno_board_cfg */ 151 ef10_nic_set_drv_limits, /* eno_set_drv_limits */ 152 ef10_nic_reset, /* eno_reset */ 153 ef10_nic_init, /* eno_init */ 154 ef10_nic_get_vi_pool, /* eno_get_vi_pool */ 155 ef10_nic_get_bar_region, /* eno_get_bar_region */ 156#if EFSYS_OPT_DIAG 157 ef10_nic_register_test, /* eno_register_test */ 158#endif /* EFSYS_OPT_DIAG */ 159 ef10_nic_fini, /* eno_fini */ 160 ef10_nic_unprobe, /* eno_unprobe */ 161}; 162 163#endif /* EFSYS_OPT_MEDFORD */ 164 165 166 __checkReturn efx_rc_t 167efx_nic_create( 168 __in efx_family_t family, 169 __in efsys_identifier_t *esip, 170 __in efsys_bar_t *esbp, 171 __in efsys_lock_t *eslp, 172 __deref_out efx_nic_t **enpp) 173{ 174 efx_nic_t *enp; 175 efx_rc_t rc; 176 177 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID); 178 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES); 179 180 /* Allocate a NIC object */ 181 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp); 182 183 if (enp == NULL) { 184 rc = ENOMEM; 185 goto fail1; 186 } 187 188 enp->en_magic = EFX_NIC_MAGIC; 189 190 switch (family) { 191#if EFSYS_OPT_SIENA 192 case EFX_FAMILY_SIENA: 193 enp->en_enop = &__efx_nic_siena_ops; 194 enp->en_features = 195 EFX_FEATURE_IPV6 | 196 EFX_FEATURE_LFSR_HASH_INSERT | 197 EFX_FEATURE_LINK_EVENTS | 198 EFX_FEATURE_PERIODIC_MAC_STATS | 199 EFX_FEATURE_MCDI | 200 EFX_FEATURE_LOOKAHEAD_SPLIT | 201 EFX_FEATURE_MAC_HEADER_FILTERS | 202 EFX_FEATURE_TX_SRC_FILTERS; 203 break; 204#endif /* EFSYS_OPT_SIENA */ 205 206#if EFSYS_OPT_HUNTINGTON 207 case EFX_FAMILY_HUNTINGTON: 208 enp->en_enop = &__efx_nic_hunt_ops; 209 enp->en_features = 210 EFX_FEATURE_IPV6 | 211 EFX_FEATURE_LINK_EVENTS | 212 EFX_FEATURE_PERIODIC_MAC_STATS | 213 EFX_FEATURE_MCDI | 214 EFX_FEATURE_MAC_HEADER_FILTERS | 215 EFX_FEATURE_MCDI_DMA | 216 EFX_FEATURE_PIO_BUFFERS | 217 EFX_FEATURE_FW_ASSISTED_TSO | 218 EFX_FEATURE_FW_ASSISTED_TSO_V2 | 219 EFX_FEATURE_TXQ_CKSUM_OP_DESC; 220 break; 221#endif /* EFSYS_OPT_HUNTINGTON */ 222 223#if EFSYS_OPT_MEDFORD 224 case EFX_FAMILY_MEDFORD: 225 enp->en_enop = &__efx_nic_medford_ops; 226 /* 227 * FW_ASSISTED_TSO ommitted as Medford only supports firmware 228 * assisted TSO version 2, not the v1 scheme used on Huntington. 229 */ 230 enp->en_features = 231 EFX_FEATURE_IPV6 | 232 EFX_FEATURE_LINK_EVENTS | 233 EFX_FEATURE_PERIODIC_MAC_STATS | 234 EFX_FEATURE_MCDI | 235 EFX_FEATURE_MAC_HEADER_FILTERS | 236 EFX_FEATURE_MCDI_DMA | 237 EFX_FEATURE_PIO_BUFFERS | 238 EFX_FEATURE_FW_ASSISTED_TSO_V2 | 239 EFX_FEATURE_TXQ_CKSUM_OP_DESC; 240 break; 241#endif /* EFSYS_OPT_MEDFORD */ 242 243 default: 244 rc = ENOTSUP; 245 goto fail2; 246 } 247 248 enp->en_family = family; 249 enp->en_esip = esip; 250 enp->en_esbp = esbp; 251 enp->en_eslp = eslp; 252 253 *enpp = enp; 254 255 return (0); 256 257fail2: 258 EFSYS_PROBE(fail2); 259 260 enp->en_magic = 0; 261 262 /* Free the NIC object */ 263 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 264 265fail1: 266 EFSYS_PROBE1(fail1, efx_rc_t, rc); 267 268 return (rc); 269} 270 271 __checkReturn efx_rc_t 272efx_nic_probe( 273 __in efx_nic_t *enp) 274{ 275 const efx_nic_ops_t *enop; 276 efx_rc_t rc; 277 278 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 279#if EFSYS_OPT_MCDI 280 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 281#endif /* EFSYS_OPT_MCDI */ 282 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE)); 283 284 enop = enp->en_enop; 285 if ((rc = enop->eno_probe(enp)) != 0) 286 goto fail1; 287 288 if ((rc = efx_phy_probe(enp)) != 0) 289 goto fail2; 290 291 enp->en_mod_flags |= EFX_MOD_PROBE; 292 293 return (0); 294 295fail2: 296 EFSYS_PROBE(fail2); 297 298 enop->eno_unprobe(enp); 299 300fail1: 301 EFSYS_PROBE1(fail1, efx_rc_t, rc); 302 303 return (rc); 304} 305 306 __checkReturn efx_rc_t 307efx_nic_set_drv_limits( 308 __inout efx_nic_t *enp, 309 __in efx_drv_limits_t *edlp) 310{ 311 const efx_nic_ops_t *enop = enp->en_enop; 312 efx_rc_t rc; 313 314 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 315 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 316 317 if (enop->eno_set_drv_limits != NULL) { 318 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0) 319 goto fail1; 320 } 321 322 return (0); 323 324fail1: 325 EFSYS_PROBE1(fail1, efx_rc_t, rc); 326 327 return (rc); 328} 329 330 __checkReturn efx_rc_t 331efx_nic_get_bar_region( 332 __in efx_nic_t *enp, 333 __in efx_nic_region_t region, 334 __out uint32_t *offsetp, 335 __out size_t *sizep) 336{ 337 const efx_nic_ops_t *enop = enp->en_enop; 338 efx_rc_t rc; 339 340 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 341 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 342 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 343 344 if (enop->eno_get_bar_region == NULL) { 345 rc = ENOTSUP; 346 goto fail1; 347 } 348 if ((rc = (enop->eno_get_bar_region)(enp, 349 region, offsetp, sizep)) != 0) { 350 goto fail2; 351 } 352 353 return (0); 354 355fail2: 356 EFSYS_PROBE(fail2); 357 358fail1: 359 EFSYS_PROBE1(fail1, efx_rc_t, rc); 360 361 return (rc); 362} 363 364 365 __checkReturn efx_rc_t 366efx_nic_get_vi_pool( 367 __in efx_nic_t *enp, 368 __out uint32_t *evq_countp, 369 __out uint32_t *rxq_countp, 370 __out uint32_t *txq_countp) 371{ 372 const efx_nic_ops_t *enop = enp->en_enop; 373 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 374 efx_rc_t rc; 375 376 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 377 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 378 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 379 380 if (enop->eno_get_vi_pool != NULL) { 381 uint32_t vi_count = 0; 382 383 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0) 384 goto fail1; 385 386 *evq_countp = vi_count; 387 *rxq_countp = vi_count; 388 *txq_countp = vi_count; 389 } else { 390 /* Use NIC limits as default value */ 391 *evq_countp = encp->enc_evq_limit; 392 *rxq_countp = encp->enc_rxq_limit; 393 *txq_countp = encp->enc_txq_limit; 394 } 395 396 return (0); 397 398fail1: 399 EFSYS_PROBE1(fail1, efx_rc_t, rc); 400 401 return (rc); 402} 403 404 405 __checkReturn efx_rc_t 406efx_nic_init( 407 __in efx_nic_t *enp) 408{ 409 const efx_nic_ops_t *enop = enp->en_enop; 410 efx_rc_t rc; 411 412 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 413 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 414 415 if (enp->en_mod_flags & EFX_MOD_NIC) { 416 rc = EINVAL; 417 goto fail1; 418 } 419 420 if ((rc = enop->eno_init(enp)) != 0) 421 goto fail2; 422 423 enp->en_mod_flags |= EFX_MOD_NIC; 424 425 return (0); 426 427fail2: 428 EFSYS_PROBE(fail2); 429fail1: 430 EFSYS_PROBE1(fail1, efx_rc_t, rc); 431 432 return (rc); 433} 434 435 void 436efx_nic_fini( 437 __in efx_nic_t *enp) 438{ 439 const efx_nic_ops_t *enop = enp->en_enop; 440 441 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 442 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 443 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC); 444 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 445 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 446 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 447 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 448 449 enop->eno_fini(enp); 450 451 enp->en_mod_flags &= ~EFX_MOD_NIC; 452} 453 454 void 455efx_nic_unprobe( 456 __in efx_nic_t *enp) 457{ 458 const efx_nic_ops_t *enop = enp->en_enop; 459 460 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 461#if EFSYS_OPT_MCDI 462 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); 463#endif /* EFSYS_OPT_MCDI */ 464 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 465 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 466 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); 467 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 468 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 469 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 470 471 efx_phy_unprobe(enp); 472 473 enop->eno_unprobe(enp); 474 475 enp->en_mod_flags &= ~EFX_MOD_PROBE; 476} 477 478 void 479efx_nic_destroy( 480 __in efx_nic_t *enp) 481{ 482 efsys_identifier_t *esip = enp->en_esip; 483 484 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 485 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0); 486 487 enp->en_family = EFX_FAMILY_INVALID; 488 enp->en_esip = NULL; 489 enp->en_esbp = NULL; 490 enp->en_eslp = NULL; 491 492 enp->en_enop = NULL; 493 494 enp->en_magic = 0; 495 496 /* Free the NIC object */ 497 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); 498} 499 500 __checkReturn efx_rc_t 501efx_nic_reset( 502 __in efx_nic_t *enp) 503{ 504 const efx_nic_ops_t *enop = enp->en_enop; 505 unsigned int mod_flags; 506 efx_rc_t rc; 507 508 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 509 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 510 /* 511 * All modules except the MCDI, PROBE, NVRAM, VPD, MON 512 * (which we do not reset here) must have been shut down or never 513 * initialized. 514 * 515 * A rule of thumb here is: If the controller or MC reboots, is *any* 516 * state lost. If it's lost and needs reapplying, then the module 517 * *must* not be initialised during the reset. 518 */ 519 mod_flags = enp->en_mod_flags; 520 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM | 521 EFX_MOD_VPD | EFX_MOD_MON); 522 EFSYS_ASSERT3U(mod_flags, ==, 0); 523 if (mod_flags != 0) { 524 rc = EINVAL; 525 goto fail1; 526 } 527 528 if ((rc = enop->eno_reset(enp)) != 0) 529 goto fail2; 530 531 return (0); 532 533fail2: 534 EFSYS_PROBE(fail2); 535fail1: 536 EFSYS_PROBE1(fail1, efx_rc_t, rc); 537 538 return (rc); 539} 540 541 const efx_nic_cfg_t * 542efx_nic_cfg_get( 543 __in efx_nic_t *enp) 544{ 545 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 546 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 547 548 return (&(enp->en_nic_cfg)); 549} 550 551#if EFSYS_OPT_DIAG 552 553 __checkReturn efx_rc_t 554efx_nic_register_test( 555 __in efx_nic_t *enp) 556{ 557 const efx_nic_ops_t *enop = enp->en_enop; 558 efx_rc_t rc; 559 560 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 561 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 562 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 563 564 if ((rc = enop->eno_register_test(enp)) != 0) 565 goto fail1; 566 567 return (0); 568 569fail1: 570 EFSYS_PROBE1(fail1, efx_rc_t, rc); 571 572 return (rc); 573} 574 575#endif /* EFSYS_OPT_DIAG */ 576 577#if EFSYS_OPT_LOOPBACK 578 579extern void 580efx_loopback_mask( 581 __in efx_loopback_kind_t loopback_kind, 582 __out efx_qword_t *maskp) 583{ 584 efx_qword_t mask; 585 586 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS); 587 EFSYS_ASSERT(maskp != NULL); 588 589 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ 590 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); 591 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); 592 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); 593 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); 594 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); 595 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); 596 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); 597 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); 598 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); 599 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); 600 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); 601 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); 602 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); 603 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); 604 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); 605 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); 606 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); 607 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); 608 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT); 609 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS); 610 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS); 611 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR == 612 EFX_LOOPBACK_XAUI_WS_FAR); 613 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR == 614 EFX_LOOPBACK_XAUI_WS_NEAR); 615 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS); 616 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS); 617 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR == 618 EFX_LOOPBACK_XFI_WS_FAR); 619 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS); 620 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT); 621 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR); 622 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR); 623 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS == 624 EFX_LOOPBACK_PMA_INT_WS); 625 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS == 626 EFX_LOOPBACK_SD_FEP2_WS); 627 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS == 628 EFX_LOOPBACK_SD_FEP1_5_WS); 629 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS); 630 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS); 631 632 /* Build bitmask of possible loopback types */ 633 EFX_ZERO_QWORD(mask); 634 635 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) || 636 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 637 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF); 638 } 639 640 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) || 641 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 642 /* 643 * The "MAC" grouping has historically been used by drivers to 644 * mean loopbacks supported by on-chip hardware. Keep that 645 * meaning here, and include on-chip PHY layer loopbacks. 646 */ 647 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA); 648 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC); 649 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII); 650 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS); 651 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI); 652 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII); 653 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII); 654 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR); 655 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI); 656 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR); 657 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR); 658 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR); 659 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR); 660 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT); 661 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR); 662 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR); 663 } 664 665 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) || 666 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 667 /* 668 * The "PHY" grouping has historically been used by drivers to 669 * mean loopbacks supported by off-chip hardware. Keep that 670 * meaning here. 671 */ 672 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY); 673 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS); 674 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS); 675 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD); 676 } 677 678 *maskp = mask; 679} 680 681 __checkReturn efx_rc_t 682efx_mcdi_get_loopback_modes( 683 __in efx_nic_t *enp) 684{ 685 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 686 efx_mcdi_req_t req; 687 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN, 688 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN); 689 efx_qword_t mask; 690 efx_qword_t modes; 691 efx_rc_t rc; 692 693 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES; 694 req.emr_in_buf = payload; 695 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN; 696 req.emr_out_buf = payload; 697 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN; 698 699 efx_mcdi_execute(enp, &req); 700 701 if (req.emr_rc != 0) { 702 rc = req.emr_rc; 703 goto fail1; 704 } 705 706 if (req.emr_out_length_used < 707 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST + 708 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) { 709 rc = EMSGSIZE; 710 goto fail2; 711 } 712 713 /* 714 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree 715 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link(). 716 */ 717 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask); 718 719 EFX_AND_QWORD(mask, 720 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED)); 721 722 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M); 723 EFX_AND_QWORD(modes, mask); 724 encp->enc_loopback_types[EFX_LINK_100FDX] = modes; 725 726 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G); 727 EFX_AND_QWORD(modes, mask); 728 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes; 729 730 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G); 731 EFX_AND_QWORD(modes, mask); 732 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes; 733 734 if (req.emr_out_length_used >= 735 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST + 736 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) { 737 /* Response includes 40G loopback modes */ 738 modes = 739 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G); 740 EFX_AND_QWORD(modes, mask); 741 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes; 742 } 743 744 EFX_ZERO_QWORD(modes); 745 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF); 746 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]); 747 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]); 748 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]); 749 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]); 750 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes; 751 752 return (0); 753 754fail2: 755 EFSYS_PROBE(fail2); 756fail1: 757 EFSYS_PROBE1(fail1, efx_rc_t, rc); 758 759 return (rc); 760} 761 762#endif /* EFSYS_OPT_LOOPBACK */ 763 764 __checkReturn efx_rc_t 765efx_nic_calculate_pcie_link_bandwidth( 766 __in uint32_t pcie_link_width, 767 __in uint32_t pcie_link_gen, 768 __out uint32_t *bandwidth_mbpsp) 769{ 770 uint32_t lane_bandwidth; 771 uint32_t total_bandwidth; 772 efx_rc_t rc; 773 774 if ((pcie_link_width == 0) || (pcie_link_width > 16) || 775 !ISP2(pcie_link_width)) { 776 rc = EINVAL; 777 goto fail1; 778 } 779 780 switch (pcie_link_gen) { 781 case EFX_PCIE_LINK_SPEED_GEN1: 782 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */ 783 lane_bandwidth = 2000; 784 break; 785 case EFX_PCIE_LINK_SPEED_GEN2: 786 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */ 787 lane_bandwidth = 4000; 788 break; 789 case EFX_PCIE_LINK_SPEED_GEN3: 790 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */ 791 lane_bandwidth = 7877; 792 break; 793 default: 794 rc = EINVAL; 795 goto fail2; 796 } 797 798 total_bandwidth = lane_bandwidth * pcie_link_width; 799 *bandwidth_mbpsp = total_bandwidth; 800 801 return (0); 802 803fail2: 804 EFSYS_PROBE(fail2); 805fail1: 806 EFSYS_PROBE1(fail1, efx_rc_t, rc); 807 808 return (rc); 809} 810 811 812 __checkReturn efx_rc_t 813efx_nic_check_pcie_link_speed( 814 __in efx_nic_t *enp, 815 __in uint32_t pcie_link_width, 816 __in uint32_t pcie_link_gen, 817 __out efx_pcie_link_performance_t *resultp) 818{ 819 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 820 uint32_t bandwidth; 821 efx_pcie_link_performance_t result; 822 efx_rc_t rc; 823 824 if ((encp->enc_required_pcie_bandwidth_mbps == 0) || 825 (pcie_link_width == 0) || (pcie_link_width == 32) || 826 (pcie_link_gen == 0)) { 827 /* 828 * No usable info on what is required and/or in use. In virtual 829 * machines, sometimes the PCIe link width is reported as 0 or 830 * 32, or the speed as 0. 831 */ 832 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH; 833 goto out; 834 } 835 836 /* Calculate the available bandwidth in megabits per second */ 837 rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width, 838 pcie_link_gen, &bandwidth); 839 if (rc != 0) 840 goto fail1; 841 842 if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) { 843 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH; 844 } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) { 845 /* The link provides enough bandwidth but not optimal latency */ 846 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY; 847 } else { 848 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL; 849 } 850 851out: 852 *resultp = result; 853 854 return (0); 855 856fail1: 857 EFSYS_PROBE1(fail1, efx_rc_t, rc); 858 859 return (rc); 860} 861