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, &micro)) != 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, &micro)) != 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 */