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