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 "falcon_nvram.h"
  29 #include "efx_types.h"
  30 #include "efx_regs.h"
  31 #include "efx_regs_pci.h"
  32 #include "efx_impl.h"
  33 
  34 #if EFSYS_OPT_FALCON
  35 
  36 #if EFSYS_OPT_MAC_FALCON_XMAC
  37 #include "falcon_xmac.h"
  38 #endif
  39 
  40 #if EFSYS_OPT_MAC_FALCON_GMAC
  41 #include "falcon_gmac.h"
  42 #endif
  43 
  44 #if EFSYS_OPT_MON_LM87
  45 #include "lm87.h"
  46 #endif
  47 
  48 #if EFSYS_OPT_MON_MAX6647
  49 #include "max6647.h"
  50 #endif
  51 
  52 #if EFSYS_OPT_PHY_NULL
  53 #include "nullphy.h"
  54 #endif
  55 
  56 #if EFSYS_OPT_PHY_QT2022C2
  57 #include "qt2022c2.h"
  58 #endif
  59 
  60 #if EFSYS_OPT_PHY_SFX7101
  61 #include "sfx7101.h"
  62 #endif
  63 
  64 #if EFSYS_OPT_PHY_TXC43128
  65 #include "txc43128.h"
  66 #endif
  67 
  68 #if EFSYS_OPT_PHY_SFT9001
  69 #include "sft9001.h"
  70 #endif
  71 
  72 #if EFSYS_OPT_PHY_QT2025C
  73 #include "qt2025c.h"
  74 #endif
  75 
  76 static  __checkReturn           int
  77 falcon_nic_cfg_raw_read(
  78         __in                    efx_nic_t *enp,
  79         __in                    uint32_t offset,
  80         __in                    uint32_t size,
  81         __out                   void *cfg)
  82 {
  83         EFSYS_ASSERT3U(offset + size, <=, FALCON_NIC_CFG_RAW_SZ);
  84 
  85 #if EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
  86         if (enp->en_u.falcon.enu_forced_cfg != NULL) {
  87                 memcpy(cfg, enp->en_u.falcon.enu_forced_cfg + offset, size);
  88                 return (0);
  89         }
  90 #endif  /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */
  91 
  92         return falcon_spi_dev_read(enp, FALCON_SPI_FLASH, offset,
  93                     (caddr_t)cfg, size);
  94 }
  95 
  96         __checkReturn           int
  97 falcon_nic_cfg_raw_read_verify(
  98         __in                    efx_nic_t *enp,
  99         __in                    uint32_t offset,
 100         __in                    uint32_t size,
 101         __out                   uint8_t *cfg)
 102 {
 103         uint32_t csum_offset;
 104         uint16_t magic, version, cksum;
 105         int rc;
 106         efx_word_t word;
 107 
 108         if ((rc = falcon_nic_cfg_raw_read(enp, CFG_MAGIC_REG_SF_OFST,
 109                     sizeof (word), &word)) != 0)
 110                 goto fail1;
 111 
 112         magic = EFX_WORD_FIELD(word, MAGIC);
 113 
 114         if ((rc = falcon_nic_cfg_raw_read(enp, CFG_VERSION_REG_SF_OFST,
 115                     sizeof (word), &word)) != 0)
 116                 goto fail2;
 117 
 118         version = EFX_WORD_FIELD(word, VERSION);
 119 
 120         cksum = 0;
 121         for (csum_offset = (version < 4) ? CFG_MAGIC_REG_SF_OFST : 0;
 122             csum_offset < FALCON_NIC_CFG_RAW_SZ;
 123             csum_offset += sizeof (efx_word_t)) {
 124 
 125                 if ((rc = falcon_nic_cfg_raw_read(enp, csum_offset,
 126                             sizeof (word), &word)) != 0)
 127                         goto fail3;
 128 
 129                 cksum += EFX_WORD_FIELD(word, EFX_WORD_0);
 130         }
 131         if (magic != MAGIC_DECODE || version < 2 || cksum != 0xffff) {
 132                 rc = EINVAL;
 133                 goto fail4;
 134         }
 135 
 136         if ((rc = falcon_nic_cfg_raw_read(enp, offset, size, cfg)) != 0)
 137                 goto fail5;
 138 
 139         return (0);
 140 
 141 fail5:
 142         EFSYS_PROBE(fail5);
 143 fail4:
 144         EFSYS_PROBE(fail4);
 145 fail3:
 146         EFSYS_PROBE(fail3);
 147 fail2:
 148         EFSYS_PROBE(fail2);
 149 fail1:
 150         EFSYS_PROBE1(fail1, int, rc);
 151 
 152         return (rc);
 153 }
 154 
 155         __checkReturn   int
 156 falcon_nic_probe(
 157         __in            efx_nic_t *enp)
 158 {
 159         efx_port_t *epp = &(enp->en_port);
 160         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 161         int rc;
 162 
 163         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 164 
 165         /* Initialise the nvram */
 166         if ((rc = falcon_nvram_init(enp)) != 0)
 167                 goto fail1;
 168 
 169         /* Probe the board configuration */
 170         if ((rc = falcon_nic_cfg_build(enp, encp)) != 0)
 171                 goto fail2;
 172         epp->ep_adv_cap_mask = epp->ep_default_adv_cap_mask;
 173 
 174         return (0);
 175 
 176 fail2:
 177         EFSYS_PROBE(fail2);
 178 fail1:
 179         EFSYS_PROBE1(fail1, int, rc);
 180 
 181         return (rc);
 182 }
 183 
 184 #define FALCON_NIC_CFG_BUILD_LOWEST_REG                         \
 185         MIN(CFG_BOARD_REV_REG_SF_OFST,                          \
 186             MIN(CFG_BOARD_TYPE_REG_SF_OFST,                     \
 187                 MIN(CFG_PHY_PORT_REG_SF_OFST,                   \
 188                     MIN(CFG_PHY_TYPE_REG_SF_OFST,               \
 189                         MIN(MAC_ADDRESS_SF_OFST,                \
 190                             MIN(NIC_STAT_SF_OFST,               \
 191                                 SRAM_CFG_SF_OFST))))))
 192 
 193 
 194 #define FALCON_NIC_CFG_BUILD_HIGHEST_REG                        \
 195         MAX(CFG_BOARD_REV_REG_SF_OFST + 1,                      \
 196             MAX(CFG_BOARD_TYPE_REG_SF_OFST + 1,                 \
 197                 MAX(CFG_PHY_PORT_REG_SF_OFST + 1,               \
 198                     MAX(CFG_PHY_TYPE_REG_SF_OFST + 1,           \
 199                         MAX(MAC_ADDRESS_SF_OFST + 6,            \
 200                             MAX(NIC_STAT_SF_OFST + 16,          \
 201                                 SRAM_CFG_SF_OFST + 16))))))
 202 
 203 #define FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE            \
 204         (FALCON_NIC_CFG_BUILD_HIGHEST_REG -             \
 205             FALCON_NIC_CFG_BUILD_LOWEST_REG)
 206 
 207         __checkReturn   int
 208 falcon_nic_cfg_build(
 209         __in            efx_nic_t *enp,
 210         __out           efx_nic_cfg_t *encp)
 211 {
 212         efx_port_t *epp = &(enp->en_port);
 213         uint8_t cfg[FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE];
 214         uint8_t *origin = cfg - FALCON_NIC_CFG_BUILD_LOWEST_REG;
 215         efx_oword_t *owordp;
 216         uint8_t major;
 217         uint8_t minor;
 218         int rc;
 219 
 220         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 221 
 222         (void) memset(encp, 0, sizeof (efx_nic_cfg_t));
 223 
 224         if ((rc = falcon_nic_cfg_raw_read_verify(enp,
 225             FALCON_NIC_CFG_BUILD_LOWEST_REG,
 226             FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE, cfg)) != 0)
 227                 goto fail1;
 228 
 229         encp->enc_board_type = EFX_BYTE_FIELD(
 230                 ((efx_byte_t *)origin)[CFG_BOARD_TYPE_REG_SF_OFST],
 231                 EFX_BYTE_0);
 232 
 233         /* Read board revision */
 234         major = EFX_BYTE_FIELD(
 235             ((efx_byte_t *)origin)[CFG_BOARD_REV_REG_SF_OFST],
 236             BOARD_REV_MAJOR);
 237         minor = EFX_BYTE_FIELD(
 238             ((efx_byte_t *)origin)[CFG_BOARD_REV_REG_SF_OFST],
 239             BOARD_REV_MINOR);
 240         enp->en_u.falcon.enu_board_rev = (major << 4) | minor;
 241 
 242         /* Sram mode */
 243         owordp = (efx_oword_t *)(origin + NIC_STAT_SF_OFST);
 244         enp->en_u.falcon.enu_internal_sram =
 245             EFX_OWORD_FIELD(*owordp, FRF_AB_ONCHIP_SRAM) != 0;
 246         if (enp->en_u.falcon.enu_internal_sram) {
 247                 enp->en_u.falcon.enu_sram_num_bank = 0;
 248                 enp->en_u.falcon.enu_sram_bank_size = 0;
 249 
 250                 /* Resource limits */
 251                 encp->enc_evq_limit = 64;    /* Interrupt-capable */
 252                 encp->enc_txq_limit = 512;
 253                 encp->enc_rxq_limit = 384;
 254                 encp->enc_buftbl_limit = 4096;
 255         } else {
 256                 uint32_t sram_rows;
 257 
 258                 owordp = (efx_oword_t *)(origin + SRAM_CFG_SF_OFST);
 259                 enp->en_u.falcon.enu_sram_num_bank =
 260                     (uint8_t)EFX_OWORD_FIELD(*owordp, FRF_AZ_SRM_NUM_BANK);
 261                 enp->en_u.falcon.enu_sram_bank_size =
 262                     (uint8_t)EFX_OWORD_FIELD(*owordp, FRF_AZ_SRM_BANK_SIZE);
 263                 sram_rows = (enp->en_u.falcon.enu_sram_num_bank + 1)
 264                     << (18 + enp->en_u.falcon.enu_sram_bank_size);
 265 
 266                 /* Resource limits */
 267                 encp->enc_evq_limit = 64;    /* Interrupt-capable */
 268                 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
 269                 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
 270                 encp->enc_buftbl_limit = sram_rows -
 271                     (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE) +
 272                     encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
 273         }
 274 
 275         encp->enc_clk_mult = 1;
 276         encp->enc_evq_timer_quantum_ns =
 277                 EFX_EVQ_FALCON_TIMER_QUANTUM_NS / encp->enc_clk_mult;
 278         encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
 279                 FRF_AB_TIMER_VAL_WIDTH) / 1000;
 280 
 281         /* Determine system monitor configuration */
 282         switch (encp->enc_board_type) {
 283 #if EFSYS_OPT_MON_LM87
 284         case BOARD_TYPE_SFE4002_DECODE:
 285         case BOARD_TYPE_SFE4003_DECODE:
 286         case BOARD_TYPE_SFE4005_DECODE:
 287         case BOARD_TYPE_SFN4112F_DECODE:
 288                 encp->enc_mon_type = EFX_MON_LM87;
 289                 enp->en_u.falcon.enu_mon_devid = LM87_DEVID;
 290 #if EFSYS_OPT_MON_STATS
 291                 encp->enc_mon_stat_mask = LM87_STAT_MASK;
 292 #endif
 293                 break;
 294 #endif  /* EFSYS_OPT_MON_LM87 */
 295 
 296 #if EFSYS_OPT_MON_MAX6647
 297         case BOARD_TYPE_SFE4001_DECODE:
 298                 encp->enc_mon_type = EFX_MON_MAX6647;
 299                 enp->en_u.falcon.enu_mon_devid = MAX6647_DEVID;
 300 #if EFSYS_OPT_MON_STATS
 301                 encp->enc_mon_stat_mask = MAX6647_STAT_MASK;
 302 #endif
 303                 break;
 304 #endif  /* EFSYS_OPT_MON_MAX6647 */
 305 
 306 #if EFSYS_OPT_MON_MAX6647
 307         case BOARD_TYPE_SFN4111T_DECODE:
 308                 encp->enc_mon_type = EFX_MON_MAX6647;
 309 #if EFSYS_OPT_MON_STATS
 310                 encp->enc_mon_stat_mask = MAX6647_STAT_MASK;
 311 #endif
 312                 /*
 313                  * MAX6646 chips are identical to MAX6647 chips in every way
 314                  * that matters to the driver so we pretend that the chip
 315                  * is always a MAX6647, but adjust the identifier accordingly
 316                  */
 317                 enp->en_u.falcon.enu_mon_devid = (major == 0 && minor < 5) ?
 318                     MAX6647_DEVID : MAX6646_DEVID;
 319                 break;
 320 #endif  /* EFSYS_OPT_MON_MAX6647 */
 321 
 322         default:
 323                 encp->enc_mon_type = EFX_MON_NULL;
 324                 enp->en_u.falcon.enu_mon_devid = 0;
 325 #if EFSYS_OPT_MON_STATS
 326                 encp->enc_mon_stat_mask = 0;
 327 #endif
 328                 break;
 329         }
 330 
 331         /* Copy the feature flags */
 332         encp->enc_features = enp->en_features;
 333 
 334         /* Read PHY MII prt and type, and mac address */
 335         encp->enc_port = EFX_BYTE_FIELD(
 336                 ((efx_byte_t *)origin)[CFG_PHY_PORT_REG_SF_OFST], EFX_BYTE_0);
 337         encp->enc_phy_type = EFX_BYTE_FIELD(
 338                 ((efx_byte_t *)origin)[CFG_PHY_TYPE_REG_SF_OFST], EFX_BYTE_0);
 339 
 340         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, origin + MAC_ADDRESS_SF_OFST);
 341 
 342         /* Populate phy capabalities */
 343         EFX_STATIC_ASSERT(EFX_PHY_NULL == PHY_TYPE_NONE_DECODE);
 344         EFX_STATIC_ASSERT(EFX_PHY_TXC43128 == PHY_TYPE_TXC43128_DECODE);
 345         EFX_STATIC_ASSERT(EFX_PHY_SFX7101 == PHY_TYPE_SFX7101_DECODE);
 346         EFX_STATIC_ASSERT(EFX_PHY_QT2022C2 == PHY_TYPE_QT2022C2_DECODE);
 347         EFX_STATIC_ASSERT(EFX_PHY_SFT9001A == PHY_TYPE_SFT9001A_DECODE);
 348         EFX_STATIC_ASSERT(EFX_PHY_QT2025C == PHY_TYPE_QT2025C_DECODE);
 349         EFX_STATIC_ASSERT(EFX_PHY_SFT9001B == PHY_TYPE_SFT9001B_DECODE);
 350 
 351         switch (encp->enc_phy_type) {
 352 #if EFSYS_OPT_PHY_NULL
 353         case PHY_TYPE_NONE_DECODE:
 354                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_XAUI;
 355                 epp->ep_default_adv_cap_mask = NULLPHY_ADV_CAP_MASK;
 356                 epp->ep_phy_cap_mask =
 357                         NULLPHY_ADV_CAP_MASK | NULLPHY_ADV_CAP_PERM;
 358 #if EFSYS_OPT_NAMES
 359                 (void) strncpy(encp->enc_phy_name, "nullphy",
 360                     sizeof (encp->enc_phy_name));
 361 #endif  /* EFSYS_OPT_NAMES */
 362 #if EFSYS_OPT_PHY_LED_CONTROL
 363                 encp->enc_led_mask = NULLPHY_LED_MASK;
 364 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 365 #if EFSYS_OPT_LOOPBACK
 366                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 367                     NULLPHY_LOOPBACK_MASK;
 368 #endif  /* EFSYS_OPT_LOOPBACK */
 369 #if EFSYS_OPT_PHY_STATS
 370                 encp->enc_phy_stat_mask = NULLPHY_STAT_MASK;
 371 #endif  /* EFSYS_OPT_PHY_STATS */
 372 #if EFSYS_OPT_PHY_PROPS
 373                 encp->enc_phy_nprops = NULLPHY_NPROPS;
 374 #endif  /* EFSYS_OPT_PHY_PROPS */
 375 #if EFSYS_OPT_PHY_BIST
 376                 encp->enc_bist_mask = NULLPHY_BIST_MASK;
 377 #endif  /* EFSYS_OPT_PHY_BIST */
 378                 break;
 379 #endif  /* EFSYS_OPT_PHY_NULL */
 380 
 381 #if EFSYS_OPT_PHY_QT2022C2
 382         case PHY_TYPE_QT2022C2_DECODE:
 383                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_XFP;
 384                 epp->ep_default_adv_cap_mask = QT2022C2_ADV_CAP_MASK;
 385                 epp->ep_phy_cap_mask =
 386                         QT2022C2_ADV_CAP_MASK | QT2022C2_ADV_CAP_PERM;
 387 #if EFSYS_OPT_NAMES
 388                 (void) strncpy(encp->enc_phy_name, "qt2022c2",
 389                     sizeof (encp->enc_phy_name));
 390 #endif  /* EFSYS_OPT_NAMES */
 391 #if EFSYS_OPT_PHY_LED_CONTROL
 392                 encp->enc_led_mask = QT2022C2_LED_MASK;
 393 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 394 #if EFSYS_OPT_LOOPBACK
 395                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 396                     QT2022C2_LOOPBACK_MASK;
 397 #endif  /* EFSYS_OPT_LOOPBACK */
 398 #if EFSYS_OPT_PHY_STATS
 399                 encp->enc_phy_stat_mask = QT2022C2_STAT_MASK;
 400 #endif  /* EFSYS_OPT_PHY_STATS */
 401 #if EFSYS_OPT_PHY_PROPS
 402                 encp->enc_phy_nprops = QT2022C2_NPROPS;
 403 #endif  /* EFSYS_OPT_PHY_PROPS */
 404 #if EFSYS_OPT_PHY_BIST
 405                 encp->enc_bist_mask = QT2022C2_BIST_MASK;
 406 #endif  /* EFSYS_OPT_PHY_BIST */
 407                 break;
 408 #endif  /* EFSYS_OPT_PHY_QT2022C2 */
 409 
 410 #if EFSYS_OPT_PHY_SFX7101
 411         case PHY_TYPE_SFX7101_DECODE:
 412                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_BASE_T;
 413                 epp->ep_default_adv_cap_mask = SFX7101_ADV_CAP_MASK;
 414                 epp->ep_phy_cap_mask =
 415                         SFX7101_ADV_CAP_MASK | SFX7101_ADV_CAP_PERM;
 416 #if EFSYS_OPT_NAMES
 417                 (void) strncpy(encp->enc_phy_name, "sfx7101",
 418                     sizeof (encp->enc_phy_name));
 419 #endif  /* EFSYS_OPT_NAMES */
 420 #if EFSYS_OPT_PHY_LED_CONTROL
 421                 encp->enc_led_mask = SFX7101_LED_MASK;
 422 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 423 #if EFSYS_OPT_LOOPBACK
 424                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 425                     SFX7101_LOOPBACK_MASK;
 426 #endif  /* EFSYS_OPT_LOOPBACK */
 427 #if EFSYS_OPT_PHY_STATS
 428                 encp->enc_phy_stat_mask = SFX7101_STAT_MASK;
 429 #endif  /* EFSYS_OPT_PHY_STATS */
 430 #if EFSYS_OPT_PHY_PROPS
 431                 encp->enc_phy_nprops = SFX7101_NPROPS;
 432 #endif  /* EFSYS_OPT_PHY_PROPS */
 433 #if EFSYS_OPT_PHY_BIST
 434                 encp->enc_bist_mask = SFX7101_BIST_MASK;
 435 #endif  /* EFSYS_OPT_PHY_BIST */
 436                 break;
 437 #endif  /* EFSYS_OPT_PHY_SFX7101 */
 438 
 439 #if EFSYS_OPT_PHY_TXC43128
 440         case PHY_TYPE_TXC43128_DECODE:
 441                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_CX4;
 442                 epp->ep_default_adv_cap_mask = TXC43128_ADV_CAP_MASK;
 443                 epp->ep_phy_cap_mask =
 444                         TXC43128_ADV_CAP_MASK | TXC43128_ADV_CAP_PERM;
 445 #if EFSYS_OPT_NAMES
 446                 (void) strncpy(encp->enc_phy_name, "txc43128",
 447                     sizeof (encp->enc_phy_name));
 448 #endif  /* EFSYS_OPT_NAMES */
 449 #if EFSYS_OPT_PHY_LED_CONTROL
 450                 encp->enc_led_mask = TXC43128_LED_MASK;
 451 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 452 #if EFSYS_OPT_LOOPBACK
 453                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 454                     TXC43128_LOOPBACK_MASK;
 455 #endif  /* EFSYS_OPT_LOOPBACK */
 456 #if EFSYS_OPT_PHY_STATS
 457                 encp->enc_phy_stat_mask = TXC43128_STAT_MASK;
 458 #endif  /* EFSYS_OPT_PHY_STATS */
 459 #if EFSYS_OPT_PHY_PROPS
 460                 encp->enc_phy_nprops = TXC43128_NPROPS;
 461 #endif  /* EFSYS_OPT_PHY_PROPS */
 462 #if EFSYS_OPT_PHY_BIST
 463                 encp->enc_bist_mask = TXC43128_BIST_MASK;
 464 #endif  /* EFSYS_OPT_PHY_BIST */
 465                 break;
 466 #endif  /* EFSYS_OPT_PHY_TXC43128 */
 467 
 468 #if EFSYS_OPT_PHY_SFT9001
 469         case PHY_TYPE_SFT9001A_DECODE:
 470         case PHY_TYPE_SFT9001B_DECODE:
 471                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_BASE_T;
 472                 epp->ep_default_adv_cap_mask = SFT9001_ADV_CAP_MASK;
 473                 epp->ep_phy_cap_mask =
 474                         SFT9001_ADV_CAP_MASK | SFT9001_ADV_CAP_PERM;
 475 #if EFSYS_OPT_NAMES
 476                 (void) strncpy(encp->enc_phy_name, "sft9001",
 477                     sizeof (encp->enc_phy_name));
 478 #endif  /* EFSYS_OPT_NAMES */
 479 #if EFSYS_OPT_PHY_LED_CONTROL
 480                 encp->enc_led_mask = SFT9001_LED_MASK;
 481 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 482 #if EFSYS_OPT_LOOPBACK
 483                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 484                     SFT9001_10G_LOOPBACK_MASK;
 485                 encp->enc_loopback_types[EFX_LINK_1000FDX] =
 486                     SFT9001_1G_LOOPBACK_MASK;
 487 #endif  /* EFSYS_OPT_LOOPBACK */
 488 #if EFSYS_OPT_PHY_STATS
 489                 encp->enc_phy_stat_mask = SFT9001_STAT_MASK;
 490 #endif  /* EFSYS_OPT_PHY_STATS */
 491 #if EFSYS_OPT_PHY_PROPS
 492                 encp->enc_phy_nprops = SFT9001_NPROPS;
 493 #endif  /* EFSYS_OPT_PHY_PROPS */
 494 #if EFSYS_OPT_PHY_BIST
 495                 encp->enc_bist_mask = SFT9001_BIST_MASK;
 496 #endif  /* EFSYS_OPT_PHY_BIST */
 497                 break;
 498 #endif  /* EFSYS_OPT_PHY_SFT9001 */
 499 
 500 #if EFSYS_OPT_PHY_QT2025C
 501         case EFX_PHY_QT2025C:
 502                 epp->ep_fixed_port_type = EFX_PHY_MEDIA_SFP_PLUS;
 503                 epp->ep_default_adv_cap_mask = QT2025C_ADV_CAP_MASK;
 504                 epp->ep_phy_cap_mask =
 505                         QT2025C_ADV_CAP_MASK | QT2025C_ADV_CAP_PERM;
 506 #if EFSYS_OPT_NAMES
 507                 (void) strncpy(encp->enc_phy_name, "qt2025c",
 508                     sizeof (encp->enc_phy_name));
 509 #endif  /* EFSYS_OPT_NAMES */
 510 #if EFSYS_OPT_PHY_LED_CONTROL
 511                 encp->enc_led_mask = QT2025C_LED_MASK;
 512 #endif  /* EFSYS_OPT_PHY_LED_CONTROL */
 513 #if EFSYS_OPT_LOOPBACK
 514                 encp->enc_loopback_types[EFX_LINK_10000FDX] =
 515                     QT2025C_LOOPBACK_MASK;
 516 #endif  /* EFSYS_OPT_LOOPBACK */
 517 #if EFSYS_OPT_PHY_STATS
 518                 encp->enc_phy_stat_mask = QT2025C_STAT_MASK;
 519 #endif  /* EFSYS_OPT_PHY_STATS */
 520 #if EFSYS_OPT_PHY_PROPS
 521                 encp->enc_phy_nprops = QT2025C_NPROPS;
 522 #endif  /* EFSYS_OPT_PHY_PROPS */
 523 #if EFSYS_OPT_PHY_BIST
 524                 encp->enc_bist_mask = QT2025C_BIST_MASK;
 525 #endif  /* EFSYS_OPT_PHY_BIST */
 526                 break;
 527 #endif  /* EFSYS_OPT_PHY_QT2025C */
 528 
 529         default:
 530                 rc = ENOTSUP;
 531                 goto fail2;
 532         }
 533 
 534 #if EFSYS_OPT_LOOPBACK
 535         encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
 536             (1 << EFX_LOOPBACK_OFF) |
 537             encp->enc_loopback_types[EFX_LINK_1000FDX] |
 538             encp->enc_loopback_types[EFX_LINK_10000FDX];
 539 #endif  /* EFSYS_OPT_LOOPBACK */
 540 
 541         return (0);
 542 
 543 fail2:
 544         EFSYS_PROBE(fail2);
 545 fail1:
 546         EFSYS_PROBE1(fail1, int, rc);
 547 
 548         return (rc);
 549 }
 550 
 551 #if EFSYS_OPT_PCIE_TUNE
 552 
 553 static                  void
 554 falcon_nic_pcie_core_read(
 555         __in            efx_nic_t *enp,
 556         __in            uint32_t addr,
 557         __out           efx_dword_t *edp)
 558 {
 559         int lstate;
 560         efx_oword_t oword;
 561         uint32_t val;
 562 
 563         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 564 
 565         EFSYS_LOCK(enp->en_eslp, lstate);
 566 
 567         EFX_POPULATE_OWORD_2(oword, FRF_BB_PCIE_CORE_TARGET_REG_ADRS, addr,
 568             FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR, 0);
 569         EFX_BAR_WRITEO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
 570 
 571         EFSYS_SPIN(10);
 572 
 573         EFX_BAR_READO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
 574         val = EFX_OWORD_FIELD(oword, FRF_BB_PCIE_CORE_TARGET_DATA);
 575 
 576         EFX_POPULATE_DWORD_1(*edp, EFX_DWORD_0, val);
 577 
 578         EFSYS_UNLOCK(enp->en_eslp, lstate);
 579 }
 580 
 581 static                  void
 582 falcon_nic_pcie_core_write(
 583         __in            efx_nic_t *enp,
 584         __in            uint32_t addr,
 585         __out           efx_dword_t *edp)
 586 {
 587         int lstate;
 588         efx_oword_t oword;
 589         uint32_t val;
 590 
 591         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 592 
 593         EFSYS_LOCK(enp->en_eslp, lstate);
 594 
 595         val = EFX_DWORD_FIELD(*edp, EFX_DWORD_0);
 596 
 597         EFX_POPULATE_OWORD_3(oword, FRF_BB_PCIE_CORE_TARGET_REG_ADRS, addr,
 598             FRF_BB_PCIE_CORE_TARGET_DATA, val,
 599             FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR, 0);
 600         EFX_BAR_WRITEO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
 601 
 602         EFSYS_UNLOCK(enp->en_eslp, lstate);
 603 }
 604 #endif  /* EFSYS_OPT_PCIE_TUNE || EFSYS_OPT_DIAG */
 605 
 606 #if EFSYS_OPT_PCIE_TUNE
 607 
 608 typedef struct falcon_pcie_rpl_s {
 609         size_t          fpr_tlp_size;
 610         uint32_t        fpr_value[4];
 611 } falcon_pcie_rpl_t;
 612 
 613 /*  TLP         1x      2x      4x      8x */
 614 static falcon_pcie_rpl_t        __cs falcon_nic_pcie_rpl[] = {
 615         { 128,  { 421,  257,    174,    166 } },
 616         { 256,  { 698,  391,    241,    225 } },
 617         { 512,  { 903,  498,    295,    193 } },
 618         { 1024, { 1670, 881,    487,    290 } }
 619 };
 620 
 621 static                  void
 622 falcon_nic_pcie_rpl_tl_set(
 623         __in            efx_nic_t *enp,
 624         __in            unsigned int nlanes)
 625 {
 626         uint32_t index;
 627         uint32_t current;
 628         falcon_pcie_rpl_t *fprp;
 629         uint32_t expected;
 630         efx_dword_t dword;
 631 
 632         EFSYS_ASSERT3U(nlanes, >, 0);
 633         EFSYS_ASSERT3U(nlanes, <=, 8);
 634         EFSYS_ASSERT(ISP2(nlanes));
 635 
 636         /* Get the appropriate set of replay timer values */
 637         falcon_nic_pcie_core_read(enp, PCR_AB_DEV_CTL_REG, &dword);
 638 
 639         index = EFX_DWORD_FIELD(dword, PCRF_AZ_MAX_PAYL_SIZE);
 640         if (index >= 4) {
 641                 EFSYS_PROBE1(fail1, int, EIO);
 642                 return;
 643         }
 644 
 645         fprp = (falcon_pcie_rpl_t *)&(falcon_nic_pcie_rpl[index]);
 646 
 647         EFSYS_PROBE1(pcie_tlp_size, size_t, fprp->fpr_tlp_size);
 648 
 649         for (index = 0; index < 4; index++)
 650                 if ((1 << index) == nlanes)
 651                         break;
 652 
 653         /* Get the current replay timer value */
 654         falcon_nic_pcie_core_read(enp, PCR_AC_ACK_LAT_TMR_REG, &dword);
 655         current = EFX_DWORD_FIELD(dword, PCRF_AC_RT);
 656 
 657         /* Get the appropriate replay timer value from the set */
 658         expected = fprp->fpr_value[index];
 659 
 660         EFSYS_PROBE2(pcie_rpl_tl, uint32_t, current, uint32_t, expected);
 661 
 662         EFSYS_PROBE1(pcie_ack_tl,
 663             uint32_t, EFX_DWORD_FIELD(dword, PCRF_AC_ALT));
 664 
 665         if (expected > current) {
 666                 EFX_SET_DWORD_FIELD(dword, PCRF_AC_RT, expected);
 667                 falcon_nic_pcie_core_write(enp, PCR_AC_ACK_LAT_TMR_REG,
 668                     &dword);
 669         }
 670 }
 671 
 672 static                  void
 673 falcon_nic_pcie_ack_freq_set(
 674         __in            efx_nic_t *enp,
 675         __in            uint32_t freq)
 676 {
 677         efx_dword_t dword;
 678 
 679         falcon_nic_pcie_core_read(enp, PCR_AC_ACK_FREQ_REG, &dword);
 680 
 681         EFSYS_PROBE2(pcie_ack_freq,
 682             uint32_t, EFX_DWORD_FIELD(dword, PCRF_AC_ACK_FREQ),
 683             uint32_t, freq);
 684 
 685         /* Set to zero to ensure that we always ACK after timeout */
 686         EFX_SET_DWORD_FIELD(dword, PCRF_AC_ACK_FREQ, freq);
 687         falcon_nic_pcie_core_write(enp, PCR_AC_ACK_FREQ_REG, &dword);
 688 }
 689 
 690                         int
 691 falcon_nic_pcie_tune(
 692         __in            efx_nic_t *enp,
 693         __in            unsigned int nlanes)
 694 {
 695         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 696 
 697         enp->en_u.falcon.enu_nlanes = nlanes;
 698         return (0);
 699 }
 700 
 701 #endif  /* EFSYS_OPT_PCIE_TUNE */
 702 
 703         __checkReturn   int
 704 falcon_nic_reset(
 705         __in            efx_nic_t *enp)
 706 {
 707         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 708         falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
 709         efx_oword_t oword;
 710         unsigned int count;
 711         int rc;
 712 
 713         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 714 
 715         /* Check the reset register */
 716         EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
 717 
 718         /* Select units for reset */
 719         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_CS, 1);
 720         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_TX, 1);
 721         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGTX, 1);
 722         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_RX, 1);
 723         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGRX, 1);
 724         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_SR, 1);
 725         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EV, 1);
 726         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EM, 1);
 727         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_PCIE_STKY, 1);
 728         EFX_SET_OWORD_FIELD(oword, FRF_BB_RST_BIU, 1);
 729         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XAUI_SD, 1);
 730 
 731         /* Initiate reset */
 732         EFX_BAR_WRITEO(enp, FR_AB_GLB_CTL_REG, &oword);
 733 
 734         /* Wait for the reset to complete */
 735         count = 0;
 736         do {
 737                 EFSYS_PROBE1(wait, unsigned int, count);
 738 
 739                 /* Spin for 10 us */
 740                 EFSYS_SPIN(10);
 741 
 742                 /* Test for reset complete */
 743                 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
 744                 if (EFX_OWORD_FIELD(oword, FRF_AB_RST_CS) == 0 &&
 745                     EFX_OWORD_FIELD(oword, FRF_AB_RST_TX) == 0 &&
 746                     EFX_OWORD_FIELD(oword, FRF_AB_RST_XGTX) == 0 &&
 747                     EFX_OWORD_FIELD(oword, FRF_AB_RST_RX) == 0 &&
 748                     EFX_OWORD_FIELD(oword, FRF_AB_RST_XGRX) == 0 &&
 749                     EFX_OWORD_FIELD(oword, FRF_AB_RST_SR) == 0 &&
 750                     EFX_OWORD_FIELD(oword, FRF_AB_RST_EV) == 0 &&
 751                     EFX_OWORD_FIELD(oword, FRF_AB_RST_EM) == 0 &&
 752                     EFX_OWORD_FIELD(oword, FRF_AB_RST_PCIE_STKY) == 0 &&
 753                     EFX_OWORD_FIELD(oword, FRF_BB_RST_BIU) == 0 &&
 754                     EFX_OWORD_FIELD(oword, FRF_AB_RST_XAUI_SD) == 0)
 755                         goto done;
 756         } while (++count < 1000);
 757 
 758         rc = ETIMEDOUT;
 759         goto fail1;
 760 
 761 done:
 762         /* GPIO initialization */
 763         EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
 764 
 765         /* Set I2C SCL to 1 */
 766         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OUT, 1);
 767         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OEN, 1);
 768 
 769         /* Select external 1G MAC clock if it is available */
 770         EFX_SET_OWORD_FIELD(oword, FRF_BB_USE_NIC_CLK,
 771             (encp->enc_board_type == BOARD_TYPE_SFN4111T_DECODE));
 772 
 773         EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
 774 
 775         fip->fi_sda = B_TRUE;
 776         fip->fi_scl = B_TRUE;
 777 
 778         return (0);
 779 
 780 fail1:
 781         EFSYS_PROBE1(fail1, int, rc);
 782 
 783         return (rc);
 784 }
 785 
 786 static                  void
 787 falcon_nic_timer_tbl_watchdog(
 788         __in            efx_nic_t *enp)
 789 {
 790         efx_oword_t oword;
 791 
 792         if (enp->en_family != EFX_FAMILY_FALCON)
 793                 return;
 794 
 795         /*
 796          * Ensure that PCI writes to the event queue read pointers are spaced
 797          * out far enough to avoid write loss.
 798          */
 799         EFX_BAR_READO(enp, FR_AZ_HW_INIT_REG, &oword);
 800         EFX_SET_OWORD_FIELD(oword, FRF_AZ_POST_WR_MASK, 0xf);
 801         EFX_SET_OWORD_FIELD(oword, FRF_AZ_WD_TIMER, 0x10);
 802         EFX_BAR_WRITEO(enp, FR_AZ_HW_INIT_REG, &oword);
 803 }
 804 
 805 static                  void
 806 falcon_rx_reset_recovery_enable(
 807         __in            efx_nic_t *enp)
 808 {
 809         efx_oword_t oword;
 810 
 811         /*
 812          * Set number of channels for receive path and also set filter table
 813          * search limits to 8, to reduce the frequency of RX_RECOVERY events
 814          */
 815         EFX_POPULATE_OWORD_4(oword,
 816                                 FRF_AZ_UDP_FULL_SRCH_LIMIT, 8,
 817                                 FRF_AZ_UDP_WILD_SRCH_LIMIT, 8,
 818                                 FRF_AZ_TCP_FULL_SRCH_LIMIT, 8,
 819                                 FRF_AZ_TCP_WILD_SRCH_LIMIT, 8);
 820         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
 821 
 822         /*
 823          * Enable RX Self-Reset functionality.
 824          * Disable ISCSI digest to reduce RX_RECOVERY frequency
 825          */
 826         EFX_BAR_READO(enp, FR_AZ_RX_SELF_RST_REG, &oword);
 827         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_ISCSI_DIS, 1);
 828         EFX_SET_OWORD_FIELD(oword, FRF_AB_RX_SW_RST_REG, 1);
 829         EFX_BAR_WRITEO(enp, FR_AZ_RX_SELF_RST_REG, &oword);
 830 }
 831 
 832         __checkReturn   int
 833 falcon_nic_init(
 834         __in            efx_nic_t *enp)
 835 {
 836         int rc;
 837 
 838         if ((rc = falcon_sram_init(enp)) != 0)
 839                 goto fail1;
 840 
 841 #if EFSYS_OPT_PCIE_TUNE
 842         /* Tune up the PCIe core */
 843         if (enp->en_u.falcon.enu_nlanes > 0) {
 844                 falcon_nic_pcie_rpl_tl_set(enp, enp->en_u.falcon.enu_nlanes);
 845                 falcon_nic_pcie_ack_freq_set(enp, 0);
 846         }
 847 #endif
 848         /* Fix NMI's due to premature timer_tbl biu watchdog */
 849         falcon_nic_timer_tbl_watchdog(enp);
 850 
 851         /* Enable RX_RECOVERY feature */
 852         falcon_rx_reset_recovery_enable(enp);
 853 
 854         return (0);
 855 
 856 fail1:
 857         EFSYS_PROBE1(fail1, int, rc);
 858 
 859         return (rc);
 860 }
 861 
 862         __checkReturn   int
 863 falcon_nic_mac_reset(
 864         __in            efx_nic_t *enp)
 865 {
 866         efx_oword_t oword;
 867         unsigned int count;
 868         int rc;
 869 
 870         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 871 
 872         EFX_BAR_READO(enp, FR_AB_MAC_CTRL_REG, &oword);
 873         EFX_SET_OWORD_FIELD(oword, FRF_BB_TXFIFO_DRAIN_EN, 1);
 874         EFX_BAR_WRITEO(enp, FR_AB_MAC_CTRL_REG, &oword);
 875 
 876         /* Reset the MAC and EM units */
 877         EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
 878 
 879         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EM, 1);
 880         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGRX, 1);
 881         EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGTX, 1);
 882 
 883         /* Initiate reset */
 884         EFX_BAR_WRITEO(enp, FR_AB_GLB_CTL_REG, &oword);
 885 
 886         /* Wait for the reset to complete */
 887         count = 0;
 888         do {
 889                 EFSYS_PROBE1(wait, unsigned int, count);
 890 
 891                 /* Spin for 10 us */
 892                 EFSYS_SPIN(10);
 893 
 894                 /* Test for reset complete */
 895                 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
 896                 if (EFX_OWORD_FIELD(oword, FRF_AB_RST_EM) == 0 &&
 897                     EFX_OWORD_FIELD(oword, FRF_AB_RST_XGRX) == 0 &&
 898                     EFX_OWORD_FIELD(oword, FRF_AB_RST_XGTX) == 0)
 899                         goto done;
 900         } while (++count < 1000);
 901 
 902         rc = ETIMEDOUT;
 903         goto fail1;
 904 
 905 done:
 906         enp->en_reset_flags |= EFX_RESET_MAC;
 907 
 908         return (0);
 909 
 910 fail1:
 911         EFSYS_PROBE1(fail1, int, rc);
 912         return (rc);
 913 }
 914 
 915                         void
 916 falcon_nic_phy_reset(
 917         __in            efx_nic_t *enp)
 918 {
 919         efx_oword_t oword;
 920         int state;
 921 
 922         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 923 
 924         /* Set PHY_RSTn to 0 */
 925         EFSYS_LOCK(enp->en_eslp, state);
 926         EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
 927         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OUT, 0);
 928         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OEN, 1);
 929         EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
 930         EFSYS_UNLOCK(enp->en_eslp, state);
 931 
 932         EFSYS_SLEEP(500000);
 933 
 934         EFSYS_LOCK(enp->en_eslp, state);
 935         EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
 936         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OEN, 0);
 937         EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
 938         EFSYS_UNLOCK(enp->en_eslp, state);
 939 
 940         EFSYS_SLEEP(100000);
 941 
 942         enp->en_reset_flags |= EFX_RESET_PHY;
 943 }
 944 
 945                         void
 946 falcon_nic_fini(
 947         __in            efx_nic_t *enp)
 948 {
 949         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 950 
 951 #if EFSYS_OPT_PCIE_TUNE
 952         falcon_nic_pcie_ack_freq_set(enp, 1);
 953 #endif  /* EFSYS_OPT_PCIE_TUNE */
 954 
 955         falcon_sram_fini(enp);
 956 }
 957 
 958                         void
 959 falcon_nic_unprobe(
 960         __in            efx_nic_t *enp)
 961 {
 962         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 963 
 964         falcon_nvram_fini(enp);
 965 }
 966 
 967 #if EFSYS_OPT_DIAG
 968 
 969 static efx_register_set_t __cs  __falcon_b0_registers[] = {
 970         { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
 971         { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
 972         { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
 973         { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
 974         { FR_AB_MAC_CTRL_REG_OFST, 0, 1 },
 975         { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
 976         { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
 977         { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
 978         { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
 979         { FR_AB_GM_CFG2_REG_OFST, 0, 1 },
 980         { FR_AB_GMF_CFG0_REG_OFST, 0, 1 },
 981         { FR_AB_XM_GLB_CFG_REG_OFST, 0, 1 },
 982         { FR_AB_XM_TX_CFG_REG_OFST, 0, 1 },
 983         { FR_AB_XM_RX_CFG_REG_OFST, 0, 1 },
 984         { FR_AB_XM_RX_PARAM_REG_OFST, 0, 1 },
 985         { FR_AB_XM_FC_REG_OFST, 0, 1 },
 986         { FR_AB_XM_ADR_LO_REG_OFST, 0, 1 },
 987         { FR_AB_XX_SD_CTL_REG_OFST, 0, 1 },
 988 };
 989 
 990 static const uint32_t __cs      __falcon_b0_register_masks[] = {
 991         0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
 992         0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000,
 993         0x7FFF0037, 0x00000000, 0x00000000, 0x00000000,
 994         0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
 995         0xFFFF0000, 0x00000000, 0x00000000, 0x00000000,
 996         0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
 997         0x0000000F, 0x00000000, 0x00000000, 0x00000000,
 998         0x000003FF, 0x00000000, 0x00000000, 0x00000000,
 999         0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
1000         0x00007337, 0x00000000, 0x00000000, 0x00000000,
1001         0x00001F1F, 0x00000000, 0x00000000, 0x00000000,
1002         0x00000C68, 0x00000000, 0x00000000, 0x00000000,
1003         0x00080164, 0x00000000, 0x00000000, 0x00000000,
1004         0x07100A0C, 0x00000000, 0x00000000, 0x00000000,
1005         0x00001FF8, 0x00000000, 0x00000000, 0x00000000,
1006         0xFFFF0001, 0x00000000, 0x00000000, 0x00000000,
1007         0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
1008         0x0003FF0F, 0x00000000, 0x00000000, 0x00000000,
1009 };
1010 
1011 static efx_register_set_t __cs  __falcon_b0_tables[] = {
1012         { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
1013             FR_AZ_RX_FILTER_TBL0_ROWS },
1014         { FR_AB_RX_FILTER_TBL1_OFST, FR_AB_RX_FILTER_TBL1_STEP,
1015             FR_AB_RX_FILTER_TBL1_ROWS },
1016         { FR_AZ_RX_DESC_PTR_TBL_OFST,
1017             FR_AZ_RX_DESC_PTR_TBL_STEP, FR_AB_RX_DESC_PTR_TBL_ROWS },
1018         { FR_AZ_TX_DESC_PTR_TBL_OFST,
1019             FR_AZ_TX_DESC_PTR_TBL_STEP, FR_AB_TX_DESC_PTR_TBL_ROWS },
1020 };
1021 
1022 static const uint32_t __cs      __falcon_b0_table_masks[] = {
1023         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
1024         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
1025         0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
1026         0x3FFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
1027 };
1028 
1029         __checkReturn   int
1030 falcon_nic_register_test(
1031         __in            efx_nic_t *enp)
1032 {
1033         efx_register_set_t *rsp;
1034         const uint32_t *dwordp;
1035         unsigned int nitems;
1036         unsigned int count;
1037         int rc;
1038 
1039         /* Fill out the register mask entries */
1040         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__falcon_b0_register_masks)
1041                     == EFX_ARRAY_SIZE(__falcon_b0_registers) * 4);
1042 
1043         nitems = EFX_ARRAY_SIZE(__falcon_b0_registers);
1044         dwordp = __falcon_b0_register_masks;
1045         for (count = 0; count < nitems; ++count) {
1046                 rsp = __falcon_b0_registers + count;
1047                 rsp->mask.eo_u32[0] = *dwordp++;
1048                 rsp->mask.eo_u32[1] = *dwordp++;
1049                 rsp->mask.eo_u32[2] = *dwordp++;
1050                 rsp->mask.eo_u32[3] = *dwordp++;
1051         }
1052 
1053         /* Fill out the register table entries */
1054         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__falcon_b0_table_masks)
1055                     == EFX_ARRAY_SIZE(__falcon_b0_tables) * 4);
1056 
1057         nitems = EFX_ARRAY_SIZE(__falcon_b0_tables);
1058         dwordp = __falcon_b0_table_masks;
1059         for (count = 0; count < nitems; ++count) {
1060                 rsp = __falcon_b0_tables + count;
1061                 rsp->mask.eo_u32[0] = *dwordp++;
1062                 rsp->mask.eo_u32[1] = *dwordp++;
1063                 rsp->mask.eo_u32[2] = *dwordp++;
1064                 rsp->mask.eo_u32[3] = *dwordp++;
1065         }
1066 
1067         if ((rc = efx_nic_test_registers(enp, __falcon_b0_registers,
1068             EFX_ARRAY_SIZE(__falcon_b0_registers))) != 0)
1069                 goto fail1;
1070 
1071         if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1072             EFX_PATTERN_BYTE_ALTERNATE,
1073             EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1074                 goto fail2;
1075 
1076         if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1077             EFX_PATTERN_BYTE_CHANGING,
1078             EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1079                 goto fail3;
1080 
1081         if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1082             EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1083                 goto fail4;
1084 
1085         return (0);
1086 
1087 fail4:
1088         EFSYS_PROBE(fail4);
1089 fail3:
1090         EFSYS_PROBE(fail3);
1091 fail2:
1092         EFSYS_PROBE(fail2);
1093 fail1:
1094         EFSYS_PROBE1(fail1, int, rc);
1095 
1096         return (rc);
1097 }
1098 
1099 #endif  /* EFSYS_OPT_DIAG */
1100 
1101 #endif  /* EFSYS_OPT_FALCON */