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