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