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