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 */