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