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