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