siena_nic.c revision 311765
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: stable/11/sys/dev/sfxge/common/siena_nic.c 311765 2017-01-09 08:07:18Z arybchik $");
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
42static	__checkReturn		efx_rc_t
43siena_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
75fail2:
76	EFSYS_PROBE(fail2);
77fail1:
78	EFSYS_PROBE1(fail1, efx_rc_t, rc);
79
80	return (rc);
81}
82
83#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
84
85static	__checkReturn	efx_rc_t
86siena_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	encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
142	/* Fragments must not span 4k boundaries. */
143	encp->enc_tx_dma_desc_boundary = 4096;
144
145	/* Resource limits */
146	rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
147	if (rc != 0) {
148		if (rc != ENOTSUP)
149			goto fail2;
150
151		nevq = 1024;
152		nrxq = EFX_RXQ_LIMIT_TARGET;
153		ntxq = EFX_TXQ_LIMIT_TARGET;
154	}
155	encp->enc_evq_limit = nevq;
156	encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
157	encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
158
159	encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
160	    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
161	    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
162
163	encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
164	encp->enc_fw_assisted_tso_enabled = B_FALSE;
165	encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
166	encp->enc_fw_assisted_tso_v2_n_contexts = 0;
167	encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
168
169	/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
170	encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
171	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
172
173	encp->enc_fw_verified_nvram_update_required = B_FALSE;
174
175	return (0);
176
177fail2:
178	EFSYS_PROBE(fail2);
179fail1:
180	EFSYS_PROBE1(fail1, efx_rc_t, rc);
181
182	return (rc);
183}
184
185static	__checkReturn	efx_rc_t
186siena_phy_cfg(
187	__in		efx_nic_t *enp)
188{
189	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
190	efx_rc_t rc;
191
192	/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
193	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
194		goto fail1;
195
196#if EFSYS_OPT_PHY_STATS
197	/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
198	siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
199			    NULL, &encp->enc_phy_stat_mask, NULL);
200#endif	/* EFSYS_OPT_PHY_STATS */
201
202	return (0);
203
204fail1:
205	EFSYS_PROBE1(fail1, efx_rc_t, rc);
206
207	return (rc);
208}
209
210	__checkReturn	efx_rc_t
211siena_nic_probe(
212	__in		efx_nic_t *enp)
213{
214	efx_port_t *epp = &(enp->en_port);
215	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
216	siena_link_state_t sls;
217	unsigned int mask;
218	efx_oword_t oword;
219	efx_rc_t rc;
220
221	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
222
223	/* Test BIU */
224	if ((rc = efx_nic_biu_test(enp)) != 0)
225		goto fail1;
226
227	/* Clear the region register */
228	EFX_POPULATE_OWORD_4(oword,
229	    FRF_AZ_ADR_REGION0, 0,
230	    FRF_AZ_ADR_REGION1, (1 << 16),
231	    FRF_AZ_ADR_REGION2, (2 << 16),
232	    FRF_AZ_ADR_REGION3, (3 << 16));
233	EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
234
235	/* Read clear any assertion state */
236	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
237		goto fail2;
238
239	/* Exit the assertion handler */
240	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
241		goto fail3;
242
243	/* Wrestle control from the BMC */
244	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
245		goto fail4;
246
247	if ((rc = siena_board_cfg(enp)) != 0)
248		goto fail5;
249
250	if ((rc = siena_phy_cfg(enp)) != 0)
251		goto fail6;
252
253	/* Obtain the default PHY advertised capabilities */
254	if ((rc = siena_nic_reset(enp)) != 0)
255		goto fail7;
256	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
257		goto fail8;
258	epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
259	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
260
261#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
262	if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
263		goto fail9;
264	enp->en_u.siena.enu_partn_mask = mask;
265#endif
266
267#if EFSYS_OPT_MAC_STATS
268	/* Wipe the MAC statistics */
269	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
270		goto fail10;
271#endif
272
273#if EFSYS_OPT_LOOPBACK
274	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
275		goto fail11;
276#endif
277
278#if EFSYS_OPT_MON_STATS
279	if ((rc = mcdi_mon_cfg_build(enp)) != 0)
280		goto fail12;
281#endif
282
283	encp->enc_features = enp->en_features;
284
285	return (0);
286
287#if EFSYS_OPT_MON_STATS
288fail12:
289	EFSYS_PROBE(fail12);
290#endif
291#if EFSYS_OPT_LOOPBACK
292fail11:
293	EFSYS_PROBE(fail11);
294#endif
295#if EFSYS_OPT_MAC_STATS
296fail10:
297	EFSYS_PROBE(fail10);
298#endif
299#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
300fail9:
301	EFSYS_PROBE(fail9);
302#endif
303fail8:
304	EFSYS_PROBE(fail8);
305fail7:
306	EFSYS_PROBE(fail7);
307fail6:
308	EFSYS_PROBE(fail6);
309fail5:
310	EFSYS_PROBE(fail5);
311fail4:
312	EFSYS_PROBE(fail4);
313fail3:
314	EFSYS_PROBE(fail3);
315fail2:
316	EFSYS_PROBE(fail2);
317fail1:
318	EFSYS_PROBE1(fail1, efx_rc_t, rc);
319
320	return (rc);
321}
322
323	__checkReturn	efx_rc_t
324siena_nic_reset(
325	__in		efx_nic_t *enp)
326{
327	efx_mcdi_req_t req;
328	efx_rc_t rc;
329
330	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
331
332	/* siena_nic_reset() is called to recover from BADASSERT failures. */
333	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
334		goto fail1;
335	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
336		goto fail2;
337
338	/*
339	 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
340	 * for backwards compatibility with PORT_RESET_IN_LEN.
341	 */
342	EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
343
344	req.emr_cmd = MC_CMD_ENTITY_RESET;
345	req.emr_in_buf = NULL;
346	req.emr_in_length = 0;
347	req.emr_out_buf = NULL;
348	req.emr_out_length = 0;
349
350	efx_mcdi_execute(enp, &req);
351
352	if (req.emr_rc != 0) {
353		rc = req.emr_rc;
354		goto fail3;
355	}
356
357	return (0);
358
359fail3:
360	EFSYS_PROBE(fail3);
361fail2:
362	EFSYS_PROBE(fail2);
363fail1:
364	EFSYS_PROBE1(fail1, efx_rc_t, rc);
365
366	return (0);
367}
368
369static			void
370siena_nic_rx_cfg(
371	__in		efx_nic_t *enp)
372{
373	efx_oword_t oword;
374
375	/*
376	 * RX_INGR_EN is always enabled on Siena, because we rely on
377	 * the RX parser to be resiliant to missing SOP/EOP.
378	 */
379	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
380	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
381	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
382
383	/* Disable parsing of additional 802.1Q in Q packets */
384	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
385	EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
386	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
387}
388
389static			void
390siena_nic_usrev_dis(
391	__in		efx_nic_t *enp)
392{
393	efx_oword_t	oword;
394
395	EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
396	EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
397}
398
399	__checkReturn	efx_rc_t
400siena_nic_init(
401	__in		efx_nic_t *enp)
402{
403	efx_rc_t rc;
404
405	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
406
407	/* Enable reporting of some events (e.g. link change) */
408	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
409		goto fail1;
410
411	siena_sram_init(enp);
412
413	/* Configure Siena's RX block */
414	siena_nic_rx_cfg(enp);
415
416	/* Disable USR_EVents for now */
417	siena_nic_usrev_dis(enp);
418
419	/* bug17057: Ensure set_link is called */
420	if ((rc = siena_phy_reconfigure(enp)) != 0)
421		goto fail2;
422
423	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
424
425	return (0);
426
427fail2:
428	EFSYS_PROBE(fail2);
429fail1:
430	EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432	return (rc);
433}
434
435			void
436siena_nic_fini(
437	__in		efx_nic_t *enp)
438{
439	_NOTE(ARGUNUSED(enp))
440}
441
442			void
443siena_nic_unprobe(
444	__in		efx_nic_t *enp)
445{
446#if EFSYS_OPT_MON_STATS
447	mcdi_mon_cfg_free(enp);
448#endif /* EFSYS_OPT_MON_STATS */
449	(void) efx_mcdi_drv_attach(enp, B_FALSE);
450}
451
452#if EFSYS_OPT_DIAG
453
454static efx_register_set_t __siena_registers[] = {
455	{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
456	{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
457	{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
458	{ FR_AZ_TX_CFG_REG_OFST, 0, 1 },
459	{ FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
460	{ FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
461	{ FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
462	{ FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
463	{ FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
464	{ FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
465	{ FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
466	{ FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
467	{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
468};
469
470static const uint32_t __siena_register_masks[] = {
471	0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
472	0x000103FF, 0x00000000, 0x00000000, 0x00000000,
473	0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
474	0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
475	0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
476	0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
477	0x00000003, 0x00000000, 0x00000000, 0x00000000,
478	0x000003FF, 0x00000000, 0x00000000, 0x00000000,
479	0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
480	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
481	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
482	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
483	0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
484};
485
486static efx_register_set_t __siena_tables[] = {
487	{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
488	    FR_AZ_RX_FILTER_TBL0_ROWS },
489	{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
490	    FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
491	{ FR_AZ_RX_DESC_PTR_TBL_OFST,
492	    FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
493	{ FR_AZ_TX_DESC_PTR_TBL_OFST,
494	    FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
495	{ FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
496	{ FR_CZ_TX_FILTER_TBL0_OFST,
497	    FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
498	{ FR_CZ_TX_MAC_FILTER_TBL0_OFST,
499	    FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
500};
501
502static const uint32_t __siena_table_masks[] = {
503	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
504	0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
505	0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
506	0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
507	0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
508	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
509	0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
510};
511
512	__checkReturn	efx_rc_t
513siena_nic_register_test(
514	__in		efx_nic_t *enp)
515{
516	efx_register_set_t *rsp;
517	const uint32_t *dwordp;
518	unsigned int nitems;
519	unsigned int count;
520	efx_rc_t rc;
521
522	/* Fill out the register mask entries */
523	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
524		    == EFX_ARRAY_SIZE(__siena_registers) * 4);
525
526	nitems = EFX_ARRAY_SIZE(__siena_registers);
527	dwordp = __siena_register_masks;
528	for (count = 0; count < nitems; ++count) {
529		rsp = __siena_registers + count;
530		rsp->mask.eo_u32[0] = *dwordp++;
531		rsp->mask.eo_u32[1] = *dwordp++;
532		rsp->mask.eo_u32[2] = *dwordp++;
533		rsp->mask.eo_u32[3] = *dwordp++;
534	}
535
536	/* Fill out the register table entries */
537	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
538		    == EFX_ARRAY_SIZE(__siena_tables) * 4);
539
540	nitems = EFX_ARRAY_SIZE(__siena_tables);
541	dwordp = __siena_table_masks;
542	for (count = 0; count < nitems; ++count) {
543		rsp = __siena_tables + count;
544		rsp->mask.eo_u32[0] = *dwordp++;
545		rsp->mask.eo_u32[1] = *dwordp++;
546		rsp->mask.eo_u32[2] = *dwordp++;
547		rsp->mask.eo_u32[3] = *dwordp++;
548	}
549
550	if ((rc = efx_nic_test_registers(enp, __siena_registers,
551	    EFX_ARRAY_SIZE(__siena_registers))) != 0)
552		goto fail1;
553
554	if ((rc = efx_nic_test_tables(enp, __siena_tables,
555	    EFX_PATTERN_BYTE_ALTERNATE,
556	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
557		goto fail2;
558
559	if ((rc = efx_nic_test_tables(enp, __siena_tables,
560	    EFX_PATTERN_BYTE_CHANGING,
561	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
562		goto fail3;
563
564	if ((rc = efx_nic_test_tables(enp, __siena_tables,
565	    EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
566		goto fail4;
567
568	return (0);
569
570fail4:
571	EFSYS_PROBE(fail4);
572fail3:
573	EFSYS_PROBE(fail3);
574fail2:
575	EFSYS_PROBE(fail2);
576fail1:
577	EFSYS_PROBE1(fail1, efx_rc_t, rc);
578
579	return (rc);
580}
581
582#endif	/* EFSYS_OPT_DIAG */
583
584#endif	/* EFSYS_OPT_SIENA */
585