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