]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/sfxge/common/siena_nic.c
MFC r299904
[FreeBSD/stable/10.git] / sys / dev / sfxge / common / siena_nic.c
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 */