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