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