2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2009-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
44 static __checkReturn efx_rc_t
45 siena_nic_get_partn_mask(
47 __out unsigned int *maskp)
50 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
51 MC_CMD_NVRAM_TYPES_OUT_LEN);
54 req.emr_cmd = MC_CMD_NVRAM_TYPES;
55 req.emr_in_buf = payload;
56 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
57 req.emr_out_buf = payload;
58 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
60 efx_mcdi_execute(enp, &req);
62 if (req.emr_rc != 0) {
67 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
72 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
79 EFSYS_PROBE1(fail1, efx_rc_t, rc);
84 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
86 static __checkReturn efx_rc_t
90 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
92 efx_dword_t capabilities;
94 uint32_t nevq, nrxq, ntxq;
97 /* Siena has a fixed 8Kbyte VI window size */
98 EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192);
99 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
101 /* External port identifier using one-based port numbering */
102 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
104 /* Board configuration */
105 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
106 &capabilities, mac_addr)) != 0)
109 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
111 encp->enc_board_type = board_type;
114 * There is no possibility to determine the number of PFs on Siena
115 * by issuing MCDI request, and it is not an easy task to find the
116 * value based on the board type, so 'enc_hw_pf_count' is set to 1
118 encp->enc_hw_pf_count = 1;
120 /* Additional capabilities */
121 encp->enc_clk_mult = 1;
122 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
123 enp->en_features |= EFX_FEATURE_TURBO;
125 if (EFX_DWORD_FIELD(capabilities,
126 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
127 encp->enc_clk_mult = 2;
131 encp->enc_evq_timer_quantum_ns =
132 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
133 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
134 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
136 /* When hash header insertion is enabled, Siena inserts 16 bytes */
137 encp->enc_rx_prefix_size = 16;
139 /* Alignment for receive packet DMA buffers */
140 encp->enc_rx_buf_align_start = 1;
141 encp->enc_rx_buf_align_end = 1;
143 /* Alignment for WPTR updates */
144 encp->enc_rx_push_align = 1;
146 #if EFSYS_OPT_RX_SCALE
147 /* There is one RSS context per function */
148 encp->enc_rx_scale_max_exclusive_contexts = 1;
150 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
151 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
154 * It is always possible to use port numbers
155 * as the input data for hash computation.
157 encp->enc_rx_scale_l4_hash_supported = B_TRUE;
159 /* There is no support for additional RSS modes */
160 encp->enc_rx_scale_additional_modes_supported = B_FALSE;
161 #endif /* EFSYS_OPT_RX_SCALE */
163 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
164 /* Fragments must not span 4k boundaries. */
165 encp->enc_tx_dma_desc_boundary = 4096;
167 /* Resource limits */
168 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
174 nrxq = EFX_RXQ_LIMIT_TARGET;
175 ntxq = EFX_TXQ_LIMIT_TARGET;
177 encp->enc_evq_limit = nevq;
178 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
179 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
181 encp->enc_txq_max_ndescs = 4096;
183 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
184 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
185 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
187 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
188 encp->enc_fw_assisted_tso_enabled = B_FALSE;
189 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
190 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
191 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
192 encp->enc_rx_packed_stream_supported = B_FALSE;
193 encp->enc_rx_var_packed_stream_supported = B_FALSE;
194 encp->enc_rx_es_super_buffer_supported = B_FALSE;
195 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
197 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
198 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
199 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
201 encp->enc_nvram_update_verify_result_supported = B_FALSE;
203 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
205 encp->enc_filter_action_flag_supported = B_FALSE;
206 encp->enc_filter_action_mark_supported = B_FALSE;
207 encp->enc_filter_action_mark_max = 0;
214 EFSYS_PROBE1(fail1, efx_rc_t, rc);
219 static __checkReturn efx_rc_t
223 #if EFSYS_OPT_PHY_STATS
224 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
225 #endif /* EFSYS_OPT_PHY_STATS */
228 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
229 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
232 #if EFSYS_OPT_PHY_STATS
233 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
234 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
235 NULL, &encp->enc_phy_stat_mask, NULL);
236 #endif /* EFSYS_OPT_PHY_STATS */
241 EFSYS_PROBE1(fail1, efx_rc_t, rc);
246 #define SIENA_BIU_MAGIC0 0x01234567
247 #define SIENA_BIU_MAGIC1 0xfedcba98
249 static __checkReturn efx_rc_t
257 * Write magic values to scratch registers 0 and 1, then
258 * verify that the values were written correctly. Interleave
259 * the accesses to ensure that the BIU is not just reading
260 * back the cached value that was last written.
262 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
263 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
265 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
266 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
268 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
269 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
274 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
275 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
281 * Perform the same test, with the values swapped. This
282 * ensures that subsequent tests don't start with the correct
283 * values already written into the scratch registers.
285 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
286 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
288 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
289 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
291 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
292 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
297 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
298 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
312 EFSYS_PROBE1(fail1, efx_rc_t, rc);
317 __checkReturn efx_rc_t
321 efx_port_t *epp = &(enp->en_port);
322 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
323 siena_link_state_t sls;
328 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
331 if ((rc = siena_nic_biu_test(enp)) != 0)
334 /* Clear the region register */
335 EFX_POPULATE_OWORD_4(oword,
336 FRF_AZ_ADR_REGION0, 0,
337 FRF_AZ_ADR_REGION1, (1 << 16),
338 FRF_AZ_ADR_REGION2, (2 << 16),
339 FRF_AZ_ADR_REGION3, (3 << 16));
340 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
342 /* Read clear any assertion state */
343 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
346 /* Exit the assertion handler */
347 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
350 /* Wrestle control from the BMC */
351 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
354 if ((rc = siena_board_cfg(enp)) != 0)
357 if ((rc = siena_phy_cfg(enp)) != 0)
360 /* Obtain the default PHY advertised capabilities */
361 if ((rc = siena_nic_reset(enp)) != 0)
363 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
365 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
366 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
368 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
369 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
371 enp->en_u.siena.enu_partn_mask = mask;
374 #if EFSYS_OPT_MAC_STATS
375 /* Wipe the MAC statistics */
376 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
380 #if EFSYS_OPT_LOOPBACK
381 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
385 #if EFSYS_OPT_MON_STATS
386 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
390 encp->enc_features = enp->en_features;
394 #if EFSYS_OPT_MON_STATS
398 #if EFSYS_OPT_LOOPBACK
402 #if EFSYS_OPT_MAC_STATS
406 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
425 EFSYS_PROBE1(fail1, efx_rc_t, rc);
430 __checkReturn efx_rc_t
437 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
439 /* siena_nic_reset() is called to recover from BADASSERT failures. */
440 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
442 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
446 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
447 * for backwards compatibility with PORT_RESET_IN_LEN.
449 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
451 req.emr_cmd = MC_CMD_ENTITY_RESET;
452 req.emr_in_buf = NULL;
453 req.emr_in_length = 0;
454 req.emr_out_buf = NULL;
455 req.emr_out_length = 0;
457 efx_mcdi_execute(enp, &req);
459 if (req.emr_rc != 0) {
471 EFSYS_PROBE1(fail1, efx_rc_t, rc);
483 * RX_INGR_EN is always enabled on Siena, because we rely on
484 * the RX parser to be resiliant to missing SOP/EOP.
486 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
487 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
488 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
490 /* Disable parsing of additional 802.1Q in Q packets */
491 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
492 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
493 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
502 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
503 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
506 __checkReturn efx_rc_t
512 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
514 /* Enable reporting of some events (e.g. link change) */
515 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
518 siena_sram_init(enp);
520 /* Configure Siena's RX block */
521 siena_nic_rx_cfg(enp);
523 /* Disable USR_EVents for now */
524 siena_nic_usrev_dis(enp);
526 /* bug17057: Ensure set_link is called */
527 if ((rc = siena_phy_reconfigure(enp)) != 0)
530 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
537 EFSYS_PROBE1(fail1, efx_rc_t, rc);
546 _NOTE(ARGUNUSED(enp))
553 #if EFSYS_OPT_MON_STATS
554 mcdi_mon_cfg_free(enp);
555 #endif /* EFSYS_OPT_MON_STATS */
556 (void) efx_mcdi_drv_attach(enp, B_FALSE);
561 static siena_register_set_t __siena_registers[] = {
562 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
563 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
564 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
565 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
566 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
567 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
568 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
569 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
570 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
571 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
572 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
573 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
574 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
577 static const uint32_t __siena_register_masks[] = {
578 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
579 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
580 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
581 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
582 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
583 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
584 0x00000003, 0x00000000, 0x00000000, 0x00000000,
585 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
586 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
587 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
588 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
589 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
590 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
593 static siena_register_set_t __siena_tables[] = {
594 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
595 FR_AZ_RX_FILTER_TBL0_ROWS },
596 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
597 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
598 { FR_AZ_RX_DESC_PTR_TBL_OFST,
599 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
600 { FR_AZ_TX_DESC_PTR_TBL_OFST,
601 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
602 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
603 { FR_CZ_TX_FILTER_TBL0_OFST,
604 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
605 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
606 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
609 static const uint32_t __siena_table_masks[] = {
610 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
611 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
612 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
613 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
614 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
615 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
616 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
619 __checkReturn efx_rc_t
620 siena_nic_test_registers(
622 __in siena_register_set_t *rsp,
626 efx_oword_t original;
632 /* This function is only suitable for registers */
633 EFSYS_ASSERT(rsp->rows == 1);
635 /* bit sweep on and off */
636 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
638 for (bit = 0; bit < 128; bit++) {
639 /* Is this bit in the mask? */
640 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
643 /* Test this bit can be set in isolation */
645 EFX_AND_OWORD(reg, rsp->mask);
646 EFX_SET_OWORD_BIT(reg, bit);
648 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
650 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
653 EFX_AND_OWORD(buf, rsp->mask);
654 if (memcmp(®, &buf, sizeof (reg))) {
659 /* Test this bit can be cleared in isolation */
660 EFX_OR_OWORD(reg, rsp->mask);
661 EFX_CLEAR_OWORD_BIT(reg, bit);
663 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
665 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
668 EFX_AND_OWORD(buf, rsp->mask);
669 if (memcmp(®, &buf, sizeof (reg))) {
675 /* Restore the old value */
676 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
688 EFSYS_PROBE1(fail1, efx_rc_t, rc);
690 /* Restore the old value */
691 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
696 __checkReturn efx_rc_t
697 siena_nic_test_tables(
699 __in siena_register_set_t *rsp,
700 __in efx_pattern_type_t pattern,
703 efx_sram_pattern_fn_t func;
705 unsigned int address;
710 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
711 func = __efx_sram_pattern_fns[pattern];
715 address = rsp->address;
716 for (index = 0; index < rsp->rows; ++index) {
717 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
718 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
719 EFX_AND_OWORD(reg, rsp->mask);
720 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE);
722 address += rsp->step;
726 address = rsp->address;
727 for (index = 0; index < rsp->rows; ++index) {
728 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
729 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
730 EFX_AND_OWORD(reg, rsp->mask);
731 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
732 if (memcmp(®, &buf, sizeof (reg))) {
737 address += rsp->step;
747 EFSYS_PROBE1(fail1, efx_rc_t, rc);
752 __checkReturn efx_rc_t
753 siena_nic_register_test(
756 siena_register_set_t *rsp;
757 const uint32_t *dwordp;
762 /* Fill out the register mask entries */
763 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
764 == EFX_ARRAY_SIZE(__siena_registers) * 4);
766 nitems = EFX_ARRAY_SIZE(__siena_registers);
767 dwordp = __siena_register_masks;
768 for (count = 0; count < nitems; ++count) {
769 rsp = __siena_registers + count;
770 rsp->mask.eo_u32[0] = *dwordp++;
771 rsp->mask.eo_u32[1] = *dwordp++;
772 rsp->mask.eo_u32[2] = *dwordp++;
773 rsp->mask.eo_u32[3] = *dwordp++;
776 /* Fill out the register table entries */
777 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
778 == EFX_ARRAY_SIZE(__siena_tables) * 4);
780 nitems = EFX_ARRAY_SIZE(__siena_tables);
781 dwordp = __siena_table_masks;
782 for (count = 0; count < nitems; ++count) {
783 rsp = __siena_tables + count;
784 rsp->mask.eo_u32[0] = *dwordp++;
785 rsp->mask.eo_u32[1] = *dwordp++;
786 rsp->mask.eo_u32[2] = *dwordp++;
787 rsp->mask.eo_u32[3] = *dwordp++;
790 if ((rc = siena_nic_test_registers(enp, __siena_registers,
791 EFX_ARRAY_SIZE(__siena_registers))) != 0)
794 if ((rc = siena_nic_test_tables(enp, __siena_tables,
795 EFX_PATTERN_BYTE_ALTERNATE,
796 EFX_ARRAY_SIZE(__siena_tables))) != 0)
799 if ((rc = siena_nic_test_tables(enp, __siena_tables,
800 EFX_PATTERN_BYTE_CHANGING,
801 EFX_ARRAY_SIZE(__siena_tables))) != 0)
804 if ((rc = siena_nic_test_tables(enp, __siena_tables,
805 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
817 EFSYS_PROBE1(fail1, efx_rc_t, rc);
822 #endif /* EFSYS_OPT_DIAG */
824 #endif /* EFSYS_OPT_SIENA */