]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/sfxge/common/siena_nic.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 "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 */