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