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