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