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 40efx_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 112static 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 131static 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 150static 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 169efx_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_TXQ_CKSUM_OP_DESC; 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_TXQ_CKSUM_OP_DESC; 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 259fail2: 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 267fail1: 268 EFSYS_PROBE1(fail1, efx_rc_t, rc); 269 270 return (rc); 271} 272 273 __checkReturn efx_rc_t 274efx_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 297fail2: 298 EFSYS_PROBE(fail2); 299 300 enop->eno_unprobe(enp); 301 302fail1: 303 EFSYS_PROBE1(fail1, efx_rc_t, rc); 304 305 return (rc); 306} 307 308 __checkReturn efx_rc_t 309efx_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 326fail1: 327 EFSYS_PROBE1(fail1, efx_rc_t, rc); 328 329 return (rc); 330} 331 332 __checkReturn efx_rc_t 333efx_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 357fail2: 358 EFSYS_PROBE(fail2); 359 360fail1: 361 EFSYS_PROBE1(fail1, efx_rc_t, rc); 362 363 return (rc); 364} 365 366 367 __checkReturn efx_rc_t 368efx_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 400fail1: 401 EFSYS_PROBE1(fail1, efx_rc_t, rc); 402 403 return (rc); 404} 405 406 407 __checkReturn efx_rc_t 408efx_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 429fail2: 430 EFSYS_PROBE(fail2); 431fail1: 432 EFSYS_PROBE1(fail1, efx_rc_t, rc); 433 434 return (rc); 435} 436 437 void 438efx_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 457efx_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 481efx_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 503efx_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 535fail2: 536 EFSYS_PROBE(fail2); 537fail1: 538 EFSYS_PROBE1(fail1, efx_rc_t, rc); 539 540 return (rc); 541} 542 543 const efx_nic_cfg_t * 544efx_nic_cfg_get( 545 __in efx_nic_t *enp) 546{ 547 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 548 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 549 550 return (&(enp->en_nic_cfg)); 551} 552 553#if EFSYS_OPT_DIAG 554 555 __checkReturn efx_rc_t 556efx_nic_register_test( 557 __in efx_nic_t *enp) 558{ 559 const efx_nic_ops_t *enop = enp->en_enop; 560 efx_rc_t rc; 561 562 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 563 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 564 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); 565 566 if ((rc = enop->eno_register_test(enp)) != 0) 567 goto fail1; 568 569 return (0); 570 571fail1: 572 EFSYS_PROBE1(fail1, efx_rc_t, rc); 573 574 return (rc); 575} 576 577#endif /* EFSYS_OPT_DIAG */ 578 579#if EFSYS_OPT_LOOPBACK 580 581extern void 582efx_loopback_mask( 583 __in efx_loopback_kind_t loopback_kind, 584 __out efx_qword_t *maskp) 585{ 586 efx_qword_t mask; 587 588 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS); 589 EFSYS_ASSERT(maskp != NULL); 590 591 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ 592 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); 593 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); 594 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); 595 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); 596 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); 597 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); 598 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); 599 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); 600 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); 601 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); 602 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); 603 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); 604 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); 605 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); 606 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); 607 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); 608 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); 609 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); 610 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT); 611 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS); 612 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS); 613 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR == 614 EFX_LOOPBACK_XAUI_WS_FAR); 615 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR == 616 EFX_LOOPBACK_XAUI_WS_NEAR); 617 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS); 618 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS); 619 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR == 620 EFX_LOOPBACK_XFI_WS_FAR); 621 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS); 622 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT); 623 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR); 624 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR); 625 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS == 626 EFX_LOOPBACK_PMA_INT_WS); 627 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS == 628 EFX_LOOPBACK_SD_FEP2_WS); 629 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS == 630 EFX_LOOPBACK_SD_FEP1_5_WS); 631 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS); 632 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS); 633 634 /* Build bitmask of possible loopback types */ 635 EFX_ZERO_QWORD(mask); 636 637 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) || 638 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 639 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF); 640 } 641 642 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) || 643 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 644 /* 645 * The "MAC" grouping has historically been used by drivers to 646 * mean loopbacks supported by on-chip hardware. Keep that 647 * meaning here, and include on-chip PHY layer loopbacks. 648 */ 649 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA); 650 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC); 651 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII); 652 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS); 653 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI); 654 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII); 655 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII); 656 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR); 657 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI); 658 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR); 659 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR); 660 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR); 661 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR); 662 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT); 663 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR); 664 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR); 665 } 666 667 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) || 668 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) { 669 /* 670 * The "PHY" grouping has historically been used by drivers to 671 * mean loopbacks supported by off-chip hardware. Keep that 672 * meaning here. 673 */ 674 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY); 675 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS); 676 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS); 677 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD); 678 } 679 680 *maskp = mask; 681} 682 683 __checkReturn efx_rc_t 684efx_mcdi_get_loopback_modes( 685 __in efx_nic_t *enp) 686{ 687 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 688 efx_mcdi_req_t req; 689 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN, 690 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN); 691 efx_qword_t mask; 692 efx_qword_t modes; 693 efx_rc_t rc; 694 695 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES; 696 req.emr_in_buf = payload; 697 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN; 698 req.emr_out_buf = payload; 699 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN; 700 701 efx_mcdi_execute(enp, &req); 702 703 if (req.emr_rc != 0) { 704 rc = req.emr_rc; 705 goto fail1; 706 } 707 708 if (req.emr_out_length_used < 709 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST + 710 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) { 711 rc = EMSGSIZE; 712 goto fail2; 713 } 714 715 /* 716 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree 717 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link(). 718 */ 719 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask); 720 721 EFX_AND_QWORD(mask, 722 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED)); 723 724 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M); 725 EFX_AND_QWORD(modes, mask); 726 encp->enc_loopback_types[EFX_LINK_100FDX] = modes; 727 728 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G); 729 EFX_AND_QWORD(modes, mask); 730 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes; 731 732 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G); 733 EFX_AND_QWORD(modes, mask); 734 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes; 735 736 if (req.emr_out_length_used >= 737 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST + 738 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) { 739 /* Response includes 40G loopback modes */ 740 modes = 741 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G); 742 EFX_AND_QWORD(modes, mask); 743 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes; 744 } 745 746 EFX_ZERO_QWORD(modes); 747 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF); 748 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]); 749 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]); 750 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]); 751 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]); 752 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes; 753 754 return (0); 755 756fail2: 757 EFSYS_PROBE(fail2); 758fail1: 759 EFSYS_PROBE1(fail1, efx_rc_t, rc); 760 761 return (rc); 762} 763 764#endif /* EFSYS_OPT_LOOPBACK */ 765 766 __checkReturn efx_rc_t 767efx_nic_calculate_pcie_link_bandwidth( 768 __in uint32_t pcie_link_width, 769 __in uint32_t pcie_link_gen, 770 __out uint32_t *bandwidth_mbpsp) 771{ 772 uint32_t lane_bandwidth; 773 uint32_t total_bandwidth; 774 efx_rc_t rc; 775 776 if ((pcie_link_width == 0) || (pcie_link_width > 16) || 777 !ISP2(pcie_link_width)) { 778 rc = EINVAL; 779 goto fail1; 780 } 781 782 switch (pcie_link_gen) { 783 case EFX_PCIE_LINK_SPEED_GEN1: 784 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */ 785 lane_bandwidth = 2000; 786 break; 787 case EFX_PCIE_LINK_SPEED_GEN2: 788 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */ 789 lane_bandwidth = 4000; 790 break; 791 case EFX_PCIE_LINK_SPEED_GEN3: 792 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */ 793 lane_bandwidth = 7877; 794 break; 795 default: 796 rc = EINVAL; 797 goto fail2; 798 } 799 800 total_bandwidth = lane_bandwidth * pcie_link_width; 801 *bandwidth_mbpsp = total_bandwidth; 802 803 return (0); 804 805fail2: 806 EFSYS_PROBE(fail2); 807fail1: 808 EFSYS_PROBE1(fail1, efx_rc_t, rc); 809 810 return (rc); 811} 812 813 814 __checkReturn efx_rc_t 815efx_nic_check_pcie_link_speed( 816 __in efx_nic_t *enp, 817 __in uint32_t pcie_link_width, 818 __in uint32_t pcie_link_gen, 819 __out efx_pcie_link_performance_t *resultp) 820{ 821 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 822 uint32_t bandwidth; 823 efx_pcie_link_performance_t result; 824 efx_rc_t rc; 825 826 if ((encp->enc_required_pcie_bandwidth_mbps == 0) || 827 (pcie_link_width == 0) || (pcie_link_width == 32) || 828 (pcie_link_gen == 0)) { 829 /* 830 * No usable info on what is required and/or in use. In virtual 831 * machines, sometimes the PCIe link width is reported as 0 or 832 * 32, or the speed as 0. 833 */ 834 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH; 835 goto out; 836 } 837 838 /* Calculate the available bandwidth in megabits per second */ 839 rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width, 840 pcie_link_gen, &bandwidth); 841 if (rc != 0) 842 goto fail1; 843 844 if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) { 845 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH; 846 } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) { 847 /* The link provides enough bandwidth but not optimal latency */ 848 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY; 849 } else { 850 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL; 851 } 852 853out: 854 *resultp = result; 855 856 return (0); 857 858fail1: 859 EFSYS_PROBE1(fail1, efx_rc_t, rc); 860 861 return (rc); 862} 863