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