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