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