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