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