1 /*
   2  * Copyright (c) 2009-2015 Solarflare Communications Inc.
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions are met:
   7  *
   8  * 1. Redistributions of source code must retain the above copyright notice,
   9  *    this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11  *    this list of conditions and the following disclaimer in the documentation
  12  *    and/or other materials provided with the distribution.
  13  *
  14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25  *
  26  * The views and conclusions contained in the software and documentation are
  27  * those of the authors and should not be interpreted as representing official
  28  * policies, either expressed or implied, of the FreeBSD Project.
  29  */
  30 
  31 #include "efx.h"
  32 #include "efx_impl.h"
  33 #include "mcdi_mon.h"
  34 
  35 #if EFSYS_OPT_SIENA
  36 
  37 static  __checkReturn           efx_rc_t
  38 siena_nic_get_partn_mask(
  39         __in                    efx_nic_t *enp,
  40         __out                   unsigned int *maskp)
  41 {
  42         efx_mcdi_req_t req;
  43         uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
  44                             MC_CMD_NVRAM_TYPES_OUT_LEN)];
  45         efx_rc_t rc;
  46 
  47         (void) memset(payload, 0, sizeof (payload));
  48         req.emr_cmd = MC_CMD_NVRAM_TYPES;
  49         req.emr_in_buf = payload;
  50         req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
  51         req.emr_out_buf = payload;
  52         req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
  53 
  54         efx_mcdi_execute(enp, &req);
  55 
  56         if (req.emr_rc != 0) {
  57                 rc = req.emr_rc;
  58                 goto fail1;
  59         }
  60 
  61         if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
  62                 rc = EMSGSIZE;
  63                 goto fail2;
  64         }
  65 
  66         *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
  67 
  68         return (0);
  69 
  70 fail2:
  71         EFSYS_PROBE(fail2);
  72 fail1:
  73         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  74 
  75         return (rc);
  76 }
  77 
  78 static  __checkReturn   efx_rc_t
  79 siena_board_cfg(
  80         __in            efx_nic_t *enp)
  81 {
  82         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
  83         uint8_t mac_addr[6];
  84         efx_dword_t capabilities;
  85         uint32_t board_type;
  86         uint32_t nevq, nrxq, ntxq;
  87         efx_rc_t rc;
  88 
  89         /* External port identifier using one-based port numbering */
  90         encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
  91 
  92         /* Board configuration */
  93         if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
  94                     &capabilities, mac_addr)) != 0)
  95                 goto fail1;
  96 
  97         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
  98 
  99         encp->enc_board_type = board_type;
 100 
 101         /* Additional capabilities */
 102         encp->enc_clk_mult = 1;
 103         if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
 104                 enp->en_features |= EFX_FEATURE_TURBO;
 105 
 106                 if (EFX_DWORD_FIELD(capabilities,
 107                         MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
 108                         encp->enc_clk_mult = 2;
 109                 }
 110         }
 111 
 112         encp->enc_evq_timer_quantum_ns =
 113                 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
 114         encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
 115                 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
 116 
 117         /* When hash header insertion is enabled, Siena inserts 16 bytes */
 118         encp->enc_rx_prefix_size = 16;
 119 
 120         /* Alignment for receive packet DMA buffers */
 121         encp->enc_rx_buf_align_start = 1;
 122         encp->enc_rx_buf_align_end = 1;
 123 
 124         /* Alignment for WPTR updates */
 125         encp->enc_rx_push_align = 1;
 126 
 127         /* Resource limits */
 128         rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
 129         if (rc != 0) {
 130                 if (rc != ENOTSUP)
 131                         goto fail2;
 132 
 133                 nevq = 1024;
 134                 nrxq = EFX_RXQ_LIMIT_TARGET;
 135                 ntxq = EFX_TXQ_LIMIT_TARGET;
 136         }
 137         encp->enc_evq_limit = nevq;
 138         encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
 139         encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
 140 
 141         encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
 142             (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
 143             (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
 144 
 145         encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
 146         encp->enc_fw_assisted_tso_enabled = B_FALSE;
 147         encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
 148         encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
 149 
 150         return (0);
 151 
 152 fail2:
 153         EFSYS_PROBE(fail2);
 154 fail1:
 155         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 156 
 157         return (rc);
 158 }
 159 
 160 static  __checkReturn   efx_rc_t
 161 siena_phy_cfg(
 162         __in            efx_nic_t *enp)
 163 {
 164         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 165         efx_rc_t rc;
 166 
 167         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
 168         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
 169                 goto fail1;
 170 
 171 #if EFSYS_OPT_PHY_STATS
 172         /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
 173         siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
 174                             NULL, &encp->enc_phy_stat_mask, NULL);
 175 #endif  /* EFSYS_OPT_PHY_STATS */
 176 
 177         return (0);
 178 
 179 fail1:
 180         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 181 
 182         return (rc);
 183 }
 184 
 185         __checkReturn   efx_rc_t
 186 siena_nic_probe(
 187         __in            efx_nic_t *enp)
 188 {
 189         efx_port_t *epp = &(enp->en_port);
 190         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 191         siena_link_state_t sls;
 192         unsigned int mask;
 193         efx_oword_t oword;
 194         efx_rc_t rc;
 195 
 196         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
 197 
 198         /* Test BIU */
 199         if ((rc = efx_nic_biu_test(enp)) != 0)
 200                 goto fail1;
 201 
 202         /* Clear the region register */
 203         EFX_POPULATE_OWORD_4(oword,
 204             FRF_AZ_ADR_REGION0, 0,
 205             FRF_AZ_ADR_REGION1, (1 << 16),
 206             FRF_AZ_ADR_REGION2, (2 << 16),
 207             FRF_AZ_ADR_REGION3, (3 << 16));
 208         EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
 209 
 210         /* Read clear any assertion state */
 211         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
 212                 goto fail2;
 213 
 214         /* Exit the assertion handler */
 215         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
 216                 goto fail3;
 217 
 218         /* Wrestle control from the BMC */
 219         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
 220                 goto fail4;
 221 
 222         if ((rc = siena_board_cfg(enp)) != 0)
 223                 goto fail5;
 224 
 225         if ((rc = siena_phy_cfg(enp)) != 0)
 226                 goto fail6;
 227 
 228         /* Obtain the default PHY advertised capabilities */
 229         if ((rc = siena_nic_reset(enp)) != 0)
 230                 goto fail7;
 231         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
 232                 goto fail8;
 233         epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
 234         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
 235 
 236 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
 237         if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
 238                 goto fail9;
 239         enp->en_u.siena.enu_partn_mask = mask;
 240 #endif
 241 
 242 #if EFSYS_OPT_MAC_STATS
 243         /* Wipe the MAC statistics */
 244         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
 245                 goto fail10;
 246 #endif
 247 
 248 #if EFSYS_OPT_LOOPBACK
 249         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
 250                 goto fail11;
 251 #endif
 252 
 253 #if EFSYS_OPT_MON_STATS
 254         if ((rc = mcdi_mon_cfg_build(enp)) != 0)
 255                 goto fail12;
 256 #endif
 257 
 258         encp->enc_features = enp->en_features;
 259 
 260         return (0);
 261 
 262 #if EFSYS_OPT_MON_STATS
 263 fail12:
 264         EFSYS_PROBE(fail12);
 265 #endif
 266 #if EFSYS_OPT_LOOPBACK
 267 fail11:
 268         EFSYS_PROBE(fail11);
 269 #endif
 270 #if EFSYS_OPT_MAC_STATS
 271 fail10:
 272         EFSYS_PROBE(fail10);
 273 #endif
 274 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
 275 fail9:
 276         EFSYS_PROBE(fail9);
 277 #endif
 278 fail8:
 279         EFSYS_PROBE(fail8);
 280 fail7:
 281         EFSYS_PROBE(fail7);
 282 fail6:
 283         EFSYS_PROBE(fail6);
 284 fail5:
 285         EFSYS_PROBE(fail5);
 286 fail4:
 287         EFSYS_PROBE(fail4);
 288 fail3:
 289         EFSYS_PROBE(fail3);
 290 fail2:
 291         EFSYS_PROBE(fail2);
 292 fail1:
 293         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 294 
 295         return (rc);
 296 }
 297 
 298         __checkReturn   efx_rc_t
 299 siena_nic_reset(
 300         __in            efx_nic_t *enp)
 301 {
 302         efx_mcdi_req_t req;
 303         efx_rc_t rc;
 304 
 305         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
 306 
 307         /* siena_nic_reset() is called to recover from BADASSERT failures. */
 308         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
 309                 goto fail1;
 310         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
 311                 goto fail2;
 312 
 313         /*
 314          * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
 315          * for backwards compatibility with PORT_RESET_IN_LEN.
 316          */
 317         EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
 318 
 319         req.emr_cmd = MC_CMD_ENTITY_RESET;
 320         req.emr_in_buf = NULL;
 321         req.emr_in_length = 0;
 322         req.emr_out_buf = NULL;
 323         req.emr_out_length = 0;
 324 
 325         efx_mcdi_execute(enp, &req);
 326 
 327         if (req.emr_rc != 0) {
 328                 rc = req.emr_rc;
 329                 goto fail3;
 330         }
 331 
 332         return (0);
 333 
 334 fail3:
 335         EFSYS_PROBE(fail3);
 336 fail2:
 337         EFSYS_PROBE(fail2);
 338 fail1:
 339         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 340 
 341         return (0);
 342 }
 343 
 344 static                  void
 345 siena_nic_rx_cfg(
 346         __in            efx_nic_t *enp)
 347 {
 348         efx_oword_t oword;
 349 
 350         /*
 351          * RX_INGR_EN is always enabled on Siena, because we rely on
 352          * the RX parser to be resiliant to missing SOP/EOP.
 353          */
 354         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
 355         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
 356         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
 357 
 358         /* Disable parsing of additional 802.1Q in Q packets */
 359         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
 360         EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
 361         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
 362 }
 363 
 364 static                  void
 365 siena_nic_usrev_dis(
 366         __in            efx_nic_t *enp)
 367 {
 368         efx_oword_t     oword;
 369 
 370         EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
 371         EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
 372 }
 373 
 374         __checkReturn   efx_rc_t
 375 siena_nic_init(
 376         __in            efx_nic_t *enp)
 377 {
 378         efx_rc_t rc;
 379 
 380         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
 381 
 382         /* Enable reporting of some events (e.g. link change) */
 383         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
 384                 goto fail1;
 385 
 386         siena_sram_init(enp);
 387 
 388         /* Configure Siena's RX block */
 389         siena_nic_rx_cfg(enp);
 390 
 391         /* Disable USR_EVents for now */
 392         siena_nic_usrev_dis(enp);
 393 
 394         /* bug17057: Ensure set_link is called */
 395         if ((rc = siena_phy_reconfigure(enp)) != 0)
 396                 goto fail2;
 397 
 398         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
 399 
 400         return (0);
 401 
 402 fail2:
 403         EFSYS_PROBE(fail2);
 404 fail1:
 405         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 406 
 407         return (rc);
 408 }
 409 
 410                         void
 411 siena_nic_fini(
 412         __in            efx_nic_t *enp)
 413 {
 414         _NOTE(ARGUNUSED(enp))
 415 }
 416 
 417                         void
 418 siena_nic_unprobe(
 419         __in            efx_nic_t *enp)
 420 {
 421 #if EFSYS_OPT_MON_STATS
 422         mcdi_mon_cfg_free(enp);
 423 #endif /* EFSYS_OPT_MON_STATS */
 424         (void) efx_mcdi_drv_attach(enp, B_FALSE);
 425 }
 426 
 427 #if EFSYS_OPT_DIAG
 428 
 429 static efx_register_set_t __siena_registers[] = {
 430         { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
 431         { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
 432         { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
 433         { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
 434         { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
 435         { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
 436         { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
 437         { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
 438         { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
 439         { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
 440         { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
 441         { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
 442         { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
 443 };
 444 
 445 static const uint32_t __siena_register_masks[] = {
 446         0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
 447         0x000103FF, 0x00000000, 0x00000000, 0x00000000,
 448         0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
 449         0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
 450         0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
 451         0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
 452         0x00000003, 0x00000000, 0x00000000, 0x00000000,
 453         0x000003FF, 0x00000000, 0x00000000, 0x00000000,
 454         0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
 455         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
 456         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
 457         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
 458         0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
 459 };
 460 
 461 static efx_register_set_t __siena_tables[] = {
 462         { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
 463             FR_AZ_RX_FILTER_TBL0_ROWS },
 464         { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
 465             FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
 466         { FR_AZ_RX_DESC_PTR_TBL_OFST,
 467             FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
 468         { FR_AZ_TX_DESC_PTR_TBL_OFST,
 469             FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
 470         { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
 471         { FR_CZ_TX_FILTER_TBL0_OFST,
 472             FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
 473         { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
 474             FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
 475 };
 476 
 477 static const uint32_t __siena_table_masks[] = {
 478         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
 479         0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
 480         0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
 481         0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
 482         0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
 483         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
 484         0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
 485 };
 486 
 487         __checkReturn   efx_rc_t
 488 siena_nic_register_test(
 489         __in            efx_nic_t *enp)
 490 {
 491         efx_register_set_t *rsp;
 492         const uint32_t *dwordp;
 493         unsigned int nitems;
 494         unsigned int count;
 495         efx_rc_t rc;
 496 
 497         /* Fill out the register mask entries */
 498         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
 499                     == EFX_ARRAY_SIZE(__siena_registers) * 4);
 500 
 501         nitems = EFX_ARRAY_SIZE(__siena_registers);
 502         dwordp = __siena_register_masks;
 503         for (count = 0; count < nitems; ++count) {
 504                 rsp = __siena_registers + count;
 505                 rsp->mask.eo_u32[0] = *dwordp++;
 506                 rsp->mask.eo_u32[1] = *dwordp++;
 507                 rsp->mask.eo_u32[2] = *dwordp++;
 508                 rsp->mask.eo_u32[3] = *dwordp++;
 509         }
 510 
 511         /* Fill out the register table entries */
 512         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
 513                     == EFX_ARRAY_SIZE(__siena_tables) * 4);
 514 
 515         nitems = EFX_ARRAY_SIZE(__siena_tables);
 516         dwordp = __siena_table_masks;
 517         for (count = 0; count < nitems; ++count) {
 518                 rsp = __siena_tables + count;
 519                 rsp->mask.eo_u32[0] = *dwordp++;
 520                 rsp->mask.eo_u32[1] = *dwordp++;
 521                 rsp->mask.eo_u32[2] = *dwordp++;
 522                 rsp->mask.eo_u32[3] = *dwordp++;
 523         }
 524 
 525         if ((rc = efx_nic_test_registers(enp, __siena_registers,
 526             EFX_ARRAY_SIZE(__siena_registers))) != 0)
 527                 goto fail1;
 528 
 529         if ((rc = efx_nic_test_tables(enp, __siena_tables,
 530             EFX_PATTERN_BYTE_ALTERNATE,
 531             EFX_ARRAY_SIZE(__siena_tables))) != 0)
 532                 goto fail2;
 533 
 534         if ((rc = efx_nic_test_tables(enp, __siena_tables,
 535             EFX_PATTERN_BYTE_CHANGING,
 536             EFX_ARRAY_SIZE(__siena_tables))) != 0)
 537                 goto fail3;
 538 
 539         if ((rc = efx_nic_test_tables(enp, __siena_tables,
 540             EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
 541                 goto fail4;
 542 
 543         return (0);
 544 
 545 fail4:
 546         EFSYS_PROBE(fail4);
 547 fail3:
 548         EFSYS_PROBE(fail3);
 549 fail2:
 550         EFSYS_PROBE(fail2);
 551 fail1:
 552         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 553 
 554         return (rc);
 555 }
 556 
 557 #endif  /* EFSYS_OPT_DIAG */
 558 
 559 #endif  /* EFSYS_OPT_SIENA */