xref: /freebsd/sys/dev/sfxge/common/siena_nic.c (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009-2016 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * The views and conclusions contained in the software and documentation are
29  * those of the authors and should not be interpreted as representing official
30  * policies, either expressed or implied, of the FreeBSD Project.
31  */
32 
33 #include <sys/cdefs.h>
34 #include "efx.h"
35 #include "efx_impl.h"
36 #include "mcdi_mon.h"
37 
38 #if EFSYS_OPT_SIENA
39 
40 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
41 
42 static	__checkReturn		efx_rc_t
43 siena_nic_get_partn_mask(
44 	__in			efx_nic_t *enp,
45 	__out			unsigned int *maskp)
46 {
47 	efx_mcdi_req_t req;
48 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
49 		MC_CMD_NVRAM_TYPES_OUT_LEN);
50 	efx_rc_t rc;
51 
52 	req.emr_cmd = MC_CMD_NVRAM_TYPES;
53 	req.emr_in_buf = payload;
54 	req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
55 	req.emr_out_buf = payload;
56 	req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
57 
58 	efx_mcdi_execute(enp, &req);
59 
60 	if (req.emr_rc != 0) {
61 		rc = req.emr_rc;
62 		goto fail1;
63 	}
64 
65 	if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
66 		rc = EMSGSIZE;
67 		goto fail2;
68 	}
69 
70 	*maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
71 
72 	return (0);
73 
74 fail2:
75 	EFSYS_PROBE(fail2);
76 fail1:
77 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
78 
79 	return (rc);
80 }
81 
82 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
83 
84 static	__checkReturn	efx_rc_t
85 siena_board_cfg(
86 	__in		efx_nic_t *enp)
87 {
88 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
89 	uint8_t mac_addr[6];
90 	efx_dword_t capabilities;
91 	uint32_t board_type;
92 	uint32_t nevq, nrxq, ntxq;
93 	efx_rc_t rc;
94 
95 	/* Siena has a fixed 8Kbyte VI window size */
96 	EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K	== 8192);
97 	encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
98 
99 	/* External port identifier using one-based port numbering */
100 	encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
101 
102 	/* Board configuration */
103 	if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
104 		    &capabilities, mac_addr)) != 0)
105 		goto fail1;
106 
107 	EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
108 
109 	encp->enc_board_type = board_type;
110 
111 	/*
112 	 * There is no possibility to determine the number of PFs on Siena
113 	 * by issuing MCDI request, and it is not an easy task to find the
114 	 * value based on the board type, so 'enc_hw_pf_count' is set to 1
115 	 */
116 	encp->enc_hw_pf_count = 1;
117 
118 	/* Additional capabilities */
119 	encp->enc_clk_mult = 1;
120 	if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
121 		enp->en_features |= EFX_FEATURE_TURBO;
122 
123 		if (EFX_DWORD_FIELD(capabilities,
124 			MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
125 			encp->enc_clk_mult = 2;
126 		}
127 	}
128 
129 	encp->enc_evq_timer_quantum_ns =
130 		EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
131 	encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
132 		FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
133 
134 	/* When hash header insertion is enabled, Siena inserts 16 bytes */
135 	encp->enc_rx_prefix_size = 16;
136 
137 	/* Alignment for receive packet DMA buffers */
138 	encp->enc_rx_buf_align_start = 1;
139 	encp->enc_rx_buf_align_end = 1;
140 
141 	/* Alignment for WPTR updates */
142 	encp->enc_rx_push_align = 1;
143 
144 #if EFSYS_OPT_RX_SCALE
145 	/* There is one RSS context per function */
146 	encp->enc_rx_scale_max_exclusive_contexts = 1;
147 
148 	encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
149 	encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
150 
151 	/*
152 	 * It is always possible to use port numbers
153 	 * as the input data for hash computation.
154 	 */
155 	encp->enc_rx_scale_l4_hash_supported = B_TRUE;
156 
157 	/* There is no support for additional RSS modes */
158 	encp->enc_rx_scale_additional_modes_supported = B_FALSE;
159 #endif /* EFSYS_OPT_RX_SCALE */
160 
161 	encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
162 	/* Fragments must not span 4k boundaries. */
163 	encp->enc_tx_dma_desc_boundary = 4096;
164 
165 	/* Resource limits */
166 	rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
167 	if (rc != 0) {
168 		if (rc != ENOTSUP)
169 			goto fail2;
170 
171 		nevq = 1024;
172 		nrxq = EFX_RXQ_LIMIT_TARGET;
173 		ntxq = EFX_TXQ_LIMIT_TARGET;
174 	}
175 	encp->enc_evq_limit = nevq;
176 	encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
177 	encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
178 
179 	encp->enc_txq_max_ndescs = 4096;
180 
181 	encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
182 	    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
183 	    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
184 
185 	encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
186 	encp->enc_fw_assisted_tso_enabled = B_FALSE;
187 	encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
188 	encp->enc_fw_assisted_tso_v2_n_contexts = 0;
189 	encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
190 	encp->enc_rx_packed_stream_supported = B_FALSE;
191 	encp->enc_rx_var_packed_stream_supported = B_FALSE;
192 	encp->enc_rx_es_super_buffer_supported = B_FALSE;
193 	encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
194 
195 	/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
196 	encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
197 	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
198 
199 	encp->enc_nvram_update_verify_result_supported = B_FALSE;
200 
201 	encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
202 
203 	encp->enc_filter_action_flag_supported = B_FALSE;
204 	encp->enc_filter_action_mark_supported = B_FALSE;
205 	encp->enc_filter_action_mark_max = 0;
206 
207 	return (0);
208 
209 fail2:
210 	EFSYS_PROBE(fail2);
211 fail1:
212 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
213 
214 	return (rc);
215 }
216 
217 static	__checkReturn	efx_rc_t
218 siena_phy_cfg(
219 	__in		efx_nic_t *enp)
220 {
221 #if EFSYS_OPT_PHY_STATS
222 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
223 #endif	/* EFSYS_OPT_PHY_STATS */
224 	efx_rc_t rc;
225 
226 	/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
227 	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
228 		goto fail1;
229 
230 #if EFSYS_OPT_PHY_STATS
231 	/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
232 	siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
233 			    NULL, &encp->enc_phy_stat_mask, NULL);
234 #endif	/* EFSYS_OPT_PHY_STATS */
235 
236 	return (0);
237 
238 fail1:
239 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
240 
241 	return (rc);
242 }
243 
244 #define	SIENA_BIU_MAGIC0	0x01234567
245 #define	SIENA_BIU_MAGIC1	0xfedcba98
246 
247 static	__checkReturn	efx_rc_t
248 siena_nic_biu_test(
249 	__in		efx_nic_t *enp)
250 {
251 	efx_oword_t oword;
252 	efx_rc_t rc;
253 
254 	/*
255 	 * Write magic values to scratch registers 0 and 1, then
256 	 * verify that the values were written correctly.  Interleave
257 	 * the accesses to ensure that the BIU is not just reading
258 	 * back the cached value that was last written.
259 	 */
260 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
261 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
262 
263 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
264 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
265 
266 	EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
267 	if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
268 		rc = EIO;
269 		goto fail1;
270 	}
271 
272 	EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
273 	if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
274 		rc = EIO;
275 		goto fail2;
276 	}
277 
278 	/*
279 	 * Perform the same test, with the values swapped.  This
280 	 * ensures that subsequent tests don't start with the correct
281 	 * values already written into the scratch registers.
282 	 */
283 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
284 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
285 
286 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
287 	EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
288 
289 	EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
290 	if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
291 		rc = EIO;
292 		goto fail3;
293 	}
294 
295 	EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
296 	if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
297 		rc = EIO;
298 		goto fail4;
299 	}
300 
301 	return (0);
302 
303 fail4:
304 	EFSYS_PROBE(fail4);
305 fail3:
306 	EFSYS_PROBE(fail3);
307 fail2:
308 	EFSYS_PROBE(fail2);
309 fail1:
310 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
311 
312 	return (rc);
313 }
314 
315 	__checkReturn	efx_rc_t
316 siena_nic_probe(
317 	__in		efx_nic_t *enp)
318 {
319 	efx_port_t *epp = &(enp->en_port);
320 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
321 	siena_link_state_t sls;
322 	unsigned int mask;
323 	efx_oword_t oword;
324 	efx_rc_t rc;
325 
326 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
327 
328 	/* Test BIU */
329 	if ((rc = siena_nic_biu_test(enp)) != 0)
330 		goto fail1;
331 
332 	/* Clear the region register */
333 	EFX_POPULATE_OWORD_4(oword,
334 	    FRF_AZ_ADR_REGION0, 0,
335 	    FRF_AZ_ADR_REGION1, (1 << 16),
336 	    FRF_AZ_ADR_REGION2, (2 << 16),
337 	    FRF_AZ_ADR_REGION3, (3 << 16));
338 	EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
339 
340 	/* Read clear any assertion state */
341 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
342 		goto fail2;
343 
344 	/* Exit the assertion handler */
345 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
346 		goto fail3;
347 
348 	/* Wrestle control from the BMC */
349 	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
350 		goto fail4;
351 
352 	if ((rc = siena_board_cfg(enp)) != 0)
353 		goto fail5;
354 
355 	if ((rc = siena_phy_cfg(enp)) != 0)
356 		goto fail6;
357 
358 	/* Obtain the default PHY advertised capabilities */
359 	if ((rc = siena_nic_reset(enp)) != 0)
360 		goto fail7;
361 	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
362 		goto fail8;
363 	epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
364 	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
365 
366 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
367 	if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
368 		goto fail9;
369 	enp->en_u.siena.enu_partn_mask = mask;
370 #endif
371 
372 #if EFSYS_OPT_MAC_STATS
373 	/* Wipe the MAC statistics */
374 	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
375 		goto fail10;
376 #endif
377 
378 #if EFSYS_OPT_LOOPBACK
379 	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
380 		goto fail11;
381 #endif
382 
383 #if EFSYS_OPT_MON_STATS
384 	if ((rc = mcdi_mon_cfg_build(enp)) != 0)
385 		goto fail12;
386 #endif
387 
388 	encp->enc_features = enp->en_features;
389 
390 	return (0);
391 
392 #if EFSYS_OPT_MON_STATS
393 fail12:
394 	EFSYS_PROBE(fail12);
395 #endif
396 #if EFSYS_OPT_LOOPBACK
397 fail11:
398 	EFSYS_PROBE(fail11);
399 #endif
400 #if EFSYS_OPT_MAC_STATS
401 fail10:
402 	EFSYS_PROBE(fail10);
403 #endif
404 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
405 fail9:
406 	EFSYS_PROBE(fail9);
407 #endif
408 fail8:
409 	EFSYS_PROBE(fail8);
410 fail7:
411 	EFSYS_PROBE(fail7);
412 fail6:
413 	EFSYS_PROBE(fail6);
414 fail5:
415 	EFSYS_PROBE(fail5);
416 fail4:
417 	EFSYS_PROBE(fail4);
418 fail3:
419 	EFSYS_PROBE(fail3);
420 fail2:
421 	EFSYS_PROBE(fail2);
422 fail1:
423 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
424 
425 	return (rc);
426 }
427 
428 	__checkReturn	efx_rc_t
429 siena_nic_reset(
430 	__in		efx_nic_t *enp)
431 {
432 	efx_mcdi_req_t req;
433 	efx_rc_t rc;
434 
435 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
436 
437 	/* siena_nic_reset() is called to recover from BADASSERT failures. */
438 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
439 		goto fail1;
440 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
441 		goto fail2;
442 
443 	/*
444 	 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
445 	 * for backwards compatibility with PORT_RESET_IN_LEN.
446 	 */
447 	EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
448 
449 	req.emr_cmd = MC_CMD_ENTITY_RESET;
450 	req.emr_in_buf = NULL;
451 	req.emr_in_length = 0;
452 	req.emr_out_buf = NULL;
453 	req.emr_out_length = 0;
454 
455 	efx_mcdi_execute(enp, &req);
456 
457 	if (req.emr_rc != 0) {
458 		rc = req.emr_rc;
459 		goto fail3;
460 	}
461 
462 	return (0);
463 
464 fail3:
465 	EFSYS_PROBE(fail3);
466 fail2:
467 	EFSYS_PROBE(fail2);
468 fail1:
469 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
470 
471 	return (0);
472 }
473 
474 static			void
475 siena_nic_rx_cfg(
476 	__in		efx_nic_t *enp)
477 {
478 	efx_oword_t oword;
479 
480 	/*
481 	 * RX_INGR_EN is always enabled on Siena, because we rely on
482 	 * the RX parser to be resiliant to missing SOP/EOP.
483 	 */
484 	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
485 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
486 	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
487 
488 	/* Disable parsing of additional 802.1Q in Q packets */
489 	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
490 	EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
491 	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
492 }
493 
494 static			void
495 siena_nic_usrev_dis(
496 	__in		efx_nic_t *enp)
497 {
498 	efx_oword_t	oword;
499 
500 	EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
501 	EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
502 }
503 
504 	__checkReturn	efx_rc_t
505 siena_nic_init(
506 	__in		efx_nic_t *enp)
507 {
508 	efx_rc_t rc;
509 
510 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
511 
512 	/* Enable reporting of some events (e.g. link change) */
513 	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
514 		goto fail1;
515 
516 	siena_sram_init(enp);
517 
518 	/* Configure Siena's RX block */
519 	siena_nic_rx_cfg(enp);
520 
521 	/* Disable USR_EVents for now */
522 	siena_nic_usrev_dis(enp);
523 
524 	/* bug17057: Ensure set_link is called */
525 	if ((rc = siena_phy_reconfigure(enp)) != 0)
526 		goto fail2;
527 
528 	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
529 
530 	return (0);
531 
532 fail2:
533 	EFSYS_PROBE(fail2);
534 fail1:
535 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
536 
537 	return (rc);
538 }
539 
540 			void
541 siena_nic_fini(
542 	__in		efx_nic_t *enp)
543 {
544 	_NOTE(ARGUNUSED(enp))
545 }
546 
547 			void
548 siena_nic_unprobe(
549 	__in		efx_nic_t *enp)
550 {
551 #if EFSYS_OPT_MON_STATS
552 	mcdi_mon_cfg_free(enp);
553 #endif /* EFSYS_OPT_MON_STATS */
554 	(void) efx_mcdi_drv_attach(enp, B_FALSE);
555 }
556 
557 #if EFSYS_OPT_DIAG
558 
559 static siena_register_set_t __siena_registers[] = {
560 	{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
561 	{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
562 	{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
563 	{ FR_AZ_TX_CFG_REG_OFST, 0, 1 },
564 	{ FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
565 	{ FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
566 	{ FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
567 	{ FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
568 	{ FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
569 	{ FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
570 	{ FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
571 	{ FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
572 	{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
573 };
574 
575 static const uint32_t __siena_register_masks[] = {
576 	0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
577 	0x000103FF, 0x00000000, 0x00000000, 0x00000000,
578 	0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
579 	0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
580 	0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
581 	0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
582 	0x00000003, 0x00000000, 0x00000000, 0x00000000,
583 	0x000003FF, 0x00000000, 0x00000000, 0x00000000,
584 	0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
585 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
586 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
587 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
588 	0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
589 };
590 
591 static siena_register_set_t __siena_tables[] = {
592 	{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
593 	    FR_AZ_RX_FILTER_TBL0_ROWS },
594 	{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
595 	    FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
596 	{ FR_AZ_RX_DESC_PTR_TBL_OFST,
597 	    FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
598 	{ FR_AZ_TX_DESC_PTR_TBL_OFST,
599 	    FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
600 	{ FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
601 	{ FR_CZ_TX_FILTER_TBL0_OFST,
602 	    FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
603 	{ FR_CZ_TX_MAC_FILTER_TBL0_OFST,
604 	    FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
605 };
606 
607 static const uint32_t __siena_table_masks[] = {
608 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
609 	0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
610 	0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
611 	0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
612 	0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
613 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
614 	0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
615 };
616 
617 	__checkReturn	efx_rc_t
618 siena_nic_test_registers(
619 	__in		efx_nic_t *enp,
620 	__in		siena_register_set_t *rsp,
621 	__in		size_t count)
622 {
623 	unsigned int bit;
624 	efx_oword_t original;
625 	efx_oword_t reg;
626 	efx_oword_t buf;
627 	efx_rc_t rc;
628 
629 	while (count > 0) {
630 		/* This function is only suitable for registers */
631 		EFSYS_ASSERT(rsp->rows == 1);
632 
633 		/* bit sweep on and off */
634 		EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
635 			    B_TRUE);
636 		for (bit = 0; bit < 128; bit++) {
637 			/* Is this bit in the mask? */
638 			if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
639 				continue;
640 
641 			/* Test this bit can be set in isolation */
642 			reg = original;
643 			EFX_AND_OWORD(reg, rsp->mask);
644 			EFX_SET_OWORD_BIT(reg, bit);
645 
646 			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
647 				    B_TRUE);
648 			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
649 				    B_TRUE);
650 
651 			EFX_AND_OWORD(buf, rsp->mask);
652 			if (memcmp(&reg, &buf, sizeof (reg))) {
653 				rc = EIO;
654 				goto fail1;
655 			}
656 
657 			/* Test this bit can be cleared in isolation */
658 			EFX_OR_OWORD(reg, rsp->mask);
659 			EFX_CLEAR_OWORD_BIT(reg, bit);
660 
661 			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
662 				    B_TRUE);
663 			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
664 				    B_TRUE);
665 
666 			EFX_AND_OWORD(buf, rsp->mask);
667 			if (memcmp(&reg, &buf, sizeof (reg))) {
668 				rc = EIO;
669 				goto fail2;
670 			}
671 		}
672 
673 		/* Restore the old value */
674 		EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
675 			    B_TRUE);
676 
677 		--count;
678 		++rsp;
679 	}
680 
681 	return (0);
682 
683 fail2:
684 	EFSYS_PROBE(fail2);
685 fail1:
686 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
687 
688 	/* Restore the old value */
689 	EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
690 
691 	return (rc);
692 }
693 
694 	__checkReturn	efx_rc_t
695 siena_nic_test_tables(
696 	__in		efx_nic_t *enp,
697 	__in		siena_register_set_t *rsp,
698 	__in		efx_pattern_type_t pattern,
699 	__in		size_t count)
700 {
701 	efx_sram_pattern_fn_t func;
702 	unsigned int index;
703 	unsigned int address;
704 	efx_oword_t reg;
705 	efx_oword_t buf;
706 	efx_rc_t rc;
707 
708 	EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
709 	func = __efx_sram_pattern_fns[pattern];
710 
711 	while (count > 0) {
712 		/* Write */
713 		address = rsp->address;
714 		for (index = 0; index < rsp->rows; ++index) {
715 			func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
716 			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
717 			EFX_AND_OWORD(reg, rsp->mask);
718 			EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
719 
720 			address += rsp->step;
721 		}
722 
723 		/* Read */
724 		address = rsp->address;
725 		for (index = 0; index < rsp->rows; ++index) {
726 			func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
727 			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
728 			EFX_AND_OWORD(reg, rsp->mask);
729 			EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
730 			if (memcmp(&reg, &buf, sizeof (reg))) {
731 				rc = EIO;
732 				goto fail1;
733 			}
734 
735 			address += rsp->step;
736 		}
737 
738 		++rsp;
739 		--count;
740 	}
741 
742 	return (0);
743 
744 fail1:
745 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
746 
747 	return (rc);
748 }
749 
750 	__checkReturn	efx_rc_t
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