]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/common/siena_nic.c
Merge lld trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / common / siena_nic.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2009-2016 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * The views and conclusions contained in the software and documentation are
29  * those of the authors and should not be interpreted as representing official
30  * policies, either expressed or implied, of the FreeBSD Project.
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include "efx.h"
37 #include "efx_impl.h"
38 #include "mcdi_mon.h"
39
40 #if EFSYS_OPT_SIENA
41
42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
43
44 static  __checkReturn           efx_rc_t
45 siena_nic_get_partn_mask(
46         __in                    efx_nic_t *enp,
47         __out                   unsigned int *maskp)
48 {
49         efx_mcdi_req_t req;
50         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
51                 MC_CMD_NVRAM_TYPES_OUT_LEN);
52         efx_rc_t rc;
53
54         req.emr_cmd = MC_CMD_NVRAM_TYPES;
55         req.emr_in_buf = payload;
56         req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
57         req.emr_out_buf = payload;
58         req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
59
60         efx_mcdi_execute(enp, &req);
61
62         if (req.emr_rc != 0) {
63                 rc = req.emr_rc;
64                 goto fail1;
65         }
66
67         if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
68                 rc = EMSGSIZE;
69                 goto fail2;
70         }
71
72         *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
73
74         return (0);
75
76 fail2:
77         EFSYS_PROBE(fail2);
78 fail1:
79         EFSYS_PROBE1(fail1, efx_rc_t, rc);
80
81         return (rc);
82 }
83
84 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
85
86 static  __checkReturn   efx_rc_t
87 siena_board_cfg(
88         __in            efx_nic_t *enp)
89 {
90         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
91         uint8_t mac_addr[6];
92         efx_dword_t capabilities;
93         uint32_t board_type;
94         uint32_t nevq, nrxq, ntxq;
95         efx_rc_t rc;
96
97         /* Siena has a fixed 8Kbyte VI window size */
98         EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K  == 8192);
99         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
100
101         /* External port identifier using one-based port numbering */
102         encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
103
104         /* Board configuration */
105         if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
106                     &capabilities, mac_addr)) != 0)
107                 goto fail1;
108
109         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
110
111         encp->enc_board_type = board_type;
112
113         /*
114          * There is no possibility to determine the number of PFs on Siena
115          * by issuing MCDI request, and it is not an easy task to find the
116          * value based on the board type, so 'enc_hw_pf_count' is set to 1
117          */
118         encp->enc_hw_pf_count = 1;
119
120         /* Additional capabilities */
121         encp->enc_clk_mult = 1;
122         if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
123                 enp->en_features |= EFX_FEATURE_TURBO;
124
125                 if (EFX_DWORD_FIELD(capabilities,
126                         MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
127                         encp->enc_clk_mult = 2;
128                 }
129         }
130
131         encp->enc_evq_timer_quantum_ns =
132                 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
133         encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
134                 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
135
136         /* When hash header insertion is enabled, Siena inserts 16 bytes */
137         encp->enc_rx_prefix_size = 16;
138
139         /* Alignment for receive packet DMA buffers */
140         encp->enc_rx_buf_align_start = 1;
141         encp->enc_rx_buf_align_end = 1;
142
143         /* Alignment for WPTR updates */
144         encp->enc_rx_push_align = 1;
145
146 #if EFSYS_OPT_RX_SCALE
147         /* There is one RSS context per function */
148         encp->enc_rx_scale_max_exclusive_contexts = 1;
149
150         encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
151         encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
152
153         /*
154          * It is always possible to use port numbers
155          * as the input data for hash computation.
156          */
157         encp->enc_rx_scale_l4_hash_supported = B_TRUE;
158
159         /* There is no support for additional RSS modes */
160         encp->enc_rx_scale_additional_modes_supported = B_FALSE;
161 #endif /* EFSYS_OPT_RX_SCALE */
162
163         encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
164         /* Fragments must not span 4k boundaries. */
165         encp->enc_tx_dma_desc_boundary = 4096;
166
167         /* Resource limits */
168         rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
169         if (rc != 0) {
170                 if (rc != ENOTSUP)
171                         goto fail2;
172
173                 nevq = 1024;
174                 nrxq = EFX_RXQ_LIMIT_TARGET;
175                 ntxq = EFX_TXQ_LIMIT_TARGET;
176         }
177         encp->enc_evq_limit = nevq;
178         encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
179         encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
180
181         encp->enc_txq_max_ndescs = 4096;
182
183         encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
184             (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
185             (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
186
187         encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
188         encp->enc_fw_assisted_tso_enabled = B_FALSE;
189         encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
190         encp->enc_fw_assisted_tso_v2_n_contexts = 0;
191         encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
192         encp->enc_rx_packed_stream_supported = B_FALSE;
193         encp->enc_rx_var_packed_stream_supported = B_FALSE;
194         encp->enc_rx_es_super_buffer_supported = B_FALSE;
195         encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
196
197         /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
198         encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
199         encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
200
201         encp->enc_nvram_update_verify_result_supported = B_FALSE;
202
203         encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
204
205         encp->enc_filter_action_flag_supported = B_FALSE;
206         encp->enc_filter_action_mark_supported = B_FALSE;
207         encp->enc_filter_action_mark_max = 0;
208
209         return (0);
210
211 fail2:
212         EFSYS_PROBE(fail2);
213 fail1:
214         EFSYS_PROBE1(fail1, efx_rc_t, rc);
215
216         return (rc);
217 }
218
219 static  __checkReturn   efx_rc_t
220 siena_phy_cfg(
221         __in            efx_nic_t *enp)
222 {
223 #if EFSYS_OPT_PHY_STATS
224         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
225 #endif  /* EFSYS_OPT_PHY_STATS */
226         efx_rc_t rc;
227
228         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
229         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
230                 goto fail1;
231
232 #if EFSYS_OPT_PHY_STATS
233         /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
234         siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
235                             NULL, &encp->enc_phy_stat_mask, NULL);
236 #endif  /* EFSYS_OPT_PHY_STATS */
237
238         return (0);
239
240 fail1:
241         EFSYS_PROBE1(fail1, efx_rc_t, rc);
242
243         return (rc);
244 }
245
246 #define SIENA_BIU_MAGIC0        0x01234567
247 #define SIENA_BIU_MAGIC1        0xfedcba98
248
249 static  __checkReturn   efx_rc_t
250 siena_nic_biu_test(
251         __in            efx_nic_t *enp)
252 {
253         efx_oword_t oword;
254         efx_rc_t rc;
255
256         /*
257          * Write magic values to scratch registers 0 and 1, then
258          * verify that the values were written correctly.  Interleave
259          * the accesses to ensure that the BIU is not just reading
260          * back the cached value that was last written.
261          */
262         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
263         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
264
265         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
266         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
267
268         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
269         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
270                 rc = EIO;
271                 goto fail1;
272         }
273
274         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
275         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
276                 rc = EIO;
277                 goto fail2;
278         }
279
280         /*
281          * Perform the same test, with the values swapped.  This
282          * ensures that subsequent tests don't start with the correct
283          * values already written into the scratch registers.
284          */
285         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
286         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
287
288         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
289         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
290
291         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
292         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
293                 rc = EIO;
294                 goto fail3;
295         }
296
297         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
298         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
299                 rc = EIO;
300                 goto fail4;
301         }
302
303         return (0);
304
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_probe(
319         __in            efx_nic_t *enp)
320 {
321         efx_port_t *epp = &(enp->en_port);
322         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
323         siena_link_state_t sls;
324         unsigned int mask;
325         efx_oword_t oword;
326         efx_rc_t rc;
327
328         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
329
330         /* Test BIU */
331         if ((rc = siena_nic_biu_test(enp)) != 0)
332                 goto fail1;
333
334         /* Clear the region register */
335         EFX_POPULATE_OWORD_4(oword,
336             FRF_AZ_ADR_REGION0, 0,
337             FRF_AZ_ADR_REGION1, (1 << 16),
338             FRF_AZ_ADR_REGION2, (2 << 16),
339             FRF_AZ_ADR_REGION3, (3 << 16));
340         EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
341
342         /* Read clear any assertion state */
343         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
344                 goto fail2;
345
346         /* Exit the assertion handler */
347         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
348                 goto fail3;
349
350         /* Wrestle control from the BMC */
351         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
352                 goto fail4;
353
354         if ((rc = siena_board_cfg(enp)) != 0)
355                 goto fail5;
356
357         if ((rc = siena_phy_cfg(enp)) != 0)
358                 goto fail6;
359
360         /* Obtain the default PHY advertised capabilities */
361         if ((rc = siena_nic_reset(enp)) != 0)
362                 goto fail7;
363         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
364                 goto fail8;
365         epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
366         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
367
368 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
369         if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
370                 goto fail9;
371         enp->en_u.siena.enu_partn_mask = mask;
372 #endif
373
374 #if EFSYS_OPT_MAC_STATS
375         /* Wipe the MAC statistics */
376         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
377                 goto fail10;
378 #endif
379
380 #if EFSYS_OPT_LOOPBACK
381         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
382                 goto fail11;
383 #endif
384
385 #if EFSYS_OPT_MON_STATS
386         if ((rc = mcdi_mon_cfg_build(enp)) != 0)
387                 goto fail12;
388 #endif
389
390         encp->enc_features = enp->en_features;
391
392         return (0);
393
394 #if EFSYS_OPT_MON_STATS
395 fail12:
396         EFSYS_PROBE(fail12);
397 #endif
398 #if EFSYS_OPT_LOOPBACK
399 fail11:
400         EFSYS_PROBE(fail11);
401 #endif
402 #if EFSYS_OPT_MAC_STATS
403 fail10:
404         EFSYS_PROBE(fail10);
405 #endif
406 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
407 fail9:
408         EFSYS_PROBE(fail9);
409 #endif
410 fail8:
411         EFSYS_PROBE(fail8);
412 fail7:
413         EFSYS_PROBE(fail7);
414 fail6:
415         EFSYS_PROBE(fail6);
416 fail5:
417         EFSYS_PROBE(fail5);
418 fail4:
419         EFSYS_PROBE(fail4);
420 fail3:
421         EFSYS_PROBE(fail3);
422 fail2:
423         EFSYS_PROBE(fail2);
424 fail1:
425         EFSYS_PROBE1(fail1, efx_rc_t, rc);
426
427         return (rc);
428 }
429
430         __checkReturn   efx_rc_t
431 siena_nic_reset(
432         __in            efx_nic_t *enp)
433 {
434         efx_mcdi_req_t req;
435         efx_rc_t rc;
436
437         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
438
439         /* siena_nic_reset() is called to recover from BADASSERT failures. */
440         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
441                 goto fail1;
442         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
443                 goto fail2;
444
445         /*
446          * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
447          * for backwards compatibility with PORT_RESET_IN_LEN.
448          */
449         EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
450
451         req.emr_cmd = MC_CMD_ENTITY_RESET;
452         req.emr_in_buf = NULL;
453         req.emr_in_length = 0;
454         req.emr_out_buf = NULL;
455         req.emr_out_length = 0;
456
457         efx_mcdi_execute(enp, &req);
458
459         if (req.emr_rc != 0) {
460                 rc = req.emr_rc;
461                 goto fail3;
462         }
463
464         return (0);
465
466 fail3:
467         EFSYS_PROBE(fail3);
468 fail2:
469         EFSYS_PROBE(fail2);
470 fail1:
471         EFSYS_PROBE1(fail1, efx_rc_t, rc);
472
473         return (0);
474 }
475
476 static                  void
477 siena_nic_rx_cfg(
478         __in            efx_nic_t *enp)
479 {
480         efx_oword_t oword;
481
482         /*
483          * RX_INGR_EN is always enabled on Siena, because we rely on
484          * the RX parser to be resiliant to missing SOP/EOP.
485          */
486         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
487         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
488         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
489
490         /* Disable parsing of additional 802.1Q in Q packets */
491         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
492         EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
493         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
494 }
495
496 static                  void
497 siena_nic_usrev_dis(
498         __in            efx_nic_t *enp)
499 {
500         efx_oword_t     oword;
501
502         EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
503         EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
504 }
505
506         __checkReturn   efx_rc_t
507 siena_nic_init(
508         __in            efx_nic_t *enp)
509 {
510         efx_rc_t rc;
511
512         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
513
514         /* Enable reporting of some events (e.g. link change) */
515         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
516                 goto fail1;
517
518         siena_sram_init(enp);
519
520         /* Configure Siena's RX block */
521         siena_nic_rx_cfg(enp);
522
523         /* Disable USR_EVents for now */
524         siena_nic_usrev_dis(enp);
525
526         /* bug17057: Ensure set_link is called */
527         if ((rc = siena_phy_reconfigure(enp)) != 0)
528                 goto fail2;
529
530         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
531
532         return (0);
533
534 fail2:
535         EFSYS_PROBE(fail2);
536 fail1:
537         EFSYS_PROBE1(fail1, efx_rc_t, rc);
538
539         return (rc);
540 }
541
542                         void
543 siena_nic_fini(
544         __in            efx_nic_t *enp)
545 {
546         _NOTE(ARGUNUSED(enp))
547 }
548
549                         void
550 siena_nic_unprobe(
551         __in            efx_nic_t *enp)
552 {
553 #if EFSYS_OPT_MON_STATS
554         mcdi_mon_cfg_free(enp);
555 #endif /* EFSYS_OPT_MON_STATS */
556         (void) efx_mcdi_drv_attach(enp, B_FALSE);
557 }
558
559 #if EFSYS_OPT_DIAG
560
561 static siena_register_set_t __siena_registers[] = {
562         { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
563         { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
564         { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
565         { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
566         { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
567         { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
568         { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
569         { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
570         { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
571         { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
572         { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
573         { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
574         { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
575 };
576
577 static const uint32_t __siena_register_masks[] = {
578         0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
579         0x000103FF, 0x00000000, 0x00000000, 0x00000000,
580         0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
581         0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
582         0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
583         0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
584         0x00000003, 0x00000000, 0x00000000, 0x00000000,
585         0x000003FF, 0x00000000, 0x00000000, 0x00000000,
586         0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
587         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
588         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
589         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
590         0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
591 };
592
593 static siena_register_set_t __siena_tables[] = {
594         { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
595             FR_AZ_RX_FILTER_TBL0_ROWS },
596         { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
597             FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
598         { FR_AZ_RX_DESC_PTR_TBL_OFST,
599             FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
600         { FR_AZ_TX_DESC_PTR_TBL_OFST,
601             FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
602         { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
603         { FR_CZ_TX_FILTER_TBL0_OFST,
604             FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
605         { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
606             FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
607 };
608
609 static const uint32_t __siena_table_masks[] = {
610         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
611         0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
612         0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
613         0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
614         0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
615         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
616         0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
617 };
618
619         __checkReturn   efx_rc_t
620 siena_nic_test_registers(
621         __in            efx_nic_t *enp,
622         __in            siena_register_set_t *rsp,
623         __in            size_t count)
624 {
625         unsigned int bit;
626         efx_oword_t original;
627         efx_oword_t reg;
628         efx_oword_t buf;
629         efx_rc_t rc;
630
631         while (count > 0) {
632                 /* This function is only suitable for registers */
633                 EFSYS_ASSERT(rsp->rows == 1);
634
635                 /* bit sweep on and off */
636                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
637                             B_TRUE);
638                 for (bit = 0; bit < 128; bit++) {
639                         /* Is this bit in the mask? */
640                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
641                                 continue;
642
643                         /* Test this bit can be set in isolation */
644                         reg = original;
645                         EFX_AND_OWORD(reg, rsp->mask);
646                         EFX_SET_OWORD_BIT(reg, bit);
647
648                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
649                                     B_TRUE);
650                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
651                                     B_TRUE);
652
653                         EFX_AND_OWORD(buf, rsp->mask);
654                         if (memcmp(&reg, &buf, sizeof (reg))) {
655                                 rc = EIO;
656                                 goto fail1;
657                         }
658
659                         /* Test this bit can be cleared in isolation */
660                         EFX_OR_OWORD(reg, rsp->mask);
661                         EFX_CLEAR_OWORD_BIT(reg, bit);
662
663                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
664                                     B_TRUE);
665                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
666                                     B_TRUE);
667
668                         EFX_AND_OWORD(buf, rsp->mask);
669                         if (memcmp(&reg, &buf, sizeof (reg))) {
670                                 rc = EIO;
671                                 goto fail2;
672                         }
673                 }
674
675                 /* Restore the old value */
676                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
677                             B_TRUE);
678
679                 --count;
680                 ++rsp;
681         }
682
683         return (0);
684
685 fail2:
686         EFSYS_PROBE(fail2);
687 fail1:
688         EFSYS_PROBE1(fail1, efx_rc_t, rc);
689
690         /* Restore the old value */
691         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
692
693         return (rc);
694 }
695
696         __checkReturn   efx_rc_t
697 siena_nic_test_tables(
698         __in            efx_nic_t *enp,
699         __in            siena_register_set_t *rsp,
700         __in            efx_pattern_type_t pattern,
701         __in            size_t count)
702 {
703         efx_sram_pattern_fn_t func;
704         unsigned int index;
705         unsigned int address;
706         efx_oword_t reg;
707         efx_oword_t buf;
708         efx_rc_t rc;
709
710         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
711         func = __efx_sram_pattern_fns[pattern];
712
713         while (count > 0) {
714                 /* Write */
715                 address = rsp->address;
716                 for (index = 0; index < rsp->rows; ++index) {
717                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
718                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
719                         EFX_AND_OWORD(reg, rsp->mask);
720                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
721
722                         address += rsp->step;
723                 }
724
725                 /* Read */
726                 address = rsp->address;
727                 for (index = 0; index < rsp->rows; ++index) {
728                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
729                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
730                         EFX_AND_OWORD(reg, rsp->mask);
731                         EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
732                         if (memcmp(&reg, &buf, sizeof (reg))) {
733                                 rc = EIO;
734                                 goto fail1;
735                         }
736
737                         address += rsp->step;
738                 }
739
740                 ++rsp;
741                 --count;
742         }
743
744         return (0);
745
746 fail1:
747         EFSYS_PROBE1(fail1, efx_rc_t, rc);
748
749         return (rc);
750 }
751
752
753         __checkReturn   efx_rc_t
754 siena_nic_register_test(
755         __in            efx_nic_t *enp)
756 {
757         siena_register_set_t *rsp;
758         const uint32_t *dwordp;
759         unsigned int nitems;
760         unsigned int count;
761         efx_rc_t rc;
762
763         /* Fill out the register mask entries */
764         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
765                     == EFX_ARRAY_SIZE(__siena_registers) * 4);
766
767         nitems = EFX_ARRAY_SIZE(__siena_registers);
768         dwordp = __siena_register_masks;
769         for (count = 0; count < nitems; ++count) {
770                 rsp = __siena_registers + count;
771                 rsp->mask.eo_u32[0] = *dwordp++;
772                 rsp->mask.eo_u32[1] = *dwordp++;
773                 rsp->mask.eo_u32[2] = *dwordp++;
774                 rsp->mask.eo_u32[3] = *dwordp++;
775         }
776
777         /* Fill out the register table entries */
778         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
779                     == EFX_ARRAY_SIZE(__siena_tables) * 4);
780
781         nitems = EFX_ARRAY_SIZE(__siena_tables);
782         dwordp = __siena_table_masks;
783         for (count = 0; count < nitems; ++count) {
784                 rsp = __siena_tables + count;
785                 rsp->mask.eo_u32[0] = *dwordp++;
786                 rsp->mask.eo_u32[1] = *dwordp++;
787                 rsp->mask.eo_u32[2] = *dwordp++;
788                 rsp->mask.eo_u32[3] = *dwordp++;
789         }
790
791         if ((rc = siena_nic_test_registers(enp, __siena_registers,
792             EFX_ARRAY_SIZE(__siena_registers))) != 0)
793                 goto fail1;
794
795         if ((rc = siena_nic_test_tables(enp, __siena_tables,
796             EFX_PATTERN_BYTE_ALTERNATE,
797             EFX_ARRAY_SIZE(__siena_tables))) != 0)
798                 goto fail2;
799
800         if ((rc = siena_nic_test_tables(enp, __siena_tables,
801             EFX_PATTERN_BYTE_CHANGING,
802             EFX_ARRAY_SIZE(__siena_tables))) != 0)
803                 goto fail3;
804
805         if ((rc = siena_nic_test_tables(enp, __siena_tables,
806             EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
807                 goto fail4;
808
809         return (0);
810
811 fail4:
812         EFSYS_PROBE(fail4);
813 fail3:
814         EFSYS_PROBE(fail3);
815 fail2:
816         EFSYS_PROBE(fail2);
817 fail1:
818         EFSYS_PROBE1(fail1, efx_rc_t, rc);
819
820         return (rc);
821 }
822
823 #endif  /* EFSYS_OPT_DIAG */
824
825 #endif  /* EFSYS_OPT_SIENA */