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