1 /* 2 * Copyright 2008-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 "sft9001.h" 33 #include "sft9001_impl.h" 34 #include "xphy.h" 35 #include "falcon_impl.h" 36 37 #if EFSYS_OPT_PHY_SFT9001 38 39 static __checkReturn int 40 sft9001_short_reach_set( 41 __in efx_nic_t *enp, 42 __in boolean_t on) 43 { 44 efx_port_t *epp = &(enp->en_port); 45 efx_word_t word; 46 int rc; 47 48 if ((rc = falcon_mdio_read(enp, epp->ep_port, 49 PMA_PMD_MMD, PMA_PMD_PWR_BACKOFF_REG, &word)) != 0) 50 goto fail1; 51 52 EFX_SET_WORD_FIELD(word, SHORT_REACH, (on) ? 1 : 0); 53 54 if ((rc = falcon_mdio_write(enp, epp->ep_port, 55 PMA_PMD_MMD, PMA_PMD_PWR_BACKOFF_REG, &word)) != 0) 56 goto fail2; 57 58 return (0); 59 60 fail2: 61 EFSYS_PROBE(fail2); 62 fail1: 63 EFSYS_PROBE1(fail1, int, rc); 64 65 return (rc); 66 } 67 68 static __checkReturn int 69 sft9001_short_reach_get( 70 __in efx_nic_t *enp, 71 __out boolean_t *onp) 72 { 73 efx_port_t *epp = &(enp->en_port); 74 efx_word_t word; 75 int rc; 76 77 if ((rc = falcon_mdio_read(enp, epp->ep_port, 78 PMA_PMD_MMD, PMA_PMD_PWR_BACKOFF_REG, &word)) != 0) 79 goto fail1; 80 81 *onp = (EFX_WORD_FIELD(word, SHORT_REACH) != 0); 82 83 return (0); 84 85 fail1: 86 EFSYS_PROBE1(fail1, int, rc); 87 88 return (rc); 89 } 90 91 static __checkReturn int 92 sft9001_robust_set( 93 __in efx_nic_t *enp, 94 __in boolean_t on) 95 { 96 efx_port_t *epp = &(enp->en_port); 97 efx_word_t word; 98 int rc; 99 100 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 101 PMA_PMD_XCONTROL_REG, &word)) != 0) 102 goto fail1; 103 104 EFX_SET_WORD_FIELD(word, ROBUST, (on) ? 1 : 0); 105 106 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 107 PMA_PMD_XCONTROL_REG, &word)) != 0) 108 goto fail2; 109 110 return (0); 111 112 fail2: 113 EFSYS_PROBE(fail2); 114 fail1: 115 EFSYS_PROBE1(fail1, int, rc); 116 117 return (rc); 118 } 119 120 static __checkReturn int 121 sft9001_robust_get( 122 __in efx_nic_t *enp, 123 __out boolean_t *onp) 124 { 125 efx_port_t *epp = &(enp->en_port); 126 efx_word_t word; 127 int rc; 128 129 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 130 PMA_PMD_XCONTROL_REG, &word)) != 0) 131 goto fail1; 132 133 *onp = (EFX_WORD_FIELD(word, ROBUST) != 0); 134 135 return (0); 136 137 fail1: 138 EFSYS_PROBE1(fail1, int, rc); 139 140 return (rc); 141 } 142 143 static __checkReturn int 144 sft9001_an_set( 145 __in efx_nic_t *enp, 146 __in boolean_t on) 147 { 148 efx_port_t *epp = &(enp->en_port); 149 efx_word_t word; 150 int rc; 151 152 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 153 AN_CONTROL1_REG, &word)) != 0) 154 goto fail1; 155 156 if (on) { 157 EFX_SET_WORD_FIELD(word, AN_ENABLE, 1); 158 EFX_SET_WORD_FIELD(word, AN_RESTART, 1); 159 } else { 160 EFX_SET_WORD_FIELD(word, AN_ENABLE, 0); 161 } 162 163 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD, 164 AN_CONTROL1_REG, &word)) != 0) 165 goto fail2; 166 167 return (0); 168 169 fail2: 170 EFSYS_PROBE(fail2); 171 fail1: 172 EFSYS_PROBE1(fail1, int, rc); 173 174 return (rc); 175 } 176 177 static __checkReturn int 178 sft9001_gmii_cfg( 179 __in efx_nic_t *enp) 180 { 181 efx_port_t *epp = &(enp->en_port); 182 efx_word_t word; 183 int rc; 184 185 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 186 PMA_PMD_XCONTROL_REG, &word)) != 0) 187 goto fail1; 188 189 EFX_SET_WORD_FIELD(word, GMII_EN, 1); 190 191 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 192 PMA_PMD_XCONTROL_REG, &word)) != 0) 193 goto fail2; 194 195 return (0); 196 197 fail2: 198 EFSYS_PROBE(fail2); 199 fail1: 200 EFSYS_PROBE1(fail1, int, rc); 201 202 return (rc); 203 } 204 205 static __checkReturn int 206 sft9001_clock_cfg( 207 __in efx_nic_t *enp) 208 { 209 efx_port_t *epp = &(enp->en_port); 210 efx_word_t word; 211 int rc; 212 213 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 214 PMA_PMD_XCONTROL_REG, &word)) != 0) 215 goto fail1; 216 217 /* Select 312MHz clock on CLK312_OUT_{P,N} */ 218 EFX_SET_WORD_FIELD(word, CLK312_OUT_SEL, SEL_312MHZ_DECODE); 219 EFX_SET_WORD_FIELD(word, CLK312_OUT_EN, 1); 220 221 /* Select 125MHz clock on TEST_CLKOUT_{P,N} */ 222 EFX_SET_WORD_FIELD(word, TEST_CLKOUT_SEL, SEL_125MHZ_DECODE); 223 EFX_SET_WORD_FIELD(word, TEST_CLKOUT_EN, 1); 224 225 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 226 PMA_PMD_XCONTROL_REG, &word)) != 0) 227 goto fail2; 228 229 return (0); 230 231 fail2: 232 EFSYS_PROBE(fail2); 233 fail1: 234 EFSYS_PROBE1(fail1, int, rc); 235 236 return (rc); 237 } 238 239 static __checkReturn int 240 sft9001_adv_cap_cfg( 241 __in efx_nic_t *enp) 242 { 243 efx_port_t *epp = &(enp->en_port); 244 efx_word_t word; 245 int rc; 246 247 /* Check base page */ 248 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 249 AN_ADV_BP_CAP_REG, &word)) != 0) 250 goto fail1; 251 252 EFSYS_ASSERT(!(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_10HDX))); 253 if (EFX_WORD_FIELD(word, AN_ADV_TA_10BASE_T) != 0) 254 EFX_SET_WORD_FIELD(word, AN_ADV_TA_10BASE_T, 0); 255 256 EFSYS_ASSERT(!(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_10FDX))); 257 if (EFX_WORD_FIELD(word, AN_ADV_TA_10BASE_T_FDX) != 0) 258 EFX_SET_WORD_FIELD(word, AN_ADV_TA_10BASE_T_FDX, 0); 259 260 if (EFX_WORD_FIELD(word, AN_ADV_TA_100BASE_TX) == 0 && 261 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_100HDX)) 262 EFX_SET_WORD_FIELD(word, AN_ADV_TA_100BASE_TX, 1); 263 else if (EFX_WORD_FIELD(word, AN_ADV_TA_100BASE_TX) != 0 && 264 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_100HDX))) 265 EFX_SET_WORD_FIELD(word, AN_ADV_TA_100BASE_TX, 0); 266 267 if (EFX_WORD_FIELD(word, AN_ADV_TA_100BASE_TX_FDX) == 0 && 268 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_100FDX)) 269 EFX_SET_WORD_FIELD(word, AN_ADV_TA_100BASE_TX_FDX, 1); 270 else if (EFX_WORD_FIELD(word, AN_ADV_TA_100BASE_TX_FDX) != 0 && 271 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_100FDX))) 272 EFX_SET_WORD_FIELD(word, AN_ADV_TA_100BASE_TX_FDX, 0); 273 274 if (EFX_WORD_FIELD(word, AN_ADV_TA_PAUSE) == 0 && 275 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 276 EFX_SET_WORD_FIELD(word, AN_ADV_TA_PAUSE, 1); 277 else if (EFX_WORD_FIELD(word, AN_ADV_TA_PAUSE) != 0 && 278 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))) 279 EFX_SET_WORD_FIELD(word, AN_ADV_TA_PAUSE, 0); 280 281 if (EFX_WORD_FIELD(word, AN_ADV_TA_ASM_DIR) == 0 && 282 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM)) 283 EFX_SET_WORD_FIELD(word, AN_ADV_TA_ASM_DIR, 1); 284 else if (EFX_WORD_FIELD(word, AN_ADV_TA_ASM_DIR) != 0 && 285 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))) 286 EFX_SET_WORD_FIELD(word, AN_ADV_TA_ASM_DIR, 0); 287 288 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD, 289 AN_ADV_BP_CAP_REG, &word)) != 0) 290 goto fail2; 291 292 /* Check 1G operation */ 293 if ((rc = falcon_mdio_read(enp, epp->ep_port, CL22EXT_MMD, 294 CL22EXT_MS_CONTROL_REG, &word)) != 0) 295 goto fail3; 296 297 EFSYS_ASSERT(!(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_1000HDX))); 298 if (EFX_WORD_FIELD(word, CL22EXT_1000BASE_T_ADV) != 0) 299 EFX_SET_WORD_FIELD(word, CL22EXT_1000BASE_T_ADV, 0); 300 301 if (EFX_WORD_FIELD(word, CL22EXT_1000BASE_T_FDX_ADV) == 0 && 302 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_1000FDX)) 303 EFX_SET_WORD_FIELD(word, CL22EXT_1000BASE_T_FDX_ADV, 1); 304 else if (EFX_WORD_FIELD(word, CL22EXT_1000BASE_T_FDX_ADV) != 0 && 305 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_1000FDX))) 306 EFX_SET_WORD_FIELD(word, CL22EXT_1000BASE_T_FDX_ADV, 0); 307 308 if ((rc = falcon_mdio_write(enp, epp->ep_port, CL22EXT_MMD, 309 CL22EXT_MS_CONTROL_REG, &word)) != 0) 310 goto fail4; 311 312 /* Check 10G operation */ 313 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 314 AN_10G_BASE_T_CONTROL_REG, &word)) != 0) 315 goto fail5; 316 317 if (EFX_WORD_FIELD(word, AN_10G_BASE_T_ADV) == 0 && 318 epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_10000FDX)) 319 EFX_SET_WORD_FIELD(word, AN_10G_BASE_T_ADV, 1); 320 else if (EFX_WORD_FIELD(word, AN_10G_BASE_T_ADV) != 0 && 321 !(epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_10000FDX))) 322 EFX_SET_WORD_FIELD(word, AN_10G_BASE_T_ADV, 0); 323 324 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD, 325 AN_10G_BASE_T_CONTROL_REG, &word)) != 0) 326 goto fail6; 327 328 return (0); 329 330 fail6: 331 EFSYS_PROBE(fail6); 332 fail5: 333 EFSYS_PROBE(fail5); 334 fail4: 335 EFSYS_PROBE(fail4); 336 fail3: 337 EFSYS_PROBE(fail3); 338 fail2: 339 EFSYS_PROBE(fail2); 340 fail1: 341 EFSYS_PROBE1(fail1, int, rc); 342 343 return (rc); 344 } 345 346 #if EFSYS_OPT_LOOPBACK 347 static __checkReturn int 348 sft9001_loopback_cfg( 349 __in efx_nic_t *enp) 350 { 351 efx_port_t *epp = &(enp->en_port); 352 efx_word_t word; 353 int rc; 354 355 switch (epp->ep_loopback_type) { 356 case EFX_LOOPBACK_PHY_XS: 357 if ((rc = falcon_mdio_read(enp, epp->ep_port, 358 PHY_XS_MMD, PHY_XS_TEST1_REG, &word)) != 0) 359 goto fail1; 360 361 EFX_SET_WORD_FIELD(word, PHY_XS_NE_LOOPBACK, 1); 362 363 if ((rc = falcon_mdio_write(enp, epp->ep_port, 364 PHY_XS_MMD, PHY_XS_TEST1_REG, &word)) != 0) 365 goto fail2; 366 367 break; 368 369 case EFX_LOOPBACK_PCS: 370 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PCS_MMD, 371 B_TRUE)) != 0) 372 goto fail1; 373 374 break; 375 376 case EFX_LOOPBACK_PMA_PMD: 377 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PMA_PMD_MMD, 378 B_TRUE)) != 0) 379 goto fail1; 380 381 break; 382 383 case EFX_LOOPBACK_GPHY: 384 if ((rc = falcon_mdio_read(enp, epp->ep_port, 385 CL22EXT_MMD, CL22EXT_CONTROL_REG, &word)) != 0) 386 goto fail1; 387 388 EFX_SET_WORD_FIELD(word, CL22EXT_NE_LOOPBACK, 1); 389 390 if ((rc = falcon_mdio_write(enp, epp->ep_port, 391 CL22EXT_MMD, CL22EXT_CONTROL_REG, &word)) != 0) 392 goto fail2; 393 394 break; 395 396 default: 397 break; 398 } 399 400 return (0); 401 402 fail2: 403 EFSYS_PROBE(fail2); 404 fail1: 405 EFSYS_PROBE1(fail1, int, rc); 406 407 return (rc); 408 } 409 #endif /* EFSYS_OPT_LOOPBACK */ 410 411 static __checkReturn int 412 sft9001_led_cfg( 413 __in efx_nic_t *enp) 414 { 415 efx_port_t *epp = &(enp->en_port); 416 efx_word_t word; 417 int rc; 418 419 #if EFSYS_OPT_PHY_LED_CONTROL 420 421 switch (epp->ep_phy_led_mode) { 422 case EFX_PHY_LED_DEFAULT: 423 EFX_POPULATE_WORD_8(word, 424 LED_TMODE, LED_NORMAL_DECODE, 425 LED_SPARE, LED_NORMAL_DECODE, 426 LED_MS, LED_NORMAL_DECODE, 427 LED_RX, LED_NORMAL_DECODE, 428 LED_TX, LED_NORMAL_DECODE, 429 LED_SPEED0, LED_NORMAL_DECODE, 430 LED_SPEED1, LED_NORMAL_DECODE, 431 LED_LINK, LED_NORMAL_DECODE); 432 break; 433 434 case EFX_PHY_LED_OFF: 435 EFX_POPULATE_WORD_8(word, 436 LED_TMODE, LED_OFF_DECODE, 437 LED_SPARE, LED_OFF_DECODE, 438 LED_MS, LED_OFF_DECODE, 439 LED_RX, LED_OFF_DECODE, 440 LED_TX, LED_OFF_DECODE, 441 LED_SPEED0, LED_OFF_DECODE, 442 LED_SPEED1, LED_OFF_DECODE, 443 LED_LINK, LED_OFF_DECODE); 444 break; 445 446 case EFX_PHY_LED_ON: 447 EFX_POPULATE_WORD_8(word, 448 LED_TMODE, LED_ON_DECODE, 449 LED_SPARE, LED_ON_DECODE, 450 LED_MS, LED_ON_DECODE, 451 LED_RX, LED_ON_DECODE, 452 LED_TX, LED_ON_DECODE, 453 LED_SPEED0, LED_ON_DECODE, 454 LED_SPEED1, LED_ON_DECODE, 455 LED_LINK, LED_ON_DECODE); 456 break; 457 458 case EFX_PHY_LED_FLASH: 459 EFX_POPULATE_WORD_8(word, 460 LED_TMODE, LED_FLASH_DECODE, 461 LED_SPARE, LED_FLASH_DECODE, 462 LED_MS, LED_FLASH_DECODE, 463 LED_RX, LED_FLASH_DECODE, 464 LED_TX, LED_FLASH_DECODE, 465 LED_SPEED0, LED_FLASH_DECODE, 466 LED_SPEED1, LED_FLASH_DECODE, 467 LED_LINK, LED_FLASH_DECODE); 468 break; 469 470 default: 471 EFSYS_ASSERT(B_FALSE); 472 break; 473 } 474 475 #else /* EFSYS_OPT_PHY_LED_CONTROL */ 476 477 EFX_POPULATE_WORD_8(word, 478 LED_TMODE, LED_NORMAL_DECODE, 479 LED_SPARE, LED_NORMAL_DECODE, 480 LED_MS, LED_NORMAL_DECODE, 481 LED_RX, LED_NORMAL_DECODE, 482 LED_TX, LED_NORMAL_DECODE, 483 LED_SPEED0, LED_NORMAL_DECODE, 484 LED_SPEED1, LED_NORMAL_DECODE, 485 LED_LINK, LED_NORMAL_DECODE); 486 487 #endif /* EFSYS_OPT_PHY_LED_CONTROL */ 488 489 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 490 PMA_PMD_LED_OVERRIDE_REG, &word)) != 0) 491 goto fail1; 492 493 return (0); 494 495 fail1: 496 EFSYS_PROBE1(fail1, int, rc); 497 498 return (rc); 499 } 500 501 __checkReturn int 502 sft9001_reset( 503 __in efx_nic_t *enp) 504 { 505 int state; 506 507 /* Lock I2C bus because sft9001 is sensitive to GPIO3 */ 508 EFSYS_LOCK(enp->en_eslp, state); 509 EFSYS_ASSERT(!enp->en_u.falcon.enu_i2c_locked); 510 enp->en_u.falcon.enu_i2c_locked = B_TRUE; 511 EFSYS_UNLOCK(enp->en_eslp, state); 512 513 /* Pull the external reset line */ 514 falcon_nic_phy_reset(enp); 515 516 /* Unlock I2C */ 517 EFSYS_LOCK(enp->en_eslp, state); 518 enp->en_u.falcon.enu_i2c_locked = B_FALSE; 519 EFSYS_UNLOCK(enp->en_eslp, state); 520 521 return (0); 522 } 523 524 __checkReturn int 525 sft9001_reconfigure( 526 __in efx_nic_t *enp) 527 { 528 efx_port_t *epp = &(enp->en_port); 529 unsigned int count; 530 int rc; 531 532 /* Wait for the firmware boot to complete */ 533 count = 0; 534 do { 535 efx_word_t word; 536 537 EFSYS_PROBE1(wait, unsigned int, count); 538 539 /* Spin for 1 ms */ 540 EFSYS_SPIN(1000); 541 542 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 543 PCS_BOOT_STATUS_REG, &word)) != 0) 544 goto fail1; 545 546 if (EFX_WORD_FIELD(word, FATAL_ERR) != 0) 547 break; /* no point in continuing */ 548 549 if (EFX_WORD_FIELD(word, BOOT_STATUS) != 0 && 550 EFX_WORD_FIELD(word, CODE_DOWNLOAD) != 0 && 551 EFX_WORD_FIELD(word, CKSUM_OK) != 0 && 552 EFX_WORD_FIELD(word, CODE_STARTED) != 0 && 553 EFX_WORD_FIELD(word, BOOT_PROGRESS) == APP_JMP_DECODE) 554 goto configure; 555 556 } while (++count < 1000); 557 558 rc = ENOTACTIVE; 559 goto fail2; 560 561 configure: 562 if ((rc = xphy_pkg_wait(enp, epp->ep_port, SFT9001_MMD_MASK)) != 0) 563 goto fail3; 564 565 /* Make sure auto-negotiation is off whilst we configure the PHY */ 566 if ((rc = sft9001_an_set(enp, B_FALSE)) != 0) 567 goto fail4; 568 569 if ((rc = sft9001_gmii_cfg(enp)) != 0) 570 goto fail5; 571 572 if ((rc = sft9001_clock_cfg(enp)) != 0) 573 goto fail6; 574 575 if ((rc = sft9001_adv_cap_cfg(enp)) != 0) 576 goto fail7; 577 578 #if EFSYS_OPT_LOOPBACK 579 if ((rc = sft9001_loopback_cfg(enp)) != 0) 580 goto fail8; 581 #endif /* EFSYS_OPT_LOOPBACK */ 582 583 if ((rc = sft9001_led_cfg(enp)) != 0) 584 goto fail9; 585 586 if ((rc = sft9001_robust_set(enp, B_TRUE)) != 0) 587 goto fail10; 588 589 #if EFSYS_OPT_LOOPBACK 590 if (epp->ep_loopback_type == EFX_LOOPBACK_OFF) { 591 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 592 goto fail11; 593 } 594 #else /* EFSYS_OPT_LOOPBACK */ 595 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 596 goto fail11; 597 #endif /* EFSYS_OPT_LOOPBACK */ 598 599 return (0); 600 601 fail11: 602 EFSYS_PROBE(fail11); 603 fail10: 604 EFSYS_PROBE(fail10); 605 fail9: 606 EFSYS_PROBE(fail9); 607 608 #if EFSYS_OPT_LOOPBACK 609 fail8: 610 EFSYS_PROBE(fail8); 611 #endif /* EFSYS_OPT_LOOPBACK */ 612 613 fail7: 614 EFSYS_PROBE(fail7); 615 fail6: 616 EFSYS_PROBE(fail6); 617 fail5: 618 EFSYS_PROBE(fail5); 619 fail4: 620 EFSYS_PROBE(fail4); 621 fail3: 622 EFSYS_PROBE(fail3); 623 fail2: 624 EFSYS_PROBE(fail2); 625 fail1: 626 EFSYS_PROBE1(fail1, int, rc); 627 628 return (rc); 629 } 630 631 __checkReturn int 632 sft9001_verify( 633 __in efx_nic_t *enp) 634 { 635 efx_port_t *epp = &(enp->en_port); 636 int rc; 637 638 if ((rc = xphy_pkg_verify(enp, epp->ep_port, SFT9001_MMD_MASK)) != 0) 639 goto fail1; 640 641 return (0); 642 643 fail1: 644 EFSYS_PROBE1(fail1, int, rc); 645 646 return (rc); 647 } 648 649 __checkReturn int 650 sft9001_uplink_check( 651 __in efx_nic_t *enp, 652 __out boolean_t *upp) 653 { 654 efx_port_t *epp = &(enp->en_port); 655 efx_word_t word; 656 int rc; 657 658 if (epp->ep_mac_type != EFX_MAC_FALCON_XMAC) { 659 rc = ENOTSUP; 660 goto fail1; 661 } 662 663 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 664 PHY_XS_LANE_STATUS_REG, &word)) != 0) 665 goto fail2; 666 667 *upp = ((EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) && 668 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) && 669 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) && 670 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) && 671 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0)); 672 673 return (0); 674 675 fail2: 676 EFSYS_PROBE(fail2); 677 fail1: 678 EFSYS_PROBE1(fail1, int, rc); 679 680 return (rc); 681 } 682 683 static __checkReturn int 684 sft9001_lp_cap_get( 685 __in efx_nic_t *enp, 686 __out unsigned int *maskp) 687 { 688 efx_port_t *epp = &(enp->en_port); 689 efx_word_t word; 690 int rc; 691 692 *maskp = 0; 693 694 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 695 AN_LP_BP_CAP_REG, &word)) != 0) 696 goto fail1; 697 698 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T) != 0) 699 *maskp |= (1 << EFX_PHY_CAP_10HDX); 700 701 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T_FDX) != 0) 702 *maskp |= (1 << EFX_PHY_CAP_10FDX); 703 704 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX) != 0) 705 *maskp |= (1 << EFX_PHY_CAP_100HDX); 706 707 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX_FDX) != 0) 708 *maskp |= (1 << EFX_PHY_CAP_100FDX); 709 710 if (EFX_WORD_FIELD(word, AN_LP_TA_PAUSE) != 0) 711 *maskp |= (1 << EFX_PHY_CAP_PAUSE); 712 713 if (EFX_WORD_FIELD(word, AN_LP_TA_ASM_DIR) != 0) 714 *maskp |= (1 << EFX_PHY_CAP_ASYM); 715 716 if ((rc = falcon_mdio_read(enp, epp->ep_port, CL22EXT_MMD, 717 CL22EXT_MS_STATUS_REG, &word)) != 0) 718 goto fail2; 719 720 if (EFX_WORD_FIELD(word, CL22EXT_1000BASE_T_LP) != 0) 721 *maskp |= (1 << EFX_PHY_CAP_1000HDX); 722 723 if (EFX_WORD_FIELD(word, CL22EXT_1000BASE_T_FDX_LP) != 0) 724 *maskp |= (1 << EFX_PHY_CAP_1000FDX); 725 726 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 727 AN_10G_BASE_T_STATUS_REG, &word)) != 0) 728 goto fail3; 729 730 if (EFX_WORD_FIELD(word, AN_10G_BASE_T_LP) != 0) 731 *maskp |= (1 << EFX_PHY_CAP_10000FDX); 732 733 return (0); 734 735 fail3: 736 EFSYS_PROBE(fail3); 737 fail2: 738 EFSYS_PROBE(fail2); 739 fail1: 740 EFSYS_PROBE1(fail1, int, rc); 741 742 return (rc); 743 } 744 745 __checkReturn int 746 sft9001_downlink_check( 747 __in efx_nic_t *enp, 748 __out efx_link_mode_t *modep, 749 __out unsigned int *fcntlp, 750 __out uint32_t *lp_cap_maskp) 751 { 752 efx_port_t *epp = &(enp->en_port); 753 unsigned int fcntl = epp->ep_fcntl; 754 unsigned int lp_cap_mask = epp->ep_lp_cap_mask; 755 boolean_t up; 756 uint32_t common; 757 int rc; 758 759 #if EFSYS_OPT_LOOPBACK 760 switch (epp->ep_loopback_type) { 761 case EFX_LOOPBACK_PHY_XS: 762 rc = xphy_mmd_fault(enp, epp->ep_port, &up); 763 if (rc != 0) 764 goto fail1; 765 766 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN; 767 goto done; 768 769 case EFX_LOOPBACK_PCS: 770 case EFX_LOOPBACK_PMA_PMD: 771 rc = xphy_mmd_check(enp, epp->ep_port, PHY_XS_MMD, &up); 772 if (rc != 0) 773 goto fail1; 774 775 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN; 776 goto done; 777 778 case EFX_LOOPBACK_GPHY: 779 *modep = EFX_LINK_1000FDX; 780 goto done; 781 782 default: 783 break; 784 } 785 #endif /* EFSYS_OPT_LOOPBACK */ 786 787 if ((rc = xphy_mmd_check(enp, epp->ep_port, AN_MMD, &up)) != 0) 788 goto fail1; 789 790 if (!up) { 791 *modep = EFX_LINK_DOWN; 792 goto done; 793 } 794 795 /* Check the link partner capabilities */ 796 if ((rc = sft9001_lp_cap_get(enp, &lp_cap_mask)) != 0) 797 goto fail2; 798 799 /* Resolve the common capabilities */ 800 common = epp->ep_adv_cap_mask & lp_cap_mask; 801 802 /* The 'best' common link mode should be the one in operation */ 803 if (common & (1 << EFX_PHY_CAP_10000FDX)) { 804 *modep = EFX_LINK_10000FDX; 805 } else if (common & (1 << EFX_PHY_CAP_1000FDX)) { 806 *modep = EFX_LINK_1000FDX; 807 } else if (common & (1 << EFX_PHY_CAP_100FDX)) { 808 *modep = EFX_LINK_100FDX; 809 } else if (common & (1 << EFX_PHY_CAP_100HDX)) { 810 *modep = EFX_LINK_100HDX; 811 } else { 812 *modep = EFX_LINK_UNKNOWN; 813 } 814 815 /* Determine negotiated or forced flow control mode */ 816 fcntl = 0; 817 if (epp->ep_fcntl_autoneg) { 818 if (common & (1 << EFX_PHY_CAP_PAUSE)) 819 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND; 820 else if (common & (1 << EFX_PHY_CAP_ASYM)) { 821 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 822 fcntl = EFX_FCNTL_RESPOND; 823 else if (lp_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 824 fcntl = EFX_FCNTL_GENERATE; 825 } 826 } else { 827 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) 828 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND; 829 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM)) 830 fcntl ^= EFX_FCNTL_GENERATE; 831 } 832 833 done: 834 *fcntlp = fcntl; 835 *lp_cap_maskp = lp_cap_mask; 836 837 return (0); 838 839 fail2: 840 EFSYS_PROBE(fail2); 841 fail1: 842 EFSYS_PROBE1(fail1, int, rc); 843 844 return (rc); 845 } 846 847 __checkReturn int 848 sft9001_oui_get( 849 __in efx_nic_t *enp, 850 __out uint32_t *ouip) 851 { 852 efx_port_t *epp = &(enp->en_port); 853 int rc; 854 855 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, ouip)) != 0) 856 goto fail1; 857 858 return (0); 859 860 fail1: 861 EFSYS_PROBE1(fail1, int, rc); 862 863 return (rc); 864 } 865 866 #define SFT9001_STAT_SET(_stat, _mode, _id, _val) \ 867 do { \ 868 (_mode) |= (1 << (_id)); \ 869 (_stat)[_id] = (uint32_t)(_val); \ 870 _NOTE(CONSTANTCONDITION) \ 871 } while (B_FALSE) 872 873 static __checkReturn int 874 sft9001_rev_get( 875 __in efx_nic_t *enp, 876 __out uint8_t *ap, 877 __out uint8_t *bp, 878 __out uint8_t *cp, 879 __out uint8_t *dp) 880 { 881 efx_port_t *epp = &(enp->en_port); 882 efx_word_t word; 883 int rc; 884 885 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 886 PMA_PMD_FW_REV0_REG, &word)) != 0) 887 goto fail1; 888 889 *ap = (uint8_t)EFX_WORD_FIELD(word, EFX_BYTE_1); 890 *bp = (uint8_t)EFX_WORD_FIELD(word, EFX_BYTE_0); 891 892 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 893 PMA_PMD_FW_REV1_REG, &word)) != 0) 894 goto fail2; 895 896 *cp = (uint8_t)EFX_WORD_FIELD(word, EFX_BYTE_1); 897 *dp = (uint8_t)EFX_WORD_FIELD(word, EFX_BYTE_0); 898 899 return (0); 900 901 fail2: 902 EFSYS_PROBE(fail2); 903 fail1: 904 EFSYS_PROBE1(fail1, int, rc); 905 906 return (rc); 907 } 908 909 #if EFSYS_OPT_PHY_STATS 910 911 static __checkReturn int 912 sft9001_pma_pmd_stats_update( 913 __in efx_nic_t *enp, 914 __inout uint64_t *maskp, 915 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 916 { 917 efx_port_t *epp = &(enp->en_port); 918 efx_word_t word; 919 uint8_t a; 920 uint8_t b; 921 uint8_t c; 922 uint8_t d; 923 int rc; 924 925 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 926 PMA_PMD_STATUS1_REG, &word)) != 0) 927 goto fail1; 928 929 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_LINK_UP, 930 (EFX_WORD_FIELD(word, PMA_PMD_LINK_UP) != 0) ? 1 : 0); 931 932 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 933 PMA_PMD_STATUS2_REG, &word)) != 0) 934 goto fail2; 935 936 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_RX_FAULT, 937 (EFX_WORD_FIELD(word, PMA_PMD_RX_FAULT) != 0) ? 1 : 0); 938 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_TX_FAULT, 939 (EFX_WORD_FIELD(word, PMA_PMD_TX_FAULT) != 0) ? 1 : 0); 940 941 if ((rc = sft9001_rev_get(enp, &a, &b, &c, &d)) != 0) 942 goto fail3; 943 944 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_A, a); 945 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_B, b); 946 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_C, c); 947 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_D, d); 948 949 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 950 PMA_PMD_CHANNELA_SNR_REG, &word)) != 0) 951 goto fail4; 952 953 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_A, 954 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 955 956 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 957 PMA_PMD_CHANNELB_SNR_REG, &word)) != 0) 958 goto fail5; 959 960 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_B, 961 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 962 963 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 964 PMA_PMD_CHANNELC_SNR_REG, &word)) != 0) 965 goto fail6; 966 967 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_C, 968 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 969 970 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 971 PMA_PMD_CHANNELD_SNR_REG, &word)) != 0) 972 goto fail7; 973 974 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_D, 975 EFX_WORD_FIELD(word, PMA_PMD_SNR)); 976 977 return (0); 978 979 fail7: 980 EFSYS_PROBE(fail7); 981 fail6: 982 EFSYS_PROBE(fail6); 983 fail5: 984 EFSYS_PROBE(fail5); 985 fail4: 986 EFSYS_PROBE(fail4); 987 fail3: 988 EFSYS_PROBE(fail3); 989 fail2: 990 EFSYS_PROBE(fail2); 991 fail1: 992 EFSYS_PROBE1(fail1, int, rc); 993 994 return (rc); 995 } 996 997 static __checkReturn int 998 sft9001_pcs_stats_update( 999 __in efx_nic_t *enp, 1000 __inout uint64_t *maskp, 1001 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1002 { 1003 efx_port_t *epp = &(enp->en_port); 1004 efx_word_t word; 1005 int rc; 1006 1007 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1008 PCS_STATUS1_REG, &word)) != 0) 1009 goto fail1; 1010 1011 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_LINK_UP, 1012 (EFX_WORD_FIELD(word, PCS_LINK_UP) != 0) ? 1 : 0); 1013 1014 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1015 PCS_STATUS2_REG, &word)) != 0) 1016 goto fail2; 1017 1018 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_RX_FAULT, 1019 (EFX_WORD_FIELD(word, PCS_RX_FAULT) != 0) ? 1 : 0); 1020 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_TX_FAULT, 1021 (EFX_WORD_FIELD(word, PCS_TX_FAULT) != 0) ? 1 : 0); 1022 1023 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1024 PCS_10GBASE_T_STATUS2_REG, &word)) != 0) 1025 goto fail3; 1026 1027 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BER, 1028 EFX_WORD_FIELD(word, PCS_BER)); 1029 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BLOCK_ERRORS, 1030 EFX_WORD_FIELD(word, PCS_ERR)); 1031 1032 return (0); 1033 1034 fail3: 1035 EFSYS_PROBE(fail3); 1036 fail2: 1037 EFSYS_PROBE(fail2); 1038 fail1: 1039 EFSYS_PROBE1(fail1, int, rc); 1040 1041 return (rc); 1042 } 1043 1044 static __checkReturn int 1045 sft9001_phy_xs_stats_update( 1046 __in efx_nic_t *enp, 1047 __inout uint64_t *maskp, 1048 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1049 { 1050 efx_port_t *epp = &(enp->en_port); 1051 efx_word_t word; 1052 int rc; 1053 1054 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1055 PHY_XS_STATUS1_REG, &word)) != 0) 1056 goto fail1; 1057 1058 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_LINK_UP, 1059 (EFX_WORD_FIELD(word, PHY_XS_LINK_UP) != 0) ? 1 : 0); 1060 1061 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1062 PHY_XS_STATUS2_REG, &word)) != 0) 1063 goto fail2; 1064 1065 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_RX_FAULT, 1066 (EFX_WORD_FIELD(word, PHY_XS_RX_FAULT) != 0) ? 1 : 0); 1067 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_TX_FAULT, 1068 (EFX_WORD_FIELD(word, PHY_XS_TX_FAULT) != 0) ? 1 : 0); 1069 1070 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD, 1071 PHY_XS_LANE_STATUS_REG, &word)) != 0) 1072 goto fail3; 1073 1074 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_ALIGN, 1075 (EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) ? 1 : 0); 1076 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_A, 1077 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) ? 1 : 0); 1078 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_B, 1079 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) ? 1 : 0); 1080 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_C, 1081 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) ? 1 : 0); 1082 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_D, 1083 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0) ? 1 : 0); 1084 1085 return (0); 1086 1087 fail3: 1088 EFSYS_PROBE(fail3); 1089 fail2: 1090 EFSYS_PROBE(fail2); 1091 fail1: 1092 EFSYS_PROBE1(fail1, int, rc); 1093 1094 return (rc); 1095 } 1096 1097 static __checkReturn int 1098 sft9001_an_stats_update( 1099 __in efx_nic_t *enp, 1100 __inout uint64_t *maskp, 1101 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1102 { 1103 efx_port_t *epp = &(enp->en_port); 1104 efx_word_t word; 1105 int rc; 1106 1107 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 1108 AN_STATUS1_REG, &word)) != 0) 1109 goto fail1; 1110 1111 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LINK_UP, 1112 (EFX_WORD_FIELD(word, AN_LINK_UP) != 0) ? 1 : 0); 1113 1114 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD, 1115 AN_10G_BASE_T_STATUS_REG, &word)) != 0) 1116 goto fail2; 1117 1118 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_MASTER, 1119 (EFX_WORD_FIELD(word, AN_MASTER) != 0) ? 1 : 0); 1120 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LOCAL_RX_OK, 1121 (EFX_WORD_FIELD(word, AN_LOCAL_RX_OK) != 0) ? 1 : 0); 1122 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_REMOTE_RX_OK, 1123 (EFX_WORD_FIELD(word, AN_REMOTE_RX_OK) != 0) ? 1 : 0); 1124 1125 return (0); 1126 1127 fail2: 1128 EFSYS_PROBE(fail2); 1129 fail1: 1130 EFSYS_PROBE1(fail1, int, rc); 1131 1132 return (rc); 1133 } 1134 1135 static __checkReturn int 1136 sft9001_cl22ext_stats_update( 1137 __in efx_nic_t *enp, 1138 __inout uint64_t *maskp, 1139 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1140 { 1141 efx_port_t *epp = &(enp->en_port); 1142 efx_word_t word; 1143 int rc; 1144 1145 if ((rc = falcon_mdio_read(enp, epp->ep_port, CL22EXT_MMD, 1146 CL22EXT_STATUS_REG, &word)) != 0) 1147 goto fail1; 1148 1149 SFT9001_STAT_SET(stat, *maskp, EFX_PHY_STAT_CL22EXT_LINK_UP, 1150 (EFX_WORD_FIELD(word, CL22EXT_LINK_UP) != 0) ? 1 : 0); 1151 1152 return (0); 1153 1154 fail1: 1155 EFSYS_PROBE1(fail1, int, rc); 1156 1157 return (rc); 1158 } 1159 1160 1161 __checkReturn int 1162 sft9001_stats_update( 1163 __in efx_nic_t *enp, 1164 __in efsys_mem_t *esmp, 1165 __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) 1166 { 1167 efx_port_t *epp = &(enp->en_port); 1168 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1169 uint64_t mask = 0; 1170 uint32_t oui; 1171 int rc; 1172 1173 _NOTE(ARGUNUSED(esmp)) 1174 1175 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, &oui)) != 0) 1176 goto fail1; 1177 1178 SFT9001_STAT_SET(stat, mask, EFX_PHY_STAT_OUI, oui); 1179 1180 if ((rc = sft9001_pma_pmd_stats_update(enp, &mask, stat)) != 0) 1181 goto fail2; 1182 1183 if ((rc = sft9001_pcs_stats_update(enp, &mask, stat)) != 0) 1184 goto fail3; 1185 1186 if ((rc = sft9001_phy_xs_stats_update(enp, &mask, stat)) != 0) 1187 goto fail4; 1188 1189 if ((rc = sft9001_an_stats_update(enp, &mask, stat)) != 0) 1190 goto fail5; 1191 1192 if ((rc = sft9001_cl22ext_stats_update(enp, &mask, stat)) != 0) 1193 goto fail6; 1194 1195 /* Ensure all the supported statistics are up to date */ 1196 EFSYS_ASSERT(mask == encp->enc_phy_stat_mask); 1197 1198 return (0); 1199 1200 fail6: 1201 EFSYS_PROBE(fail6); 1202 fail5: 1203 EFSYS_PROBE(fail5); 1204 fail4: 1205 EFSYS_PROBE(fail4); 1206 fail3: 1207 EFSYS_PROBE(fail3); 1208 fail2: 1209 EFSYS_PROBE(fail2); 1210 fail1: 1211 EFSYS_PROBE1(fail1, int, rc); 1212 1213 return (rc); 1214 } 1215 #endif /* EFSYS_OPT_PHY_STATS */ 1216 1217 #if EFSYS_OPT_PHY_PROPS 1218 1219 #if EFSYS_OPT_NAMES 1220 /* START MKCONFIG GENERATED Sft9001PhyPropNamesBlock 575ed5e718aa4657 */ 1221 static const char __cs * __cs __sft9001_prop_name[] = { 1222 "short_reach", 1223 "robust", 1224 }; 1225 1226 /* END MKCONFIG GENERATED Sft9001PhyPropNamesBlock */ 1227 1228 const char __cs * 1229 sft9001_prop_name( 1230 __in efx_nic_t *enp, 1231 __in unsigned int id) 1232 { 1233 _NOTE(ARGUNUSED(enp)) 1234 1235 EFSYS_ASSERT3U(id, <, SFT9001_NPROPS); 1236 1237 return (__sft9001_prop_name[id]); 1238 } 1239 #endif /* EFSYS_OPT_NAMES */ 1240 1241 __checkReturn int 1242 sft9001_prop_get( 1243 __in efx_nic_t *enp, 1244 __in unsigned int id, 1245 __in uint32_t flags, 1246 __out uint32_t *valp) 1247 { 1248 uint32_t val; 1249 int rc; 1250 1251 switch (id) { 1252 case SFT9001_SHORT_REACH: { 1253 boolean_t on; 1254 1255 if (flags * EFX_PHY_PROP_DEFAULT) { 1256 val = 0; 1257 break; 1258 } 1259 1260 if ((rc = sft9001_short_reach_get(enp, &on)) != 0) 1261 goto fail1; 1262 1263 val = (on) ? 1 : 0; 1264 break; 1265 } 1266 case SFT9001_ROBUST: { 1267 boolean_t on; 1268 1269 if (flags * EFX_PHY_PROP_DEFAULT) { 1270 val = 0; 1271 break; 1272 } 1273 1274 if ((rc = sft9001_robust_get(enp, &on)) != 0) 1275 goto fail1; 1276 1277 val = (on) ? 1 : 0; 1278 break; 1279 } 1280 default: 1281 EFSYS_ASSERT(B_FALSE); 1282 1283 val = 0; 1284 break; 1285 } 1286 1287 *valp = val; 1288 return (0); 1289 1290 fail1: 1291 EFSYS_PROBE1(fail1, int, rc); 1292 1293 return (rc); 1294 } 1295 1296 __checkReturn int 1297 sft9001_prop_set( 1298 __in efx_nic_t *enp, 1299 __in unsigned int id, 1300 __in uint32_t val) 1301 { 1302 efx_port_t *epp = &(enp->en_port); 1303 int rc; 1304 1305 switch (id) { 1306 case SFT9001_SHORT_REACH: 1307 if ((rc = sft9001_an_set(enp, B_FALSE)) != 0) 1308 goto fail1; 1309 1310 if ((rc = sft9001_short_reach_set(enp, (val != 0))) != 0) 1311 goto fail2; 1312 1313 #if EFSYS_OPT_LOOPBACK 1314 if (epp->ep_loopback_type == EFX_LOOPBACK_OFF) { 1315 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 1316 goto fail3; 1317 } 1318 #else /* EFSYS_OPT_LOOPBACK */ 1319 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 1320 goto fail3; 1321 #endif /* EFSYS_OPT_LOOPBACK */ 1322 1323 break; 1324 1325 case SFT9001_ROBUST: 1326 if ((rc = sft9001_an_set(enp, B_FALSE)) != 0) 1327 goto fail1; 1328 1329 if ((rc = sft9001_robust_set(enp, (val != 0))) != 0) 1330 goto fail2; 1331 1332 #if EFSYS_OPT_LOOPBACK 1333 if (epp->ep_loopback_type == EFX_LOOPBACK_OFF) { 1334 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 1335 goto fail3; 1336 } 1337 #else /* EFSYS_OPT_LOOPBACK */ 1338 if ((rc = sft9001_an_set(enp, B_TRUE)) != 0) 1339 goto fail3; 1340 #endif /* EFSYS_OPT_LOOPBACK */ 1341 1342 break; 1343 1344 default: 1345 EFSYS_ASSERT(B_FALSE); 1346 break; 1347 } 1348 1349 return (0); 1350 1351 fail3: 1352 EFSYS_PROBE(fail3); 1353 fail2: 1354 EFSYS_PROBE(fail2); 1355 fail1: 1356 EFSYS_PROBE1(fail1, int, rc); 1357 1358 return (rc); 1359 } 1360 #endif /* EFSYS_OPT_PHY_PROPS */ 1361 1362 #if EFSYS_OPT_NVRAM_SFT9001 1363 1364 static __checkReturn int 1365 sft9001_ssr( 1366 __in efx_nic_t *enp, 1367 __in boolean_t loader) 1368 { 1369 efx_port_t *epp = &(enp->en_port); 1370 efx_oword_t oword; 1371 efx_word_t word; 1372 int state; 1373 int rc; 1374 1375 EFSYS_LOCK(enp->en_eslp, state); 1376 1377 /* Lock I2C bus and pull GPIO(3) low */ 1378 EFSYS_ASSERT(!enp->en_u.falcon.enu_i2c_locked); 1379 enp->en_u.falcon.enu_i2c_locked = B_TRUE; 1380 1381 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword); 1382 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO3_OEN, loader ? 1 : 0); 1383 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO3_OUT, 0); 1384 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword); 1385 1386 EFSYS_UNLOCK(enp->en_eslp, state); 1387 1388 /* Special software reset */ 1389 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1390 PMA_PMD_XCONTROL_REG, &word)) != 0) 1391 goto fail1; 1392 EFX_SET_WORD_FIELD(word, SSR, 1); 1393 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 1394 PMA_PMD_XCONTROL_REG, &word)) != 0) 1395 goto fail2; 1396 1397 /* Sleep for 500ms */ 1398 EFSYS_SLEEP(500000); 1399 1400 goto out; 1401 1402 fail2: 1403 EFSYS_PROBE(fail2); 1404 fail1: 1405 EFSYS_PROBE1(fail1, int, rc); 1406 1407 out: 1408 /* Unlock the I2C bus and restore GPIO(3) */ 1409 EFSYS_LOCK(enp->en_eslp, state); 1410 enp->en_u.falcon.enu_i2c_locked = B_FALSE; 1411 1412 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword); 1413 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO3_OEN, 0); 1414 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword); 1415 1416 EFSYS_UNLOCK(enp->en_eslp, state); 1417 1418 return (rc); 1419 } 1420 1421 static __checkReturn int 1422 sft9001_loader_wait( 1423 __in efx_nic_t *enp) 1424 { 1425 efx_port_t *epp = &(enp->en_port); 1426 efx_word_t word; 1427 unsigned int count; 1428 unsigned int response; 1429 int rc; 1430 1431 /* Wait up to 20s for the command to complete */ 1432 for (count = 0; count < 200; count++) { 1433 EFSYS_SLEEP(100000); /* 100ms */ 1434 1435 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1436 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1437 goto fail1; 1438 1439 response = EFX_WORD_FIELD(word, EFX_WORD_0); 1440 if (response == LOADER_RESPONSE_OK) 1441 return (0); 1442 if (response != LOADER_RESPONSE_BUSY) { 1443 rc = EIO; 1444 goto fail2; 1445 } 1446 } 1447 1448 rc = ETIMEDOUT; 1449 1450 EFSYS_PROBE(fail3); 1451 fail2: 1452 EFSYS_PROBE(fail2); 1453 fail1: 1454 EFSYS_PROBE1(fail1, int, rc); 1455 1456 return (rc); 1457 } 1458 1459 static __checkReturn int 1460 sft9001_program_loader( 1461 __in efx_nic_t *enp, 1462 __in unsigned int offset, 1463 __in size_t words) 1464 { 1465 efx_port_t *epp = &(enp->en_port); 1466 efx_word_t word; 1467 int rc; 1468 1469 /* Setup address of block transfer */ 1470 EFX_POPULATE_WORD_1(word, EFX_WORD_0, offset); 1471 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1472 LOADER_FLASH_ADDR_LOW_REG, &word)) != 0) 1473 goto fail1; 1474 1475 EFX_POPULATE_WORD_1(word, EFX_WORD_0, (offset >> 16)); 1476 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1477 LOADER_FLASH_ADDR_HI_REG, &word)) != 0) 1478 goto fail2; 1479 1480 EFX_POPULATE_WORD_1(word, EFX_WORD_0, words); 1481 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1482 LOADER_ACTUAL_BUFF_SZ_REG, &word)) != 0) 1483 goto fail3; 1484 1485 return (0); 1486 1487 fail3: 1488 EFSYS_PROBE(fail3); 1489 fail2: 1490 EFSYS_PROBE(fail2); 1491 fail1: 1492 EFSYS_PROBE1(fail1, int, rc); 1493 1494 return (rc); 1495 } 1496 1497 __checkReturn int 1498 sft9001_nvram_size( 1499 __in efx_nic_t *enp, 1500 __out size_t *sizep) 1501 { 1502 _NOTE(ARGUNUSED(enp)) 1503 EFSYS_ASSERT(sizep); 1504 1505 *sizep = FIRMWARE_MAX_SIZE; 1506 1507 return (0); 1508 } 1509 1510 __checkReturn int 1511 sft9001_nvram_get_version( 1512 __in efx_nic_t *enp, 1513 __out uint32_t *subtypep, 1514 __out_ecount(4) uint16_t version[4]) 1515 { 1516 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1517 uint8_t a, b, c, d; 1518 int rc; 1519 1520 if ((rc = sft9001_rev_get(enp, &a, &b, &c, &d)) != 0) 1521 goto fail1; 1522 1523 version[0] = a; 1524 version[1] = b; 1525 version[2] = c; 1526 version[3] = d; 1527 1528 switch (encp->enc_phy_type) { 1529 case EFX_PHY_SFT9001A: 1530 *subtypep = PHY_TYPE_SFT9001A_DECODE; 1531 break; 1532 case EFX_PHY_SFT9001B: 1533 *subtypep = PHY_TYPE_SFT9001B_DECODE; 1534 break; 1535 default: 1536 EFSYS_ASSERT(0); 1537 *subtypep = 0; 1538 } 1539 1540 return (0); 1541 1542 fail1: 1543 EFSYS_PROBE1(fail1, int, rc); 1544 1545 return (0); 1546 } 1547 1548 __checkReturn int 1549 sft9001_nvram_rw_start( 1550 __in efx_nic_t *enp, 1551 __out size_t *block_sizep) 1552 { 1553 efx_port_t *epp = &(enp->en_port); 1554 sft9001_firmware_header_t header; 1555 unsigned int pos; 1556 efx_word_t word; 1557 int rc; 1558 1559 /* Reboot without starting the firmware */ 1560 if ((rc = sft9001_ssr(enp, B_TRUE)) != 0) 1561 goto fail1; 1562 1563 /* Check that the C166 is idle, and in download mode */ 1564 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1565 PCS_BOOT_STATUS_REG, &word)) != 0) 1566 goto fail2; 1567 if (EFX_WORD_FIELD(word, BOOT_STATUS) == 0 || 1568 EFX_WORD_FIELD(word, BOOT_PROGRESS) != MDIO_WAIT_DECODE) { 1569 rc = ETIMEDOUT; 1570 goto fail3; 1571 } 1572 1573 /* Download loader code */ 1574 EFX_ZERO_WORD(word); 1575 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1576 PCS_LM_RAM_LS_ADDR_REG, &word)) != 0) 1577 goto fail4; 1578 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1579 PCS_LM_RAM_MS_ADDR_REG, &word)) != 0) 1580 goto fail5; 1581 for (pos = 0; pos < sft9001_loader_size / sizeof (uint16_t); pos++) { 1582 /* Firmware is little endian */ 1583 word.ew_u8[0] = sft9001_loader[pos]; 1584 word.ew_u8[1] = sft9001_loader[pos+1]; 1585 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1586 PCS_LM_RAM_DATA_REG, &word)) != 0) 1587 goto fail6; 1588 } 1589 1590 /* Sleep for 500ms */ 1591 EFSYS_SLEEP(500000); 1592 1593 /* Start downloaded code */ 1594 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1595 PCS_BOOT_STATUS_REG, &word)) != 0) 1596 goto fail7; 1597 EFX_SET_WORD_FIELD(word, CODE_DOWNLOAD, 1); 1598 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD, 1599 PCS_BOOT_STATUS_REG, &word)) != 0) 1600 goto fail8; 1601 1602 /* Sleep 1s */ 1603 EFSYS_SLEEP(1000000); 1604 1605 /* And check it started */ 1606 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1607 PCS_BOOT_STATUS_REG, &word)) != 0) 1608 goto fail9; 1609 1610 if (EFX_WORD_FIELD(word, CODE_STARTED) == 0) { 1611 rc = ETIMEDOUT; 1612 goto fail10; 1613 } 1614 1615 /* Verify program block size is appropriate */ 1616 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1617 LOADER_MAX_BUFF_SZ_REG, &word)) != 0) 1618 goto fail11; 1619 if (EFX_WORD_FIELD(word, EFX_WORD_0) < FIRMWARE_BLOCK_SIZE) { 1620 rc = EIO; 1621 goto fail12; 1622 } 1623 if (block_sizep != NULL) 1624 *block_sizep = FIRMWARE_BLOCK_SIZE; 1625 1626 /* Read firmware header */ 1627 if ((rc = sft9001_nvram_read_chunk(enp, 0, (void *)&header, 1628 sizeof (header))) != 0) 1629 goto fail13; 1630 1631 /* Verify firmware isn't too large */ 1632 if (EFX_DWORD_FIELD(header.code_length, EFX_DWORD_0) + 1633 sizeof (sft9001_firmware_header_t) > FIRMWARE_MAX_SIZE) { 1634 rc = EIO; 1635 goto fail14; 1636 } 1637 1638 return (0); 1639 1640 fail14: 1641 EFSYS_PROBE(fail14); 1642 fail13: 1643 EFSYS_PROBE(fail13); 1644 fail12: 1645 EFSYS_PROBE(fail12); 1646 fail11: 1647 EFSYS_PROBE(fail11); 1648 fail10: 1649 EFSYS_PROBE(fail10); 1650 fail9: 1651 EFSYS_PROBE(fail9); 1652 fail8: 1653 EFSYS_PROBE(fail8); 1654 fail7: 1655 EFSYS_PROBE(fail7); 1656 fail6: 1657 EFSYS_PROBE(fail6); 1658 fail5: 1659 EFSYS_PROBE(fail5); 1660 fail4: 1661 EFSYS_PROBE(fail4); 1662 fail3: 1663 EFSYS_PROBE(fail3); 1664 fail2: 1665 EFSYS_PROBE(fail2); 1666 fail1: 1667 EFSYS_PROBE1(fail1, int, rc); 1668 1669 /* Reboot the PHY into the main firmware */ 1670 (void) sft9001_ssr(enp, B_FALSE); 1671 1672 /* Sleep for 500ms */ 1673 EFSYS_SLEEP(500000); 1674 1675 return (rc); 1676 } 1677 1678 __checkReturn int 1679 sft9001_nvram_read_chunk( 1680 __in efx_nic_t *enp, 1681 __in unsigned int offset, 1682 __out_bcount(size) caddr_t data, 1683 __in size_t size) 1684 { 1685 efx_port_t *epp = &(enp->en_port); 1686 efx_word_t word; 1687 unsigned int pos; 1688 size_t chunk; 1689 size_t words; 1690 int rc; 1691 1692 while (size > 0) { 1693 chunk = MIN(size, FIRMWARE_BLOCK_SIZE); 1694 1695 /* Read in 2byte words */ 1696 EFSYS_ASSERT(!(chunk & 0x1)); 1697 words = chunk >> 1; 1698 1699 /* Program address/length */ 1700 if ((rc = sft9001_program_loader(enp, offset, words)) != 0) 1701 goto fail1; 1702 1703 /* Select read mode, and wait for buffer to fill */ 1704 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_READ_FLASH); 1705 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1706 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1707 goto fail2; 1708 1709 if ((rc = sft9001_loader_wait(enp)) != 0) 1710 goto fail3; 1711 1712 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1713 LOADER_WORDS_READ_REG, &word)) != 0) 1714 goto fail4; 1715 1716 if (words != (size_t)EFX_WORD_FIELD(word, EFX_WORD_0)) 1717 goto fail5; 1718 1719 for (pos = 0; pos < words; ++pos) { 1720 if ((rc = falcon_mdio_read(enp, epp->ep_port, 1721 LOADER_MMD, LOADER_DATA_REG, &word)) != 0) 1722 goto fail6; 1723 1724 /* Firmware is little endian */ 1725 data[pos] = word.ew_u8[0]; 1726 data[pos+1] = word.ew_u8[1]; 1727 } 1728 1729 size -= chunk; 1730 offset += chunk; 1731 data += chunk; 1732 } 1733 1734 return (0); 1735 1736 fail6: 1737 EFSYS_PROBE(fail6); 1738 fail5: 1739 EFSYS_PROBE(fail5); 1740 fail4: 1741 EFSYS_PROBE(fail4); 1742 fail3: 1743 EFSYS_PROBE(fail3); 1744 fail2: 1745 EFSYS_PROBE(fail2); 1746 fail1: 1747 EFSYS_PROBE1(fail1, int, rc); 1748 1749 return (rc); 1750 } 1751 1752 __checkReturn int 1753 sft9001_nvram_erase( 1754 __in efx_nic_t *enp) 1755 { 1756 efx_port_t *epp = &(enp->en_port); 1757 efx_word_t word; 1758 int rc; 1759 1760 EFX_POPULATE_WORD_1(word, EFX_BYTE_0, LOADER_CMD_ERASE_FLASH); 1761 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1762 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0) 1763 goto fail1; 1764 1765 if ((rc = sft9001_loader_wait(enp)) != 0) 1766 goto fail2; 1767 1768 return (0); 1769 1770 fail2: 1771 EFSYS_PROBE(fail2); 1772 fail1: 1773 EFSYS_PROBE1(fail1, int, rc); 1774 1775 return (rc); 1776 } 1777 1778 __checkReturn int 1779 sft9001_nvram_write_chunk( 1780 __in efx_nic_t *enp, 1781 __in unsigned int offset, 1782 __in_bcount(size) caddr_t data, 1783 __in size_t size) 1784 { 1785 efx_port_t *epp = &(enp->en_port); 1786 efx_word_t word; 1787 unsigned int pos; 1788 size_t chunk; 1789 size_t words; 1790 int rc; 1791 1792 while (size > 0) { 1793 chunk = MIN(size, FIRMWARE_BLOCK_SIZE); 1794 1795 /* Write in 2byte words */ 1796 EFSYS_ASSERT(!(chunk & 0x1)); 1797 words = chunk >> 1; 1798 1799 /* Program address/length */ 1800 if ((rc = sft9001_program_loader(enp, offset, words)) != 0) 1801 goto fail1; 1802 1803 /* Select write mode */ 1804 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_FILL_BUFFER); 1805 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD, 1806 LOADER_CMD_RESPONSE_REG, &word)) != 0) 1807 goto fail2; 1808 1809 for (pos = 0; pos < words; ++pos) { 1810 /* Firmware is little-endian */ 1811 word.ew_u8[0] = data[pos]; 1812 word.ew_u8[1] = data[pos+1]; 1813 1814 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1815 LOADER_MMD, LOADER_DATA_REG, &word)) != 0) 1816 goto fail3; 1817 } 1818 1819 EFX_POPULATE_WORD_1(word, EFX_WORD_0, 1820 LOADER_CMD_PROGRAM_FLASH); 1821 if ((rc = falcon_mdio_write(enp, epp->ep_port, 1822 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0) 1823 goto fail4; 1824 1825 if ((rc = sft9001_loader_wait(enp)) != 0) 1826 goto fail5; 1827 1828 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD, 1829 LOADER_WORDS_WRITTEN_REG, &word)) != 0) 1830 goto fail6; 1831 1832 if (words != EFX_WORD_FIELD(word, EFX_WORD_0)) 1833 goto fail7; 1834 1835 size -= chunk; 1836 offset += chunk; 1837 data += chunk; 1838 } 1839 1840 return (0); 1841 1842 fail7: 1843 EFSYS_PROBE(fail7); 1844 fail6: 1845 EFSYS_PROBE(fail6); 1846 fail5: 1847 EFSYS_PROBE(fail5); 1848 fail4: 1849 EFSYS_PROBE(fail4); 1850 fail3: 1851 EFSYS_PROBE(fail3); 1852 fail2: 1853 EFSYS_PROBE(fail2); 1854 fail1: 1855 EFSYS_PROBE1(fail1, int, rc); 1856 1857 return (rc); 1858 } 1859 1860 void 1861 sft9001_nvram_rw_finish( 1862 __in efx_nic_t *enp) 1863 { 1864 efx_port_t *epp = &(enp->en_port); 1865 efx_word_t word; 1866 int rc; 1867 1868 /* Reboot the PHY into the main firmware */ 1869 if ((rc = sft9001_ssr(enp, B_FALSE)) != 0) 1870 goto fail1; 1871 1872 /* Sleep for 500ms */ 1873 EFSYS_SLEEP(500000); 1874 1875 /* Verify that PHY rebooted */ 1876 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD, 1877 PCS_BOOT_STATUS_REG, &word)) != 0) 1878 goto fail2; 1879 if (EFX_WORD_FIELD(word, EFX_WORD_0) != 0x7E) 1880 goto fail3; 1881 1882 return; 1883 1884 fail3: 1885 EFSYS_PROBE(fail3); 1886 fail2: 1887 EFSYS_PROBE(fail2); 1888 fail1: 1889 EFSYS_PROBE1(fail1, int, rc); 1890 } 1891 1892 #endif /* EFSYS_OPT_NVRAM_SFT9001 */ 1893 1894 #if EFSYS_OPT_PHY_BIST 1895 1896 __checkReturn int 1897 sft9001_bist_start( 1898 __in efx_nic_t *enp, 1899 __in efx_phy_bist_type_t type) 1900 { 1901 efx_port_t *epp = &(enp->en_port); 1902 boolean_t break_link = (type == EFX_PHY_BIST_TYPE_CABLE_LONG); 1903 efx_word_t word; 1904 int rc; 1905 1906 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1907 PMA_PMD_DIAG_CONTROL_REG, &word)) != 0) 1908 goto fail1; 1909 1910 if (EFX_WORD_FIELD(word, DIAG_RUNNING) != 0) { 1911 rc = EBUSY; 1912 goto fail2; 1913 } 1914 1915 EFX_POPULATE_WORD_3(word, 1916 RUN_DIAG_IMMED, 1, 1917 LENGTH_UNIT, LENGTH_M_DECODE, 1918 BREAK_LINK, break_link ? 1 : 0); 1919 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD, 1920 PMA_PMD_DIAG_CONTROL_REG, &word)) != 0) 1921 goto fail3; 1922 1923 return (0); 1924 1925 fail3: 1926 EFSYS_PROBE(fail3); 1927 fail2: 1928 EFSYS_PROBE(fail2); 1929 fail1: 1930 EFSYS_PROBE1(fail1, int, rc); 1931 1932 return (rc); 1933 } 1934 1935 static efx_phy_cable_status_t 1936 sft9001_bist_status( 1937 __in uint16_t code) 1938 { 1939 switch (code) { 1940 case PAIR_BUSY_DECODE: 1941 return (EFX_PHY_CABLE_STATUS_BUSY); 1942 case INTER_PAIR_SHORT_DECODE: 1943 return (EFX_PHY_CABLE_STATUS_INTERPAIRSHORT); 1944 case INTRA_PAIR_SHORT_DECODE: 1945 return (EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT); 1946 case PAIR_OPEN_DECODE: 1947 return (EFX_PHY_CABLE_STATUS_OPEN); 1948 case PAIR_OK_DECODE: 1949 return (EFX_PHY_CABLE_STATUS_OK); 1950 default: 1951 return (EFX_PHY_CABLE_STATUS_INVALID); 1952 } 1953 } 1954 1955 __checkReturn int 1956 sft9001_bist_poll( 1957 __in efx_nic_t *enp, 1958 __in efx_phy_bist_type_t type, 1959 __out efx_phy_bist_result_t *resultp, 1960 __out_opt uint32_t *value_maskp, 1961 __out_ecount_opt(count) unsigned long *valuesp, 1962 __in size_t count) 1963 { 1964 efx_port_t *epp = &(enp->en_port); 1965 uint32_t value_mask = 0; 1966 efx_word_t word; 1967 int rc; 1968 1969 _NOTE(ARGUNUSED(type)) 1970 1971 *resultp = EFX_PHY_BIST_RESULT_UNKNOWN; 1972 1973 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1974 PMA_PMD_DIAG_CONTROL_REG, &word)) != 0) 1975 goto fail1; 1976 1977 if (EFX_WORD_FIELD(word, DIAG_RUNNING)) { 1978 *resultp = EFX_PHY_BIST_RESULT_RUNNING; 1979 return (0); 1980 } 1981 1982 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 1983 PMA_PMD_DIAG_RESULT_REG, &word)) != 0) 1984 goto fail2; 1985 1986 *resultp = EFX_PHY_BIST_RESULT_PASSED; 1987 1988 if (count > EFX_PHY_BIST_CABLE_STATUS_A) { 1989 valuesp[EFX_PHY_BIST_CABLE_STATUS_A] = 1990 sft9001_bist_status(EFX_WORD_FIELD(word, PAIR_A_CODE)); 1991 value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_A); 1992 } 1993 if (count > EFX_PHY_BIST_CABLE_STATUS_B) { 1994 valuesp[EFX_PHY_BIST_CABLE_STATUS_B] = 1995 sft9001_bist_status(EFX_WORD_FIELD(word, PAIR_B_CODE)); 1996 value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_B); 1997 } 1998 if (count > EFX_PHY_BIST_CABLE_STATUS_C) { 1999 valuesp[EFX_PHY_BIST_CABLE_STATUS_C] = 2000 sft9001_bist_status(EFX_WORD_FIELD(word, PAIR_C_CODE)); 2001 value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_C); 2002 } 2003 if (count > EFX_PHY_BIST_CABLE_STATUS_D) { 2004 valuesp[EFX_PHY_BIST_CABLE_STATUS_D] = 2005 sft9001_bist_status(EFX_WORD_FIELD(word, PAIR_D_CODE)); 2006 value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_D); 2007 } 2008 2009 if (count > EFX_PHY_BIST_CABLE_LENGTH_A) { 2010 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 2011 PMA_PMD_DIAG_A_LENGTH_REG, &word)) != 0) 2012 goto fail3; 2013 valuesp[EFX_PHY_BIST_CABLE_LENGTH_A] = 2014 EFX_WORD_FIELD(word, EFX_WORD_0); 2015 value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_A); 2016 } 2017 if (count > EFX_PHY_BIST_CABLE_LENGTH_B) { 2018 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 2019 PMA_PMD_DIAG_B_LENGTH_REG, &word)) != 0) 2020 goto fail4; 2021 valuesp[EFX_PHY_BIST_CABLE_LENGTH_B] = 2022 EFX_WORD_FIELD(word, EFX_WORD_0); 2023 value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_B); 2024 } 2025 if (count > EFX_PHY_BIST_CABLE_LENGTH_C) { 2026 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 2027 PMA_PMD_DIAG_C_LENGTH_REG, &word)) != 0) 2028 goto fail5; 2029 valuesp[EFX_PHY_BIST_CABLE_LENGTH_C] = 2030 EFX_WORD_FIELD(word, EFX_WORD_0); 2031 value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_C); 2032 } 2033 if (count > EFX_PHY_BIST_CABLE_LENGTH_D) { 2034 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD, 2035 PMA_PMD_DIAG_D_LENGTH_REG, &word)) != 0) 2036 goto fail6; 2037 valuesp[EFX_PHY_BIST_CABLE_LENGTH_D] = 2038 EFX_WORD_FIELD(word, EFX_WORD_0); 2039 value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_D); 2040 } 2041 2042 if (value_maskp != NULL) 2043 *value_maskp = value_mask; 2044 2045 return (0); 2046 2047 fail6: 2048 EFSYS_PROBE(fail6); 2049 fail5: 2050 EFSYS_PROBE(fail5); 2051 fail4: 2052 EFSYS_PROBE(fail4); 2053 fail3: 2054 EFSYS_PROBE(fail3); 2055 fail2: 2056 EFSYS_PROBE(fail2); 2057 fail1: 2058 EFSYS_PROBE1(fail1, int, rc); 2059 2060 return (rc); 2061 } 2062 2063 void 2064 sft9001_bist_stop( 2065 __in efx_nic_t *enp, 2066 __in efx_phy_bist_type_t type) 2067 { 2068 boolean_t break_link = (type == EFX_PHY_BIST_TYPE_CABLE_LONG); 2069 2070 if (break_link) { 2071 /* Pull external reset and reconfigure the PHY */ 2072 falcon_nic_phy_reset(enp); 2073 2074 EFSYS_ASSERT3U(enp->en_reset_flags, &, EFX_RESET_PHY); 2075 enp->en_reset_flags &= ~EFX_RESET_PHY; 2076 2077 (void) sft9001_reconfigure(enp); 2078 } 2079 } 2080 2081 #endif /* EFSYS_OPT_PHY_BIST */ 2082 2083 #endif /* EFSYS_OPT_PHY_SFT9001 */