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