1 /* 2 * Copyright 2007-2013 Solarflare Communications Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "efsys.h" 27 #include "efx.h" 28 #include "efx_types.h" 29 #include "efx_regs.h" 30 #include "efx_impl.h" 31 #include "falcon_nvram.h" 32 #include "sfx7101.h" 33 #include "sfx7101_impl.h" 34 #include "xphy.h" 35 36 #if EFSYS_OPT_PHY_SFX7101 37 38 static __checkReturn int 39 sfx7101_power_on( 40 __in efx_nic_t *enp, 41 __in boolean_t reflash) 42 { 43 efx_byte_t byte; 44 int rc; 45 46 if ((rc = falcon_i2c_check(enp, PCA9539)) != 0) 47 goto fail1; 48 49 /* Enable all port 0 outputs on IO expander */ 50 EFX_ZERO_BYTE(byte); 51 52 if ((rc = falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte, 53 1)) != 0) 54 goto fail2; 55 56 /* Enable necessary port 1 outputs on IO expander */ 57 EFX_SET_BYTE(byte); 58 EFX_SET_BYTE_FIELD(byte, P1_SPARE, 0); 59 60 if ((rc = falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte, 61 1)) != 0) 62 goto fail3; 63 64 /* Turn off all power rails */ 65 EFX_SET_BYTE(byte); 66 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 67 1)) != 0) 68 goto fail4; 69 70 /* Sleep for 1 s */ 71 EFSYS_SLEEP(1000000); 72 73 /* Turn on 1.2V, 2.5V, and 5V power rails */ 74 EFX_SET_BYTE(byte); 75 EFX_SET_BYTE_FIELD(byte, P0_EN_1V2, 0); 76 EFX_SET_BYTE_FIELD(byte, P0_EN_2V5, 0); 77 EFX_SET_BYTE_FIELD(byte, P0_EN_5V, 0); 78 EFX_SET_BYTE_FIELD(byte, P0_X_TRST, 0); 79 80 /* Disable flash configuration */ 81 if (!reflash) 82 EFX_SET_BYTE_FIELD(byte, P0_FLASH_CFG_EN, 0); 83 84 /* Turn off JTAG */ 85 EFX_SET_BYTE_FIELD(byte, P0_SHORTEN_JTAG, 0); 86 87 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 88 1)) != 0) 89 goto fail5; 90 91 /* Spin for 10 ms */ 92 EFSYS_SPIN(10000); 93 94 /* Turn on 1V power rail */ 95 EFX_SET_BYTE_FIELD(byte, P0_EN_1V0X, 0); 96 97 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 98 1)) != 0) 99 goto fail6; 100 101 /* Sleep for 1 s */ 102 EFSYS_SLEEP(1000000); 103 104 enp->en_reset_flags |= EFX_RESET_PHY; 105 106 return (0); 107 108 fail6: 109 EFSYS_PROBE(fail6); 110 fail5: 111 EFSYS_PROBE(fail5); 112 fail4: 113 EFSYS_PROBE(fail4); 114 115 /* Turn off all power rails */ 116 EFX_SET_BYTE(byte); 117 118 (void) falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 1); 119 120 fail3: 121 EFSYS_PROBE(fail3); 122 123 /* Disable port 1 outputs on IO expander */ 124 EFX_SET_BYTE(byte); 125 (void) falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte, 1); 126 127 fail2: 128 EFSYS_PROBE(fail2); 129 130 /* Disable port 0 outputs on IO expander */ 131 EFX_SET_BYTE(byte); 132 (void) falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte, 1); 133 134 fail1: 135 EFSYS_PROBE1(fail1, int, rc); 136 137 return (rc); 138 } 139 140 static __checkReturn int 141 sfx7101_power_off( 142 __in efx_nic_t *enp) 143 { 144 efx_port_t *epp = &(enp->en_port); 145 efx_word_t word; 146 efx_byte_t byte; 147 int rc; 148 149 /* Power down the LNPGA */ 150 EFX_POPULATE_WORD_1(word, LNPGA_POWERDOWN, 1); 151 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 152 PMA_PMD_XCONTROL_REG, &word)) != 0) 153 goto fail1; 154 155 /* Sleep for 200 ms */ 156 EFSYS_SLEEP(200000); 157 158 /* Turn off all power rails */ 159 EFX_SET_BYTE(byte); 160 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 161 1)) != 0) 162 goto fail2; 163 164 /* Disable port 1 outputs on IO expander */ 165 EFX_SET_BYTE(byte); 166 if ((rc = falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte, 167 1)) != 0) 168 goto fail3; 169 170 /* Disable port 0 outputs on IO expander */ 171 EFX_SET_BYTE(byte); 172 if ((rc = falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte, 173 1)) != 0) 174 goto fail4; 175 176 return (0); 177 178 fail4: 179 EFSYS_PROBE(fail4); 180 fail3: 181 EFSYS_PROBE(fail3); 182 fail2: 183 EFSYS_PROBE(fail2); 184 fail1: 185 EFSYS_PROBE1(fail1, int, rc); 186 187 return (rc); 188 } 189 190 __checkReturn int 191 sfx7101_power( 192 __in efx_nic_t *enp, 193 __in boolean_t on) 194 { 195 int rc; 196 197 if (on) { 198 if ((rc = sfx7101_power_on(enp, B_FALSE)) != 0) 199 goto fail1; 200 201 } else { 202 if ((rc = sfx7101_power_off(enp)) != 0) 203 goto fail1; 204 } 205 206 return (0); 207 208 fail1: 209 EFSYS_PROBE1(fail1, int, rc); 210 211 return (rc); 212 } 213 214 __checkReturn int 215 sfx7101_reset( 216 __in efx_nic_t *enp) 217 { 218 efx_port_t *epp = &(enp->en_port); 219 efx_word_t word; 220 int rc; 221 222 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 223 PMA_PMD_XCONTROL_REG, &word)) != 0) 224 goto fail1; 225 226 EFX_SET_WORD_FIELD(word, SSR, 1); 227 228 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 229 PMA_PMD_XCONTROL_REG, &word)) != 0) 230 goto fail2; 231 232 /* Sleep 500ms */ 233 EFSYS_SPIN(500000); 234 235 enp->en_reset_flags |= EFX_RESET_PHY; 236 237 return (0); 238 239 fail2: 240 EFSYS_PROBE(fail2); 241 fail1: 242 EFSYS_PROBE1(fail1, int, rc); 243 244 return (rc); 245 } 246 247 static __checkReturn int 248 sfx7101_an_set( 249 __in efx_nic_t *enp, 250 __in boolean_t on) 251 { 252 efx_port_t *epp = &(enp->en_port); 253 efx_word_t word; 254 int rc; 255 256 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 257 AN_CONTROL1_REG, &word)) != 0) 258 goto fail1; 259 260 if (on) { 261 EFX_SET_WORD_FIELD(word, AN_ENABLE, 1); 262 EFX_SET_WORD_FIELD(word, AN_RESTART, 1); 263 } else { 264 EFX_SET_WORD_FIELD(word, AN_ENABLE, 0); 265 } 266 267 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD, 268 AN_CONTROL1_REG, &word)) != 0) 269 goto fail2; 270 271 return (0); 272 273 fail2: 274 EFSYS_PROBE(fail2); 275 fail1: 276 EFSYS_PROBE1(fail1, int, rc); 277 278 return (rc); 279 } 280 281 static __checkReturn int 282 sfx7101_led_cfg( 283 __in efx_nic_t *enp) 284 { 285 efx_port_t *epp = &(enp->en_port); 286 efx_word_t word; 287 int rc; 288 289 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 290 PMA_PMD_LED_CONTROL_REG, &word)) != 0) 291 goto fail1; 292 293 EFX_SET_WORD_FIELD(word, LED_ACTIVITY_EN, 1); 294 295 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 296 PMA_PMD_LED_CONTROL_REG, &word)) != 0) 297 goto fail2; 298 299 #if EFSYS_OPT_PHY_LED_CONTROL 300 301 switch (epp->ep_phy_led_mode) { 302 case EFX_PHY_LED_DEFAULT: 303 EFX_POPULATE_WORD_3(word, 304 LED_LINK, LED_NORMAL_DECODE, 305 LED_TX, LED_NORMAL_DECODE, 306 LED_RX, LED_OFF_DECODE); 307 break; 308 309 case EFX_PHY_LED_OFF: 310 EFX_POPULATE_WORD_3(word, 311 LED_LINK, LED_OFF_DECODE, 312 LED_TX, LED_OFF_DECODE, 313 LED_RX, LED_OFF_DECODE); 314 break; 315 316 case EFX_PHY_LED_ON: 317 EFX_POPULATE_WORD_3(word, 318 LED_LINK, LED_ON_DECODE, 319 LED_TX, LED_ON_DECODE, 320 LED_RX, LED_ON_DECODE); 321 break; 322 323 case EFX_PHY_LED_FLASH: 324 EFX_POPULATE_WORD_3(word, 325 LED_LINK, LED_FLASH_DECODE, 326 LED_TX, LED_FLASH_DECODE, 327 LED_RX, LED_FLASH_DECODE); 328 break; 329 330 default: 331 EFSYS_ASSERT(B_FALSE); 332 break; 333 } 334 335 #else /* EFSYS_OPT_PHY_LED_CONTROL */ 336 337 EFX_POPULATE_WORD_3(word, 338 LED_LINK, LED_NORMAL_DECODE, 339 LED_TX, LED_NORMAL_DECODE, 340 LED_RX, LED_OFF_DECODE); 341 342 #endif /* EFSYS_OPT_PHY_LED_CONTROL */ 343 344 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 345 PMA_PMD_LED_OVERRIDE_REG, &word)) != 0) 346 goto fail3; 347 348 return (0); 349 350 fail3: 351 EFSYS_PROBE(fail3); 352 fail2: 353 EFSYS_PROBE(fail2); 354 fail1: 355 EFSYS_PROBE1(fail1, int, rc); 356 357 return (rc); 358 } 359 360 static __checkReturn int 361 sfx7101_clock_cfg( 362 __in efx_nic_t *enp, 363 __in boolean_t enable) 364 { 365 efx_port_t *epp = &(enp->en_port); 366 efx_word_t word; 367 int rc; 368 369 EFX_POPULATE_WORD_1(word, CLK312_EN, (enable) ? 1 : 0); 370 371 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 372 PCS_TEST_SELECT_REG, &word)) != 0) 373 goto fail1; 374 375 return (0); 376 377 fail1: 378 EFSYS_PROBE1(fail1, int, rc); 379 380 return (rc); 381 } 382 383 static __checkReturn int 384 sfx7101_adv_cap_cfg( 385 __in efx_nic_t *enp) 386 { 387 efx_port_t *epp = &(enp->en_port); 388 efx_word_t word; 389 int rc; 390 391 /* Check base page */ 392 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 393 AN_ADV_BP_CAP_REG, &word)) != 0) 394 goto fail1; 395 396 EFX_SET_WORD_FIELD(word, AN_ADV_TA_PAUSE, 397 ((epp->ep_adv_cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1)); 398 EFX_SET_WORD_FIELD(word, AN_ADV_TA_ASM_DIR, 399 ((epp->ep_adv_cap_mask >> EFX_PHY_CAP_ASYM) & 0x1)); 400 401 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD, 402 AN_ADV_BP_CAP_REG, &word)) != 0) 403 goto fail2; 404 405 return (0); 406 407 fail2: 408 EFSYS_PROBE(fail2); 409 fail1: 410 EFSYS_PROBE1(fail1, int, rc); 411 412 return (rc); 413 } 414 415 #if EFSYS_OPT_LOOPBACK 416 static __checkReturn int 417 sfx7101_loopback_cfg( 418 __in efx_nic_t *enp) 419 { 420 efx_port_t *epp = &(enp->en_port); 421 efx_word_t word; 422 int rc; 423 424 switch (epp->ep_loopback_type) { 425 case EFX_LOOPBACK_PHY_XS: 426 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 427 PHY_XS_XGXS_TEST_REG, &word)) != 0) 428 goto fail1; 429 430 EFX_SET_WORD_FIELD(word, NE_LOOPBACK, 1); 431 432 if ((rc = falcon_mdio_write(enp, epp->ep_port, PHY_XS_MMD, 433 PHY_XS_XGXS_TEST_REG, &word)) != 0) 434 goto fail2; 435 436 break; 437 438 case EFX_LOOPBACK_PCS: 439 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PCS_MMD, 440 B_TRUE)) != 0) 441 goto fail1; 442 443 break; 444 445 case EFX_LOOPBACK_PMA_PMD: 446 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PMA_PMD_MMD, 447 B_TRUE)) != 0) 448 goto fail1; 449 450 break; 451 452 default: 453 break; 454 } 455 456 return (0); 457 458 fail2: 459 EFSYS_PROBE(fail2); 460 fail1: 461 EFSYS_PROBE1(fail1, int, rc); 462 463 return (rc); 464 } 465 #endif /* EFSYS_OPT_LOOPBACK */ 466 467 __checkReturn int 468 sfx7101_reconfigure( 469 __in efx_nic_t *enp) 470 { 471 efx_port_t *epp = &(enp->en_port); 472 unsigned int count; 473 int rc; 474 475 /* Wait for the firmware boot to complete */ 476 count = 0; 477 do { 478 efx_word_t word; 479 480 EFSYS_PROBE1(wait, unsigned int, count); 481 482 /* Spin for 1 ms */ 483 EFSYS_SPIN(1000); 484 485 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 486 PCS_BOOT_STATUS_REG, &word)) != 0) 487 goto fail1; 488 489 if (EFX_WORD_FIELD(word, FATAL_ERR) != 0) 490 break; /* no point in continuing */ 491 492 if (EFX_WORD_FIELD(word, BOOT_STATUS) != 0 && 493 EFX_WORD_FIELD(word, CODE_DOWNLOAD) != 0 && 494 EFX_WORD_FIELD(word, CKSUM_OK) != 0 && 495 EFX_WORD_FIELD(word, CODE_STARTED) != 0 && 496 EFX_WORD_FIELD(word, BOOT_PROGRESS) == APP_JMP_DECODE) 497 goto configure; 498 499 } while (++count < 1000); 500 501 rc = ENOTACTIVE; 502 goto fail2; 503 504 configure: 505 if ((rc = xphy_pkg_wait(enp, epp->ep_port, SFX7101_MMD_MASK)) != 0) 506 goto fail3; 507 508 /* Make sure auto-negotiation is off whilst we configure the PHY */ 509 if ((rc = sfx7101_an_set(enp, B_FALSE)) != 0) 510 goto fail4; 511 512 if ((rc = sfx7101_clock_cfg(enp, B_TRUE)) != 0) 513 goto fail5; 514 515 #if EFSYS_OPT_LOOPBACK 516 if ((rc = sfx7101_loopback_cfg(enp)) != 0) 517 goto fail6; 518 #endif /* EFSYS_OPT_LOOPBACK */ 519 520 if ((rc = sfx7101_led_cfg(enp)) != 0) 521 goto fail7; 522 523 if ((rc = sfx7101_adv_cap_cfg(enp)) != 0) 524 goto fail8; 525 526 #if EFSYS_OPT_LOOPBACK 527 if (epp->ep_loopback_type == EFX_LOOPBACK_OFF) { 528 if ((rc = sfx7101_an_set(enp, B_TRUE)) != 0) 529 goto fail9; 530 } 531 #else /* EFSYS_OPT_LOOPBACK */ 532 if ((rc = sfx7101_an_set(enp, B_TRUE)) != 0) 533 goto fail9; 534 #endif /* EFSYS_OPT_LOOPBACK */ 535 536 return (0); 537 538 fail9: 539 EFSYS_PROBE(fail9); 540 fail8: 541 EFSYS_PROBE(fail8); 542 fail7: 543 EFSYS_PROBE(fail7); 544 545 #if EFSYS_OPT_LOOPBACK 546 fail6: 547 EFSYS_PROBE(fail6); 548 #endif /* EFSYS_OPT_LOOPBACK */ 549 550 fail5: 551 EFSYS_PROBE(fail5); 552 fail4: 553 EFSYS_PROBE(fail4); 554 fail3: 555 EFSYS_PROBE(fail3); 556 fail2: 557 EFSYS_PROBE(fail2); 558 fail1: 559 EFSYS_PROBE1(fail1, int, rc); 560 561 return (rc); 562 } 563 564 __checkReturn int 565 sfx7101_verify( 566 __in efx_nic_t *enp) 567 { 568 efx_port_t *epp = &(enp->en_port); 569 int rc; 570 571 if ((rc = xphy_pkg_verify(enp, epp->ep_port, SFX7101_MMD_MASK)) != 0) 572 goto fail1; 573 574 return (0); 575 576 fail1: 577 EFSYS_PROBE1(fail1, int, rc); 578 579 return (rc); 580 } 581 582 __checkReturn int 583 sfx7101_uplink_check( 584 __in efx_nic_t *enp, 585 __out boolean_t *upp) 586 { 587 efx_port_t *epp = &(enp->en_port); 588 efx_word_t word; 589 int rc; 590 591 if (epp->ep_mac_type != EFX_MAC_FALCON_XMAC) { 592 rc = ENOTSUP; 593 goto fail1; 594 } 595 596 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 597 PHY_XS_LANE_STATUS_REG, &word)) != 0) 598 goto fail2; 599 600 *upp = ((EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) && 601 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) && 602 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) && 603 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) && 604 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0)); 605 606 return (0); 607 608 fail2: 609 EFSYS_PROBE(fail2); 610 fail1: 611 EFSYS_PROBE1(fail1, int, rc); 612 613 return (rc); 614 } 615 616 void 617 sfx7101_uplink_reset( 618 __in efx_nic_t *enp) 619 { 620 efx_port_t *epp = &(enp->en_port); 621 efx_word_t word; 622 int rc; 623 624 if (epp->ep_mac_type != EFX_MAC_FALCON_XMAC) { 625 rc = ENOTSUP; 626 goto fail1; 627 } 628 629 /* Disable the clock */ 630 if ((rc = sfx7101_clock_cfg(enp, B_FALSE)) != 0) 631 goto fail2; 632 633 /* Put the XGXS and SERDES into reset */ 634 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 635 PCS_SOFT_RST2_REG, &word)) != 0) 636 goto fail3; 637 638 EFX_SET_WORD_FIELD(word, XGXS_RST_N, 0); 639 EFX_SET_WORD_FIELD(word, SERDES_RST_N, 0); 640 641 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 642 PCS_SOFT_RST2_REG, &word)) != 0) 643 goto fail4; 644 645 /* Put the PLL into reset */ 646 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 647 PCS_CLOCK_CTRL_REG, &word)) != 0) 648 goto fail5; 649 650 EFX_SET_WORD_FIELD(word, PLL312_RST_N, 0); 651 652 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 653 PCS_CLOCK_CTRL_REG, &word)) != 0) 654 goto fail6; 655 656 EFSYS_SPIN(10); 657 658 /* Take the PLL out of reset */ 659 EFX_SET_WORD_FIELD(word, PLL312_RST_N, 1); 660 661 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 662 PCS_CLOCK_CTRL_REG, &word)) != 0) 663 goto fail7; 664 665 EFSYS_SPIN(10); 666 667 /* Take the XGXS and SERDES out of reset */ 668 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 669 PCS_SOFT_RST2_REG, &word)) != 0) 670 goto fail8; 671 672 EFX_SET_WORD_FIELD(word, XGXS_RST_N, 1); 673 EFX_SET_WORD_FIELD(word, SERDES_RST_N, 1); 674 675 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 676 PCS_SOFT_RST2_REG, &word)) != 0) 677 goto fail9; 678 679 /* Enable the clock */ 680 if ((rc = sfx7101_clock_cfg(enp, B_TRUE)) != 0) 681 goto fail10; 682 683 /* Sleep 200 ms */ 684 EFSYS_SLEEP(200000); 685 686 return; 687 688 fail10: 689 EFSYS_PROBE(fail10); 690 fail9: 691 EFSYS_PROBE(fail9); 692 fail8: 693 EFSYS_PROBE(fail8); 694 fail7: 695 EFSYS_PROBE(fail7); 696 fail6: 697 EFSYS_PROBE(fail6); 698 fail5: 699 EFSYS_PROBE(fail5); 700 fail4: 701 EFSYS_PROBE(fail4); 702 fail3: 703 EFSYS_PROBE(fail3); 704 fail2: 705 EFSYS_PROBE(fail2); 706 fail1: 707 EFSYS_PROBE1(fail1, int, rc); 708 } 709 710 static __checkReturn int 711 sfx7101_lp_cap_get( 712 __in efx_nic_t *enp, 713 __out unsigned int *maskp) 714 { 715 efx_port_t *epp = &(enp->en_port); 716 efx_word_t word; 717 int rc; 718 719 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 720 AN_LP_BP_CAP_REG, &word)) != 0) 721 goto fail1; 722 723 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T) != 0) 724 *maskp |= (1 << EFX_PHY_CAP_10HDX); 725 726 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T_FDX) != 0) 727 *maskp |= (1 << EFX_PHY_CAP_10FDX); 728 729 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX) != 0) 730 *maskp |= (1 << EFX_PHY_CAP_100HDX); 731 732 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX_FDX) != 0) 733 *maskp |= (1 << EFX_PHY_CAP_100FDX); 734 735 if (EFX_WORD_FIELD(word, AN_LP_TA_PAUSE) != 0) 736 *maskp |= (1 << EFX_PHY_CAP_PAUSE); 737 738 if (EFX_WORD_FIELD(word, AN_LP_TA_ASM_DIR) != 0) 739 *maskp |= (1 << EFX_PHY_CAP_ASYM); 740 741 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 742 AN_10G_BASE_T_STATUS_REG, &word)) != 0) 743 goto fail2; 744 745 if (EFX_WORD_FIELD(word, AN_10G_BASE_T_LP) != 0) 746 *maskp |= (1 << EFX_PHY_CAP_10000FDX); 747 748 return (0); 749 750 fail2: 751 EFSYS_PROBE(fail2); 752 fail1: 753 EFSYS_PROBE1(fail1, int, rc); 754 755 return (rc); 756 } 757 758 __checkReturn int 759 sfx7101_downlink_check( 760 __in efx_nic_t *enp, 761 __out efx_link_mode_t *modep, 762 __out unsigned int *fcntlp, 763 __out uint32_t *lp_cap_maskp) 764 { 765 efx_port_t *epp = &(enp->en_port); 766 unsigned int lp_cap_mask = epp->ep_lp_cap_mask; 767 unsigned int fcntl = epp->ep_fcntl; 768 uint32_t common; 769 boolean_t up; 770 int rc; 771 772 #if EFSYS_OPT_LOOPBACK 773 switch (epp->ep_loopback_type) { 774 case EFX_LOOPBACK_PHY_XS: 775 rc = xphy_mmd_fault(enp, epp->ep_port, &up); 776 if (rc != 0) 777 goto fail1; 778 779 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN; 780 goto done; 781 782 case EFX_LOOPBACK_PCS: 783 case EFX_LOOPBACK_PMA_PMD: 784 rc = xphy_mmd_check(enp, epp->ep_port, PHY_XS_MMD, &up); 785 if (rc != 0) 786 goto fail1; 787 788 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN; 789 goto done; 790 791 default: 792 break; 793 } 794 795 #endif /* EFSYS_OPT_LOOPBACK */ 796 rc = xphy_mmd_check(enp, epp->ep_port, AN_MMD, &up); 797 if (rc != 0) 798 goto fail1; 799 800 /* Check the link partner capabilities */ 801 if ((rc = sfx7101_lp_cap_get(enp, &lp_cap_mask)) != 0) 802 goto fail2; 803 804 /* Resolve the common capabilities */ 805 common = epp->ep_adv_cap_mask & lp_cap_mask; 806 807 /* Determine negotiated or forced flow control mode */ 808 fcntl = 0; 809 if (epp->ep_fcntl_autoneg) { 810 if (common & (1 << EFX_PHY_CAP_PAUSE)) 811 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND; 812 else if (common & (1 << EFX_PHY_CAP_ASYM)) { 813 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 814 fcntl = EFX_FCNTL_RESPOND; 815 else if (lp_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 816 fcntl = EFX_FCNTL_GENERATE; 817 } 818 } else { 819 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 820 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND; 821 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM)) 822 fcntl ^= EFX_FCNTL_GENERATE; 823 } 824 825 *fcntlp = fcntl; 826 *lp_cap_maskp = lp_cap_mask; 827 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN; 828 829 #if EFSYS_OPT_LOOPBACK 830 done: 831 #endif 832 *fcntlp = epp->ep_fcntl; 833 *lp_cap_maskp = epp->ep_lp_cap_mask; 834 835 return (0); 836 837 fail2: 838 EFSYS_PROBE(fail2); 839 fail1: 840 EFSYS_PROBE1(fail1, int, rc); 841 842 return (rc); 843 } 844 845 __checkReturn int 846 sfx7101_oui_get( 847 __in efx_nic_t *enp, 848 __out uint32_t *ouip) 849 { 850 efx_port_t *epp = &(enp->en_port); 851 int rc; 852 853 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, ouip)) != 0) 854 goto fail1; 855 856 return (0); 857 858 fail1: 859 EFSYS_PROBE1(fail1, int, rc); 860 861 return (rc); 862 } 863 864 #if EFSYS_OPT_PHY_STATS 865 866 #define SFX7101_STAT_SET(_stat, _mask, _id, _val) \ 867 do { \ 868 (_mask) |= (1ULL << (_id)); \ 869 (_stat)[_id] = (uint32_t)(_val); \ 870 _NOTE(CONSTANTCONDITION) \ 871 } while (B_FALSE) 872 873 static __checkReturn int 874 sfx7101_rev_get( 875 __in efx_nic_t *enp, 876 __out uint16_t *majorp, 877 __out uint16_t *minorp, 878 __out uint16_t *microp) 879 { 880 efx_port_t *epp = &(enp->en_port); 881 efx_word_t word[2]; 882 int rc; 883 884 /* 885 * There appear to be two version string formats in use: 886 * 887 * - ('0','major') ('.','minor') with micro == 0 888 * - ('major','.') ('minor','micro') 889 * 890 */ 891 892 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 893 PMA_PMD_FW_REV0_REG, &(word[0]))) != 0) 894 goto fail1; 895 896 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 897 PMA_PMD_FW_REV1_REG, &(word[1]))) != 0) 898 goto fail2; 899 900 if (EFX_WORD_FIELD(word[1], EFX_BYTE_0) == '0') { 901 *majorp = EFX_WORD_FIELD(word[1], EFX_BYTE_1) - '0'; 902 903 if (EFX_WORD_FIELD(word[0], EFX_BYTE_0) != '.') 904 goto fail3; 905 906 *minorp = EFX_WORD_FIELD(word[0], EFX_BYTE_1) - '0'; 907 *microp = 0; 908 909 } else { 910 *majorp = EFX_WORD_FIELD(word[1], EFX_BYTE_0) - '0'; 911 912 if (EFX_WORD_FIELD(word[1], EFX_BYTE_1) != '.') 913 goto fail3; 914 915 *minorp = EFX_WORD_FIELD(word[0], EFX_BYTE_0) - '0'; 916 *microp = EFX_WORD_FIELD(word[0], EFX_BYTE_1) - '0'; 917 } 918 919 return (0); 920 921 fail3: 922 rc = EIO; 923 EFSYS_PROBE(fail3); 924 fail2: 925 EFSYS_PROBE(fail2); 926 fail1: 927 EFSYS_PROBE1(fail1, int, rc); 928 929 return (rc); 930 } 931 932 static __checkReturn int 933 sfx7101_pma_pmd_stats_update( 934 __in efx_nic_t *enp, 935 __inout uint64_t *maskp, 936 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 937 { 938 efx_port_t *epp = &(enp->en_port); 939 efx_word_t word; 940 uint16_t major; 941 uint16_t minor; 942 uint16_t micro; 943 int rc; 944 945 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 946 PMA_PMD_STATUS1_REG, &word)) != 0) 947 goto fail1; 948 949 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_LINK_UP, 950 (EFX_WORD_FIELD(word, PMA_PMD_LINK_UP) != 0) ? 1 : 0); 951 952 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 953 PMA_PMD_STATUS2_REG, &word)) != 0) 954 goto fail2; 955 956 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_RX_FAULT, 957 (EFX_WORD_FIELD(word, PMA_PMD_RX_FAULT) != 0) ? 1 : 0); 958 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_TX_FAULT, 959 (EFX_WORD_FIELD(word, PMA_PMD_TX_FAULT) != 0) ? 1 : 0); 960 961 if ((rc = sfx7101_rev_get(enp, &major, &minor, µ)) != 0) 962 goto fail3; 963 964 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MAJOR, major); 965 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MINOR, minor); 966 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MICRO, micro); 967 968 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 969 PMA_PMD_CHANNELA_SNR_REG, &word)) != 0) 970 goto fail4; 971 972 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_A, 973 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 974 975 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 976 PMA_PMD_CHANNELB_SNR_REG, &word)) != 0) 977 goto fail5; 978 979 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_B, 980 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 981 982 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 983 PMA_PMD_CHANNELC_SNR_REG, &word)) != 0) 984 goto fail6; 985 986 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_C, 987 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 988 989 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 990 PMA_PMD_CHANNELD_SNR_REG, &word)) != 0) 991 goto fail7; 992 993 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_D, 994 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 995 996 return (0); 997 998 fail7: 999 EFSYS_PROBE(fail7); 1000 fail6: 1001 EFSYS_PROBE(fail6); 1002 fail5: 1003 EFSYS_PROBE(fail5); 1004 fail4: 1005 EFSYS_PROBE(fail4); 1006 fail3: 1007 EFSYS_PROBE(fail3); 1008 fail2: 1009 EFSYS_PROBE(fail2); 1010 fail1: 1011 EFSYS_PROBE1(fail1, int, rc); 1012 1013 return (rc); 1014 } 1015 1016 static __checkReturn int 1017 sfx7101_pcs_stats_update( 1018 __in efx_nic_t *enp, 1019 __inout uint64_t *maskp, 1020 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1021 { 1022 efx_port_t *epp = &(enp->en_port); 1023 efx_word_t word; 1024 int rc; 1025 1026 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1027 PCS_STATUS1_REG, &word)) != 0) 1028 goto fail1; 1029 1030 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_LINK_UP, 1031 (EFX_WORD_FIELD(word, PCS_LINK_UP) != 0) ? 1 : 0); 1032 1033 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1034 PCS_STATUS2_REG, &word)) != 0) 1035 goto fail2; 1036 1037 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_RX_FAULT, 1038 (EFX_WORD_FIELD(word, PCS_RX_FAULT) != 0) ? 1 : 0); 1039 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_TX_FAULT, 1040 (EFX_WORD_FIELD(word, PCS_TX_FAULT) != 0) ? 1 : 0); 1041 1042 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1043 PCS_10GBASE_R_STATUS2_REG, &word)) != 0) 1044 goto fail3; 1045 1046 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BER, 1047 EFX_WORD_FIELD(word, PCS_BER)); 1048 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BLOCK_ERRORS, 1049 EFX_WORD_FIELD(word, PCS_ERR)); 1050 1051 return (0); 1052 1053 fail3: 1054 EFSYS_PROBE(fail3); 1055 fail2: 1056 EFSYS_PROBE(fail2); 1057 fail1: 1058 EFSYS_PROBE1(fail1, int, rc); 1059 1060 return (rc); 1061 } 1062 1063 static __checkReturn int 1064 sfx7101_phy_xs_stats_update( 1065 __in efx_nic_t *enp, 1066 __inout uint64_t *maskp, 1067 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1068 { 1069 efx_port_t *epp = &(enp->en_port); 1070 efx_word_t word; 1071 int rc; 1072 1073 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1074 PHY_XS_STATUS1_REG, &word)) != 0) 1075 goto fail1; 1076 1077 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_LINK_UP, 1078 (EFX_WORD_FIELD(word, PHY_XS_LINK_UP) != 0) ? 1 : 0); 1079 1080 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1081 PHY_XS_STATUS2_REG, &word)) != 0) 1082 goto fail2; 1083 1084 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_RX_FAULT, 1085 (EFX_WORD_FIELD(word, PHY_XS_RX_FAULT) != 0) ? 1 : 0); 1086 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_TX_FAULT, 1087 (EFX_WORD_FIELD(word, PHY_XS_TX_FAULT) != 0) ? 1 : 0); 1088 1089 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1090 PHY_XS_LANE_STATUS_REG, &word)) != 0) 1091 goto fail3; 1092 1093 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_ALIGN, 1094 (EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) ? 1 : 0); 1095 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_A, 1096 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) ? 1 : 0); 1097 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_B, 1098 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) ? 1 : 0); 1099 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_C, 1100 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) ? 1 : 0); 1101 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_D, 1102 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0) ? 1 : 0); 1103 1104 return (0); 1105 1106 fail3: 1107 EFSYS_PROBE(fail3); 1108 fail2: 1109 EFSYS_PROBE(fail2); 1110 fail1: 1111 EFSYS_PROBE1(fail1, int, rc); 1112 1113 return (rc); 1114 } 1115 1116 static __checkReturn int 1117 sfx7101_an_stats_update( 1118 __in efx_nic_t *enp, 1119 __inout uint64_t *maskp, 1120 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1121 { 1122 efx_port_t *epp = &(enp->en_port); 1123 efx_word_t word; 1124 int rc; 1125 1126 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 1127 AN_STATUS1_REG, &word)) != 0) 1128 goto fail1; 1129 1130 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LINK_UP, 1131 (EFX_WORD_FIELD(word, AN_LINK_UP) != 0) ? 1 : 0); 1132 1133 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 1134 AN_10G_BASE_T_STATUS_REG, &word)) != 0) 1135 goto fail2; 1136 1137 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_MASTER, 1138 (EFX_WORD_FIELD(word, AN_MASTER) != 0) ? 1 : 0); 1139 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LOCAL_RX_OK, 1140 (EFX_WORD_FIELD(word, AN_LOCAL_RX_OK) != 0) ? 1 : 0); 1141 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_REMOTE_RX_OK, 1142 (EFX_WORD_FIELD(word, AN_REMOTE_RX_OK) != 0) ? 1 : 0); 1143 1144 return (0); 1145 1146 fail2: 1147 EFSYS_PROBE(fail2); 1148 fail1: 1149 EFSYS_PROBE1(fail1, int, rc); 1150 1151 return (rc); 1152 } 1153 1154 __checkReturn int 1155 sfx7101_stats_update( 1156 __in efx_nic_t *enp, 1157 __in efsys_mem_t *esmp, 1158 __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1159 { 1160 efx_port_t *epp = &(enp->en_port); 1161 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1162 uint64_t mask = 0; 1163 uint32_t oui; 1164 int rc; 1165 1166 _NOTE(ARGUNUSED(esmp)) 1167 1168 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, &oui)) != 0) 1169 goto fail1; 1170 1171 SFX7101_STAT_SET(stat, mask, EFX_PHY_STAT_OUI, oui); 1172 1173 if ((rc = sfx7101_pma_pmd_stats_update(enp, &mask, stat)) != 0) 1174 goto fail2; 1175 1176 if ((rc = sfx7101_pcs_stats_update(enp, &mask, stat)) != 0) 1177 goto fail3; 1178 1179 if ((rc = sfx7101_phy_xs_stats_update(enp, &mask, stat)) != 0) 1180 goto fail4; 1181 1182 if ((rc = sfx7101_an_stats_update(enp, &mask, stat)) != 0) 1183 goto fail5; 1184 1185 /* Ensure all the supported statistics are up to date */ 1186 EFSYS_ASSERT(mask == encp->enc_phy_stat_mask); 1187 1188 return (0); 1189 1190 fail5: 1191 EFSYS_PROBE(fail5); 1192 fail4: 1193 EFSYS_PROBE(fail4); 1194 fail3: 1195 EFSYS_PROBE(fail3); 1196 fail2: 1197 EFSYS_PROBE(fail2); 1198 fail1: 1199 EFSYS_PROBE1(fail1, int, rc); 1200 1201 return (rc); 1202 } 1203 #endif /* EFSYS_OPT_PHY_STATS */ 1204 1205 #if EFSYS_OPT_PHY_PROPS 1206 1207 #if EFSYS_OPT_NAMES 1208 const char __cs * 1209 sfx7101_prop_name( 1210 __in efx_nic_t *enp, 1211 __in unsigned int id) 1212 { 1213 _NOTE(ARGUNUSED(enp, id)) 1214 1215 EFSYS_ASSERT(B_FALSE); 1216 1217 return (NULL); 1218 } 1219 #endif /* EFSYS_OPT_NAMES */ 1220 1221 __checkReturn int 1222 sfx7101_prop_get( 1223 __in efx_nic_t *enp, 1224 __in unsigned int id, 1225 __in uint32_t flags, 1226 __out uint32_t *valp) 1227 { 1228 _NOTE(ARGUNUSED(enp, id, flags, valp)) 1229 1230 EFSYS_ASSERT(B_FALSE); 1231 1232 return (ENOTSUP); 1233 } 1234 1235 __checkReturn int 1236 sfx7101_prop_set( 1237 __in efx_nic_t *enp, 1238 __in unsigned int id, 1239 __in uint32_t val) 1240 { 1241 _NOTE(ARGUNUSED(enp, id, val)) 1242 1243 EFSYS_ASSERT(B_FALSE); 1244 1245 return (ENOTSUP); 1246 } 1247 1248 #endif /* EFSYS_OPT_PHY_PROPS */ 1249 1250 #if EFSYS_OPT_NVRAM_SFX7101 1251 1252 static __checkReturn int 1253 sfx7101_loader_wait( 1254 __in efx_nic_t *enp) 1255 { 1256 efx_port_t *epp = &(enp->en_port); 1257 efx_word_t word; 1258 unsigned int count; 1259 unsigned int response; 1260 int rc; 1261 1262 /* Wait up to 20s for the command to complete */ 1263 for (count = 0; count < 200; count++) { 1264 EFSYS_SLEEP(100000); /* 100ms */ 1265 1266 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1267 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1268 goto fail1; 1269 1270 response = EFX_WORD_FIELD(word, EFX_WORD_0); 1271 if (response == LOADER_RESPONSE_OK) 1272 return (0); 1273 if (response != LOADER_RESPONSE_BUSY) { 1274 rc = EIO; 1275 goto fail2; 1276 } 1277 } 1278 1279 rc = ETIMEDOUT; 1280 1281 EFSYS_PROBE(fail3); 1282 fail2: 1283 EFSYS_PROBE(fail2); 1284 fail1: 1285 EFSYS_PROBE1(fail1, int, rc); 1286 1287 return (rc); 1288 } 1289 1290 static __checkReturn int 1291 sfx7101_program_loader( 1292 __in efx_nic_t *enp, 1293 __in unsigned int offset, 1294 __in size_t words) 1295 { 1296 efx_port_t *epp = &(enp->en_port); 1297 efx_word_t word; 1298 int rc; 1299 1300 /* Setup address of block transfer */ 1301 EFX_POPULATE_WORD_1(word, EFX_WORD_0, offset); 1302 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1303 LOADER_FLASH_ADDR_LOW_REG, &word)) != 0) 1304 goto fail1; 1305 1306 EFX_POPULATE_WORD_1(word, EFX_WORD_0, (offset >> 16)); 1307 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1308 LOADER_FLASH_ADDR_HI_REG, &word)) != 0) 1309 goto fail2; 1310 1311 EFX_POPULATE_WORD_1(word, EFX_WORD_0, words); 1312 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1313 LOADER_ACTUAL_BUFF_SZ_REG, &word)) != 0) 1314 goto fail3; 1315 1316 return (0); 1317 1318 fail3: 1319 EFSYS_PROBE(fail3); 1320 fail2: 1321 EFSYS_PROBE(fail2); 1322 fail1: 1323 EFSYS_PROBE1(fail1, int, rc); 1324 1325 return (rc); 1326 } 1327 1328 __checkReturn int 1329 sfx7101_nvram_size( 1330 __in efx_nic_t *enp, 1331 __out size_t *sizep) 1332 { 1333 _NOTE(ARGUNUSED(enp)) 1334 EFSYS_ASSERT(sizep); 1335 1336 *sizep = FIRMWARE_MAX_SIZE; 1337 1338 return (0); 1339 } 1340 1341 __checkReturn int 1342 sfx7101_nvram_get_version( 1343 __in efx_nic_t *enp, 1344 __out uint32_t *subtypep, 1345 __out_ecount(4) uint16_t version[4]) 1346 { 1347 uint16_t major, minor, micro; 1348 int rc; 1349 1350 if ((rc = sfx7101_rev_get(enp, &major, &minor, µ)) != 0) 1351 goto fail1; 1352 1353 version[0] = major; 1354 version[1] = minor; 1355 version[2] = 0; 1356 version[3] = 0; 1357 1358 *subtypep = PHY_TYPE_SFX7101_DECODE; 1359 1360 return (0); 1361 1362 fail1: 1363 EFSYS_PROBE1(fail1, int, rc); 1364 1365 return (0); 1366 } 1367 1368 __checkReturn int 1369 sfx7101_nvram_rw_start( 1370 __in efx_nic_t *enp, 1371 __out size_t *block_sizep) 1372 { 1373 efx_port_t *epp = &(enp->en_port); 1374 sfx7101_firmware_header_t header; 1375 efx_word_t word; 1376 unsigned int pos; 1377 int rc; 1378 1379 /* Ensure the PHY is on */ 1380 if ((rc = sfx7101_power_on(enp, B_TRUE)) != 0) 1381 goto fail1; 1382 1383 /* Special software reset */ 1384 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1385 PMA_PMD_XCONTROL_REG, &word)) != 0) 1386 goto fail2; 1387 EFX_SET_WORD_FIELD(word, SSR, 1); 1388 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 1389 PMA_PMD_XCONTROL_REG, &word)) != 0) 1390 goto fail3; 1391 1392 /* Sleep for 500ms */ 1393 EFSYS_SLEEP(500000); 1394 1395 /* Check that the C166 is idle, and in download mode */ 1396 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1397 PCS_BOOT_STATUS_REG, &word)) != 0) 1398 goto fail4; 1399 if (EFX_WORD_FIELD(word, BOOT_STATUS) == 0 || 1400 EFX_WORD_FIELD(word, BOOT_PROGRESS) != MDIO_WAIT_DECODE) { 1401 rc = ETIMEDOUT; 1402 goto fail5; 1403 } 1404 1405 /* Download loader code into PHY RAM */ 1406 EFX_ZERO_WORD(word); 1407 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1408 PCS_LM_RAM_LS_ADDR_REG, &word)) != 0) 1409 goto fail6; 1410 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1411 PCS_LM_RAM_MS_ADDR_REG, &word)) != 0) 1412 goto fail7; 1413 1414 for (pos = 0; pos < sfx7101_loader_size / sizeof (uint16_t); pos++) { 1415 /* Firmware is little endian */ 1416 word.ew_u8[0] = sfx7101_loader[pos]; 1417 word.ew_u8[1] = sfx7101_loader[pos+1]; 1418 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1419 PCS_LM_RAM_DATA_REG, &word)) != 0) 1420 goto fail8; 1421 } 1422 1423 /* Sleep for 500ms */ 1424 EFSYS_SLEEP(500000); 1425 1426 /* Start downloaded code */ 1427 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1428 PCS_BOOT_STATUS_REG, &word)) != 0) 1429 goto fail9; 1430 EFX_SET_WORD_FIELD(word, CODE_DOWNLOAD, 1); 1431 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1432 PCS_BOOT_STATUS_REG, &word)) != 0) 1433 goto fail10; 1434 1435 /* Sleep 1s */ 1436 EFSYS_SLEEP(1000000); 1437 1438 /* And check it started */ 1439 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1440 PCS_BOOT_STATUS_REG, &word)) != 0) 1441 goto fail11; 1442 1443 if (!EFX_WORD_FIELD(word, CODE_STARTED)) { 1444 rc = ETIMEDOUT; 1445 goto fail12; 1446 } 1447 1448 /* Verify program block size is appropriate */ 1449 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1450 LOADER_MAX_BUFF_SZ_REG, &word)) != 0) 1451 goto fail13; 1452 if (EFX_WORD_FIELD(word, EFX_WORD_0) < FIRMWARE_BLOCK_SIZE) { 1453 rc = EIO; 1454 goto fail14; 1455 } 1456 if (block_sizep != NULL) 1457 *block_sizep = FIRMWARE_BLOCK_SIZE; 1458 1459 /* Read firmware header */ 1460 if ((rc = sfx7101_nvram_read_chunk(enp, 0, (void *)&header, 1461 sizeof (header))) != 0) 1462 goto fail15; 1463 1464 /* Verify firmware isn't too large */ 1465 if (EFX_DWORD_FIELD(header.code_length, EFX_DWORD_0) + 1466 sizeof (sfx7101_firmware_header_t) > FIRMWARE_MAX_SIZE) { 1467 rc = EIO; 1468 goto fail16; 1469 } 1470 1471 return (0); 1472 1473 fail16: 1474 EFSYS_PROBE(fail16); 1475 fail15: 1476 EFSYS_PROBE(fail15); 1477 fail14: 1478 EFSYS_PROBE(fail14); 1479 fail13: 1480 EFSYS_PROBE(fail13); 1481 fail12: 1482 EFSYS_PROBE(fail12); 1483 fail11: 1484 EFSYS_PROBE(fail11); 1485 fail10: 1486 EFSYS_PROBE(fail10); 1487 fail9: 1488 EFSYS_PROBE(fail9); 1489 fail8: 1490 EFSYS_PROBE(fail8); 1491 fail7: 1492 EFSYS_PROBE(fail7); 1493 fail6: 1494 EFSYS_PROBE(fail6); 1495 fail5: 1496 EFSYS_PROBE(fail5); 1497 fail4: 1498 EFSYS_PROBE(fail4); 1499 fail3: 1500 EFSYS_PROBE(fail3); 1501 fail2: 1502 EFSYS_PROBE(fail2); 1503 fail1: 1504 EFSYS_PROBE1(fail1, int, rc); 1505 1506 /* Restore the original image */ 1507 sfx7101_nvram_rw_finish(enp); 1508 1509 return (rc); 1510 } 1511 1512 __checkReturn int 1513 sfx7101_nvram_read_chunk( 1514 __in efx_nic_t *enp, 1515 __in unsigned int offset, 1516 __out_bcount(size) caddr_t data, 1517 __in size_t size) 1518 { 1519 efx_port_t *epp = &(enp->en_port); 1520 efx_word_t word; 1521 unsigned int pos; 1522 size_t chunk; 1523 size_t words; 1524 int rc; 1525 1526 while (size > 0) { 1527 chunk = MIN(size, FIRMWARE_BLOCK_SIZE); 1528 1529 /* Read in 2byte words */ 1530 EFSYS_ASSERT(!(chunk & 0x1)); 1531 words = chunk >> 1; 1532 1533 /* Program address/length */ 1534 if ((rc = sfx7101_program_loader(enp, offset, words)) != 0) 1535 goto fail1; 1536 1537 /* Select read mode, and wait for buffer to fill */ 1538 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_READ_FLASH); 1539 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1540 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1541 goto fail2; 1542 1543 if ((rc = sfx7101_loader_wait(enp)) != 0) 1544 goto fail3; 1545 1546 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1547 LOADER_WORDS_READ_REG, &word)) != 0) 1548 goto fail4; 1549 1550 if (words != (size_t)EFX_WORD_FIELD(word, EFX_WORD_0)) 1551 goto fail5; 1552 1553 for (pos = 0; pos < words; ++pos) { 1554 if ((rc = falcon_mdio_read(enp, epp->ep_port, 1555 LOADER_MMD, LOADER_DATA_REG, &word)) != 0) 1556 goto fail6; 1557 1558 /* Firmware is little endian */ 1559 data[pos] = word.ew_u8[0]; 1560 data[pos+1] = word.ew_u8[1]; 1561 } 1562 1563 offset += chunk; 1564 data += chunk; 1565 size -= chunk; 1566 } 1567 1568 return (0); 1569 1570 fail6: 1571 EFSYS_PROBE(fail6); 1572 fail5: 1573 EFSYS_PROBE(fail5); 1574 fail4: 1575 EFSYS_PROBE(fail4); 1576 fail3: 1577 EFSYS_PROBE(fail3); 1578 fail2: 1579 EFSYS_PROBE(fail2); 1580 fail1: 1581 EFSYS_PROBE1(fail1, int, rc); 1582 1583 return (rc); 1584 } 1585 1586 __checkReturn int 1587 sfx7101_nvram_erase( 1588 __in efx_nic_t *enp) 1589 { 1590 efx_port_t *epp = &(enp->en_port); 1591 efx_word_t word; 1592 int rc; 1593 1594 EFX_POPULATE_WORD_1(word, EFX_BYTE_0, LOADER_CMD_ERASE_FLASH); 1595 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1596 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0) 1597 goto fail1; 1598 1599 return (0); 1600 1601 fail1: 1602 EFSYS_PROBE1(fail1, int, rc); 1603 1604 return (rc); 1605 } 1606 1607 __checkReturn int 1608 sfx7101_nvram_write_chunk( 1609 __in efx_nic_t *enp, 1610 __in unsigned int offset, 1611 __in_bcount(size) caddr_t data, 1612 __in size_t size) 1613 { 1614 efx_port_t *epp = &(enp->en_port); 1615 efx_word_t word; 1616 unsigned int pos; 1617 size_t chunk; 1618 size_t words; 1619 int rc; 1620 1621 while (size > 0) { 1622 chunk = MIN(size, FIRMWARE_BLOCK_SIZE); 1623 1624 /* Write in 2byte words */ 1625 EFSYS_ASSERT(!(chunk & 0x1)); 1626 words = chunk >> 1; 1627 1628 /* Program address/length */ 1629 if ((rc = sfx7101_program_loader(enp, offset, words)) != 0) 1630 goto fail1; 1631 1632 /* Select write mode */ 1633 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_FILL_BUFFER); 1634 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1635 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1636 goto fail2; 1637 1638 for (pos = 0; pos < words; ++pos) { 1639 /* Firmware is little-endian */ 1640 word.ew_u8[0] = data[pos]; 1641 word.ew_u8[1] = data[pos+1]; 1642 1643 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1644 LOADER_MMD, LOADER_DATA_REG, &word)) != 0) 1645 goto fail3; 1646 } 1647 1648 EFX_POPULATE_WORD_1(word, EFX_WORD_0, 1649 LOADER_CMD_PROGRAM_FLASH); 1650 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1651 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0) 1652 goto fail4; 1653 1654 if ((rc = sfx7101_loader_wait(enp)) != 0) 1655 goto fail5; 1656 1657 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1658 LOADER_WORDS_WRITTEN_REG, &word)) != 0) 1659 goto fail6; 1660 1661 if (words != EFX_WORD_FIELD(word, EFX_WORD_0)) 1662 goto fail7; 1663 1664 size -= chunk; 1665 offset += chunk; 1666 data += chunk; 1667 } 1668 1669 return (0); 1670 1671 fail7: 1672 EFSYS_PROBE(fail7); 1673 fail6: 1674 EFSYS_PROBE(fail6); 1675 fail5: 1676 EFSYS_PROBE(fail5); 1677 fail4: 1678 EFSYS_PROBE(fail4); 1679 fail3: 1680 EFSYS_PROBE(fail3); 1681 fail2: 1682 EFSYS_PROBE(fail2); 1683 fail1: 1684 EFSYS_PROBE1(fail1, int, rc); 1685 1686 return (rc); 1687 } 1688 1689 1690 void 1691 sfx7101_nvram_rw_finish( 1692 __in efx_nic_t *enp) 1693 { 1694 efx_port_t *epp = &(enp->en_port); 1695 efx_word_t word; 1696 efx_byte_t byte; 1697 int rc; 1698 1699 EFX_SET_BYTE(byte); 1700 EFX_SET_BYTE_FIELD(byte, P0_EN_1V2, 0); 1701 EFX_SET_BYTE_FIELD(byte, P0_EN_2V5, 0); 1702 EFX_SET_BYTE_FIELD(byte, P0_EN_5V, 0); 1703 EFX_SET_BYTE_FIELD(byte, P0_X_TRST, 0); 1704 EFX_SET_BYTE_FIELD(byte, P0_FLASH_CFG_EN, 0); 1705 1706 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, 1707 (caddr_t)&byte, 1)) != 0) 1708 goto fail1; 1709 1710 /* Special software reset */ 1711 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1712 PMA_PMD_XCONTROL_REG, &word)) != 0) 1713 goto fail2; 1714 EFX_SET_WORD_FIELD(word, SSR, 1); 1715 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 1716 PMA_PMD_XCONTROL_REG, &word)) != 0) 1717 goto fail3; 1718 1719 /* Sleep 1/2 second */ 1720 EFSYS_SLEEP(500000); 1721 1722 /* Verify that PHY rebooted */ 1723 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1724 PCS_BOOT_STATUS_REG, &word)) != 0) 1725 goto fail4; 1726 if (EFX_WORD_FIELD(word, EFX_WORD_0) != 0x7E) 1727 goto fail5; 1728 1729 return; 1730 1731 fail5: 1732 EFSYS_PROBE(fail4); 1733 fail4: 1734 EFSYS_PROBE(fail4); 1735 fail3: 1736 EFSYS_PROBE(fail3); 1737 fail2: 1738 EFSYS_PROBE(fail2); 1739 fail1: 1740 EFSYS_PROBE1(fail1, int, rc); 1741 } 1742 1743 #endif /* EFSYS_OPT_NVRAM_SFX7101 */ 1744 1745 #endif /* EFSYS_OPT_PHY_SFX7101 */