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