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