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