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