common/sfc_efx/base: set NIC features in generic place
[dpdk.git] / drivers / common / sfc_efx / base / siena_nic.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 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         encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
139         /* Fragments must not span 4k boundaries. */
140         encp->enc_tx_dma_desc_boundary = 4096;
141
142         /* Resource limits */
143         rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
144         if (rc != 0) {
145                 if (rc != ENOTSUP)
146                         goto fail2;
147
148                 nevq = 1024;
149                 nrxq = EFX_RXQ_LIMIT_TARGET;
150                 ntxq = EFX_TXQ_LIMIT_TARGET;
151         }
152         encp->enc_evq_limit = nevq;
153         encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
154         encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
155
156         encp->enc_evq_max_nevs = SIENA_EVQ_MAXNEVS;
157         encp->enc_evq_min_nevs = SIENA_EVQ_MINNEVS;
158
159         encp->enc_rxq_max_ndescs = EF10_RXQ_MAXNDESCS;
160         encp->enc_rxq_min_ndescs = EF10_RXQ_MINNDESCS;
161
162         encp->enc_txq_max_ndescs = SIENA_TXQ_MAXNDESCS;
163         encp->enc_txq_min_ndescs = SIENA_TXQ_MINNDESCS;
164
165         encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
166             (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
167             (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
168
169         encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
170         encp->enc_fw_assisted_tso_enabled = B_FALSE;
171         encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
172         encp->enc_fw_assisted_tso_v2_n_contexts = 0;
173         encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
174         encp->enc_rx_packed_stream_supported = B_FALSE;
175         encp->enc_rx_var_packed_stream_supported = B_FALSE;
176         encp->enc_rx_es_super_buffer_supported = B_FALSE;
177         encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
178
179         /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
180         encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
181         encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
182
183         encp->enc_nvram_update_verify_result_supported = B_FALSE;
184
185         encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
186
187         encp->enc_filter_action_flag_supported = B_FALSE;
188         encp->enc_filter_action_mark_supported = B_FALSE;
189         encp->enc_filter_action_mark_max = 0;
190
191         return (0);
192
193 fail2:
194         EFSYS_PROBE(fail2);
195 fail1:
196         EFSYS_PROBE1(fail1, efx_rc_t, rc);
197
198         return (rc);
199 }
200
201 static  __checkReturn   efx_rc_t
202 siena_phy_cfg(
203         __in            efx_nic_t *enp)
204 {
205 #if EFSYS_OPT_PHY_STATS
206         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
207 #endif  /* EFSYS_OPT_PHY_STATS */
208         efx_rc_t rc;
209
210         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
211         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
212                 goto fail1;
213
214 #if EFSYS_OPT_PHY_STATS
215         /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
216         siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
217                             NULL, &encp->enc_phy_stat_mask, NULL);
218 #endif  /* EFSYS_OPT_PHY_STATS */
219
220         return (0);
221
222 fail1:
223         EFSYS_PROBE1(fail1, efx_rc_t, rc);
224
225         return (rc);
226 }
227
228 #define SIENA_BIU_MAGIC0        0x01234567
229 #define SIENA_BIU_MAGIC1        0xfedcba98
230
231 static  __checkReturn   efx_rc_t
232 siena_nic_biu_test(
233         __in            efx_nic_t *enp)
234 {
235         efx_oword_t oword;
236         efx_rc_t rc;
237
238         /*
239          * Write magic values to scratch registers 0 and 1, then
240          * verify that the values were written correctly.  Interleave
241          * the accesses to ensure that the BIU is not just reading
242          * back the cached value that was last written.
243          */
244         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
245         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
246
247         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
248         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
249
250         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
251         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
252                 rc = EIO;
253                 goto fail1;
254         }
255
256         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
257         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
258                 rc = EIO;
259                 goto fail2;
260         }
261
262         /*
263          * Perform the same test, with the values swapped.  This
264          * ensures that subsequent tests don't start with the correct
265          * values already written into the scratch registers.
266          */
267         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
268         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
269
270         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
271         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
272
273         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
274         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
275                 rc = EIO;
276                 goto fail3;
277         }
278
279         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
280         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
281                 rc = EIO;
282                 goto fail4;
283         }
284
285         return (0);
286
287 fail4:
288         EFSYS_PROBE(fail4);
289 fail3:
290         EFSYS_PROBE(fail3);
291 fail2:
292         EFSYS_PROBE(fail2);
293 fail1:
294         EFSYS_PROBE1(fail1, efx_rc_t, rc);
295
296         return (rc);
297 }
298
299         __checkReturn   efx_rc_t
300 siena_nic_probe(
301         __in            efx_nic_t *enp)
302 {
303         efx_port_t *epp = &(enp->en_port);
304         siena_link_state_t sls;
305         unsigned int mask;
306         efx_oword_t oword;
307         efx_rc_t rc;
308
309         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
310
311         /* Test BIU */
312         if ((rc = siena_nic_biu_test(enp)) != 0)
313                 goto fail1;
314
315         /* Clear the region register */
316         EFX_POPULATE_OWORD_4(oword,
317             FRF_AZ_ADR_REGION0, 0,
318             FRF_AZ_ADR_REGION1, (1 << 16),
319             FRF_AZ_ADR_REGION2, (2 << 16),
320             FRF_AZ_ADR_REGION3, (3 << 16));
321         EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
322
323         /* Read clear any assertion state */
324         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
325                 goto fail2;
326
327         /* Exit the assertion handler */
328         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
329                 goto fail3;
330
331         /* Wrestle control from the BMC */
332         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
333                 goto fail4;
334
335         if ((rc = siena_board_cfg(enp)) != 0)
336                 goto fail5;
337
338         if ((rc = siena_phy_cfg(enp)) != 0)
339                 goto fail6;
340
341         /* Obtain the default PHY advertised capabilities */
342         if ((rc = siena_nic_reset(enp)) != 0)
343                 goto fail7;
344         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
345                 goto fail8;
346         epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
347         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
348
349 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
350         if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
351                 goto fail9;
352         enp->en_u.siena.enu_partn_mask = mask;
353 #endif
354
355 #if EFSYS_OPT_MAC_STATS
356         /* Wipe the MAC statistics */
357         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
358                 goto fail10;
359 #endif
360
361 #if EFSYS_OPT_LOOPBACK
362         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
363                 goto fail11;
364 #endif
365
366 #if EFSYS_OPT_MON_STATS
367         if ((rc = mcdi_mon_cfg_build(enp)) != 0)
368                 goto fail12;
369 #endif
370
371         return (0);
372
373 #if EFSYS_OPT_MON_STATS
374 fail12:
375         EFSYS_PROBE(fail12);
376 #endif
377 #if EFSYS_OPT_LOOPBACK
378 fail11:
379         EFSYS_PROBE(fail11);
380 #endif
381 #if EFSYS_OPT_MAC_STATS
382 fail10:
383         EFSYS_PROBE(fail10);
384 #endif
385 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
386 fail9:
387         EFSYS_PROBE(fail9);
388 #endif
389 fail8:
390         EFSYS_PROBE(fail8);
391 fail7:
392         EFSYS_PROBE(fail7);
393 fail6:
394         EFSYS_PROBE(fail6);
395 fail5:
396         EFSYS_PROBE(fail5);
397 fail4:
398         EFSYS_PROBE(fail4);
399 fail3:
400         EFSYS_PROBE(fail3);
401 fail2:
402         EFSYS_PROBE(fail2);
403 fail1:
404         EFSYS_PROBE1(fail1, efx_rc_t, rc);
405
406         return (rc);
407 }
408
409         __checkReturn   efx_rc_t
410 siena_nic_reset(
411         __in            efx_nic_t *enp)
412 {
413         efx_mcdi_req_t req;
414         efx_rc_t rc;
415
416         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
417
418         /* siena_nic_reset() is called to recover from BADASSERT failures. */
419         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
420                 goto fail1;
421         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
422                 goto fail2;
423
424         /*
425          * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
426          * for backwards compatibility with PORT_RESET_IN_LEN.
427          */
428         EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
429
430         req.emr_cmd = MC_CMD_ENTITY_RESET;
431         req.emr_in_buf = NULL;
432         req.emr_in_length = 0;
433         req.emr_out_buf = NULL;
434         req.emr_out_length = 0;
435
436         efx_mcdi_execute(enp, &req);
437
438         if (req.emr_rc != 0) {
439                 rc = req.emr_rc;
440                 goto fail3;
441         }
442
443         return (0);
444
445 fail3:
446         EFSYS_PROBE(fail3);
447 fail2:
448         EFSYS_PROBE(fail2);
449 fail1:
450         EFSYS_PROBE1(fail1, efx_rc_t, rc);
451
452         return (0);
453 }
454
455 static                  void
456 siena_nic_rx_cfg(
457         __in            efx_nic_t *enp)
458 {
459         efx_oword_t oword;
460
461         /*
462          * RX_INGR_EN is always enabled on Siena, because we rely on
463          * the RX parser to be resiliant to missing SOP/EOP.
464          */
465         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
466         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
467         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
468
469         /* Disable parsing of additional 802.1Q in Q packets */
470         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
471         EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
472         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
473 }
474
475 static                  void
476 siena_nic_usrev_dis(
477         __in            efx_nic_t *enp)
478 {
479         efx_oword_t     oword;
480
481         EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
482         EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
483 }
484
485         __checkReturn   efx_rc_t
486 siena_nic_init(
487         __in            efx_nic_t *enp)
488 {
489         efx_rc_t rc;
490
491         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
492
493         /* Enable reporting of some events (e.g. link change) */
494         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
495                 goto fail1;
496
497         siena_sram_init(enp);
498
499         /* Configure Siena's RX block */
500         siena_nic_rx_cfg(enp);
501
502         /* Disable USR_EVents for now */
503         siena_nic_usrev_dis(enp);
504
505         /* bug17057: Ensure set_link is called */
506         if ((rc = siena_phy_reconfigure(enp)) != 0)
507                 goto fail2;
508
509         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
510
511         return (0);
512
513 fail2:
514         EFSYS_PROBE(fail2);
515 fail1:
516         EFSYS_PROBE1(fail1, efx_rc_t, rc);
517
518         return (rc);
519 }
520
521                         void
522 siena_nic_fini(
523         __in            efx_nic_t *enp)
524 {
525         _NOTE(ARGUNUSED(enp))
526 }
527
528                         void
529 siena_nic_unprobe(
530         __in            efx_nic_t *enp)
531 {
532 #if EFSYS_OPT_MON_STATS
533         mcdi_mon_cfg_free(enp);
534 #endif /* EFSYS_OPT_MON_STATS */
535         (void) efx_mcdi_drv_attach(enp, B_FALSE);
536 }
537
538 #if EFSYS_OPT_DIAG
539
540 static siena_register_set_t __siena_registers[] = {
541         { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
542         { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
543         { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
544         { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
545         { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
546         { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
547         { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
548         { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
549         { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
550         { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
551         { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
552         { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
553         { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
554 };
555
556 static const uint32_t __siena_register_masks[] = {
557         0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
558         0x000103FF, 0x00000000, 0x00000000, 0x00000000,
559         0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
560         0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
561         0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
562         0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
563         0x00000003, 0x00000000, 0x00000000, 0x00000000,
564         0x000003FF, 0x00000000, 0x00000000, 0x00000000,
565         0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
566         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
567         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
568         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
569         0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
570 };
571
572 static siena_register_set_t __siena_tables[] = {
573         { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
574             FR_AZ_RX_FILTER_TBL0_ROWS },
575         { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
576             FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
577         { FR_AZ_RX_DESC_PTR_TBL_OFST,
578             FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
579         { FR_AZ_TX_DESC_PTR_TBL_OFST,
580             FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
581         { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
582         { FR_CZ_TX_FILTER_TBL0_OFST,
583             FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
584         { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
585             FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
586 };
587
588 static const uint32_t __siena_table_masks[] = {
589         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
590         0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
591         0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
592         0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
593         0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
594         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
595         0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
596 };
597
598         __checkReturn   efx_rc_t
599 siena_nic_test_registers(
600         __in            efx_nic_t *enp,
601         __in            siena_register_set_t *rsp,
602         __in            size_t count)
603 {
604         unsigned int bit;
605         efx_oword_t original;
606         efx_oword_t reg;
607         efx_oword_t buf;
608         efx_rc_t rc;
609
610         while (count > 0) {
611                 /* This function is only suitable for registers */
612                 EFSYS_ASSERT(rsp->rows == 1);
613
614                 /* bit sweep on and off */
615                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
616                             B_TRUE);
617                 for (bit = 0; bit < 128; bit++) {
618                         /* Is this bit in the mask? */
619                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
620                                 continue;
621
622                         /* Test this bit can be set in isolation */
623                         reg = original;
624                         EFX_AND_OWORD(reg, rsp->mask);
625                         EFX_SET_OWORD_BIT(reg, bit);
626
627                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
628                                     B_TRUE);
629                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
630                                     B_TRUE);
631
632                         EFX_AND_OWORD(buf, rsp->mask);
633                         if (memcmp(&reg, &buf, sizeof (reg))) {
634                                 rc = EIO;
635                                 goto fail1;
636                         }
637
638                         /* Test this bit can be cleared in isolation */
639                         EFX_OR_OWORD(reg, rsp->mask);
640                         EFX_CLEAR_OWORD_BIT(reg, bit);
641
642                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
643                                     B_TRUE);
644                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
645                                     B_TRUE);
646
647                         EFX_AND_OWORD(buf, rsp->mask);
648                         if (memcmp(&reg, &buf, sizeof (reg))) {
649                                 rc = EIO;
650                                 goto fail2;
651                         }
652                 }
653
654                 /* Restore the old value */
655                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
656                             B_TRUE);
657
658                 --count;
659                 ++rsp;
660         }
661
662         return (0);
663
664 fail2:
665         EFSYS_PROBE(fail2);
666 fail1:
667         EFSYS_PROBE1(fail1, efx_rc_t, rc);
668
669         /* Restore the old value */
670         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
671
672         return (rc);
673 }
674
675         __checkReturn   efx_rc_t
676 siena_nic_test_tables(
677         __in            efx_nic_t *enp,
678         __in            siena_register_set_t *rsp,
679         __in            efx_pattern_type_t pattern,
680         __in            size_t count)
681 {
682         efx_sram_pattern_fn_t func;
683         unsigned int index;
684         unsigned int address;
685         efx_oword_t reg;
686         efx_oword_t buf;
687         efx_rc_t rc;
688
689         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
690         func = __efx_sram_pattern_fns[pattern];
691
692         while (count > 0) {
693                 /* Write */
694                 address = rsp->address;
695                 for (index = 0; index < rsp->rows; ++index) {
696                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
697                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
698                         EFX_AND_OWORD(reg, rsp->mask);
699                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
700
701                         address += rsp->step;
702                 }
703
704                 /* Read */
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_READO(enp->en_esbp, address, &buf, B_TRUE);
711                         if (memcmp(&reg, &buf, sizeof (reg))) {
712                                 rc = EIO;
713                                 goto fail1;
714                         }
715
716                         address += rsp->step;
717                 }
718
719                 ++rsp;
720                 --count;
721         }
722
723         return (0);
724
725 fail1:
726         EFSYS_PROBE1(fail1, efx_rc_t, rc);
727
728         return (rc);
729 }
730
731
732         __checkReturn   efx_rc_t
733 siena_nic_register_test(
734         __in            efx_nic_t *enp)
735 {
736         siena_register_set_t *rsp;
737         const uint32_t *dwordp;
738         unsigned int nitems;
739         unsigned int count;
740         efx_rc_t rc;
741
742         /* Fill out the register mask entries */
743         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
744                     == EFX_ARRAY_SIZE(__siena_registers) * 4);
745
746         nitems = EFX_ARRAY_SIZE(__siena_registers);
747         dwordp = __siena_register_masks;
748         for (count = 0; count < nitems; ++count) {
749                 rsp = __siena_registers + count;
750                 rsp->mask.eo_u32[0] = *dwordp++;
751                 rsp->mask.eo_u32[1] = *dwordp++;
752                 rsp->mask.eo_u32[2] = *dwordp++;
753                 rsp->mask.eo_u32[3] = *dwordp++;
754         }
755
756         /* Fill out the register table entries */
757         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
758                     == EFX_ARRAY_SIZE(__siena_tables) * 4);
759
760         nitems = EFX_ARRAY_SIZE(__siena_tables);
761         dwordp = __siena_table_masks;
762         for (count = 0; count < nitems; ++count) {
763                 rsp = __siena_tables + count;
764                 rsp->mask.eo_u32[0] = *dwordp++;
765                 rsp->mask.eo_u32[1] = *dwordp++;
766                 rsp->mask.eo_u32[2] = *dwordp++;
767                 rsp->mask.eo_u32[3] = *dwordp++;
768         }
769
770         if ((rc = siena_nic_test_registers(enp, __siena_registers,
771             EFX_ARRAY_SIZE(__siena_registers))) != 0)
772                 goto fail1;
773
774         if ((rc = siena_nic_test_tables(enp, __siena_tables,
775             EFX_PATTERN_BYTE_ALTERNATE,
776             EFX_ARRAY_SIZE(__siena_tables))) != 0)
777                 goto fail2;
778
779         if ((rc = siena_nic_test_tables(enp, __siena_tables,
780             EFX_PATTERN_BYTE_CHANGING,
781             EFX_ARRAY_SIZE(__siena_tables))) != 0)
782                 goto fail3;
783
784         if ((rc = siena_nic_test_tables(enp, __siena_tables,
785             EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
786                 goto fail4;
787
788         return (0);
789
790 fail4:
791         EFSYS_PROBE(fail4);
792 fail3:
793         EFSYS_PROBE(fail3);
794 fail2:
795         EFSYS_PROBE(fail2);
796 fail1:
797         EFSYS_PROBE1(fail1, efx_rc_t, rc);
798
799         return (rc);
800 }
801
802 #endif  /* EFSYS_OPT_DIAG */
803
804 #endif  /* EFSYS_OPT_SIENA */