]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/sfxge/common/siena_nic.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.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 #if EFSYS_OPT_PCIE_TUNE
82
83         __checkReturn   efx_rc_t
84 siena_nic_pcie_extended_sync(
85         __in            efx_nic_t *enp)
86 {
87         efx_rc_t rc;
88
89         if ((rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG17230,
90                     B_TRUE, NULL) != 0))
91                 goto fail1;
92
93         return (0);
94
95 fail1:
96         EFSYS_PROBE1(fail1, efx_rc_t, rc);
97
98         return (rc);
99 }
100
101 #endif  /* EFSYS_OPT_PCIE_TUNE */
102
103 static  __checkReturn   efx_rc_t
104 siena_board_cfg(
105         __in            efx_nic_t *enp)
106 {
107         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
108         uint8_t mac_addr[6];
109         efx_dword_t capabilities;
110         uint32_t board_type;
111         uint32_t nevq, nrxq, ntxq;
112         efx_rc_t rc;
113
114         /* External port identifier using one-based port numbering */
115         encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
116
117         /* Board configuration */
118         if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
119                     &capabilities, mac_addr)) != 0)
120                 goto fail1;
121
122         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
123
124         encp->enc_board_type = board_type;
125
126         /* Additional capabilities */
127         encp->enc_clk_mult = 1;
128         if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
129                 enp->en_features |= EFX_FEATURE_TURBO;
130
131                 if (EFX_DWORD_FIELD(capabilities,
132                         MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
133                         encp->enc_clk_mult = 2;
134                 }
135         }
136
137         encp->enc_evq_timer_quantum_ns =
138                 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
139         encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
140                 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
141
142         /* When hash header insertion is enabled, Siena inserts 16 bytes */
143         encp->enc_rx_prefix_size = 16;
144
145         /* Alignment for receive packet DMA buffers */
146         encp->enc_rx_buf_align_start = 1;
147         encp->enc_rx_buf_align_end = 1;
148
149         /* Alignment for WPTR updates */
150         encp->enc_rx_push_align = 1;
151
152         /* Resource limits */
153         rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
154         if (rc != 0) {
155                 if (rc != ENOTSUP)
156                         goto fail2;
157
158                 nevq = 1024;
159                 nrxq = EFX_RXQ_LIMIT_TARGET;
160                 ntxq = EFX_TXQ_LIMIT_TARGET;
161         }
162         encp->enc_evq_limit = nevq;
163         encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
164         encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
165
166         encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
167             (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
168             (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
169
170         encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
171         encp->enc_fw_assisted_tso_enabled = B_FALSE;
172         encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
173         encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
174
175         return (0);
176
177 fail2:
178         EFSYS_PROBE(fail2);
179 fail1:
180         EFSYS_PROBE1(fail1, efx_rc_t, rc);
181
182         return (rc);
183 }
184
185 static  __checkReturn   efx_rc_t
186 siena_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
204 fail1:
205         EFSYS_PROBE1(fail1, efx_rc_t, rc);
206
207         return (rc);
208 }
209
210         __checkReturn   efx_rc_t
211 siena_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
288 fail12:
289         EFSYS_PROBE(fail12);
290 #endif
291 #if EFSYS_OPT_LOOPBACK
292 fail11:
293         EFSYS_PROBE(fail11);
294 #endif
295 #if EFSYS_OPT_MAC_STATS
296 fail10:
297         EFSYS_PROBE(fail10);
298 #endif
299 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
300 fail9:
301         EFSYS_PROBE(fail9);
302 #endif
303 fail8:
304         EFSYS_PROBE(fail8);
305 fail7:
306         EFSYS_PROBE(fail7);
307 fail6:
308         EFSYS_PROBE(fail6);
309 fail5:
310         EFSYS_PROBE(fail5);
311 fail4:
312         EFSYS_PROBE(fail4);
313 fail3:
314         EFSYS_PROBE(fail3);
315 fail2:
316         EFSYS_PROBE(fail2);
317 fail1:
318         EFSYS_PROBE1(fail1, efx_rc_t, rc);
319
320         return (rc);
321 }
322
323         __checkReturn   efx_rc_t
324 siena_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
359 fail3:
360         EFSYS_PROBE(fail3);
361 fail2:
362         EFSYS_PROBE(fail2);
363 fail1:
364         EFSYS_PROBE1(fail1, efx_rc_t, rc);
365
366         return (0);
367 }
368
369 static                  void
370 siena_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
389 static                  void
390 siena_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
400 siena_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
427 fail2:
428         EFSYS_PROBE(fail2);
429 fail1:
430         EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432         return (rc);
433 }
434
435                         void
436 siena_nic_fini(
437         __in            efx_nic_t *enp)
438 {
439         _NOTE(ARGUNUSED(enp))
440 }
441
442                         void
443 siena_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
454 static 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
470 static 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
486 static 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
502 static 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
513 siena_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
570 fail4:
571         EFSYS_PROBE(fail4);
572 fail3:
573         EFSYS_PROBE(fail3);
574 fail2:
575         EFSYS_PROBE(fail2);
576 fail1:
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 */