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