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