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