xref: /freebsd/sys/dev/sfxge/common/siena_nic.c (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
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 __FBSDID("$FreeBSD$");
35 
36 #include "efx.h"
37 #include "efx_impl.h"
38 #include "mcdi_mon.h"
39 
40 #if EFSYS_OPT_SIENA
41 
42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
43 
44 static	__checkReturn		efx_rc_t
45 siena_nic_get_partn_mask(
46 	__in			efx_nic_t *enp,
47 	__out			unsigned int *maskp)
48 {
49 	efx_mcdi_req_t req;
50 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
51 		MC_CMD_NVRAM_TYPES_OUT_LEN);
52 	efx_rc_t rc;
53 
54 	req.emr_cmd = MC_CMD_NVRAM_TYPES;
55 	req.emr_in_buf = payload;
56 	req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
57 	req.emr_out_buf = payload;
58 	req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
59 
60 	efx_mcdi_execute(enp, &req);
61 
62 	if (req.emr_rc != 0) {
63 		rc = req.emr_rc;
64 		goto fail1;
65 	}
66 
67 	if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
68 		rc = EMSGSIZE;
69 		goto fail2;
70 	}
71 
72 	*maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
73 
74 	return (0);
75 
76 fail2:
77 	EFSYS_PROBE(fail2);
78 fail1:
79 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
80 
81 	return (rc);
82 }
83 
84 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
85 
86 static	__checkReturn	efx_rc_t
87 siena_board_cfg(
88 	__in		efx_nic_t *enp)
89 {
90 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
91 	uint8_t mac_addr[6];
92 	efx_dword_t capabilities;
93 	uint32_t board_type;
94 	uint32_t nevq, nrxq, ntxq;
95 	efx_rc_t rc;
96 
97 	/* Siena has a fixed 8Kbyte VI window size */
98 	EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K	== 8192);
99 	encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
100 
101 	/* External port identifier using one-based port numbering */
102 	encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
103 
104 	/* Board configuration */
105 	if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
106 		    &capabilities, mac_addr)) != 0)
107 		goto fail1;
108 
109 	EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
110 
111 	encp->enc_board_type = board_type;
112 
113 	/*
114 	 * There is no possibility to determine the number of PFs on Siena
115 	 * by issuing MCDI request, and it is not an easy task to find the
116 	 * value based on the board type, so 'enc_hw_pf_count' is set to 1
117 	 */
118 	encp->enc_hw_pf_count = 1;
119 
120 	/* Additional capabilities */
121 	encp->enc_clk_mult = 1;
122 	if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
123 		enp->en_features |= EFX_FEATURE_TURBO;
124 
125 		if (EFX_DWORD_FIELD(capabilities,
126 			MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
127 			encp->enc_clk_mult = 2;
128 		}
129 	}
130 
131 	encp->enc_evq_timer_quantum_ns =
132 		EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
133 	encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
134 		FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
135 
136 	/* When hash header insertion is enabled, Siena inserts 16 bytes */
137 	encp->enc_rx_prefix_size = 16;
138 
139 	/* Alignment for receive packet DMA buffers */
140 	encp->enc_rx_buf_align_start = 1;
141 	encp->enc_rx_buf_align_end = 1;
142 
143 	/* Alignment for WPTR updates */
144 	encp->enc_rx_push_align = 1;
145 
146 #if EFSYS_OPT_RX_SCALE
147 	/* There is one RSS context per function */
148 	encp->enc_rx_scale_max_exclusive_contexts = 1;
149 
150 	encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
151 	encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
152 
153 	/*
154 	 * It is always possible to use port numbers
155 	 * as the input data for hash computation.
156 	 */
157 	encp->enc_rx_scale_l4_hash_supported = B_TRUE;
158 
159 	/* There is no support for additional RSS modes */
160 	encp->enc_rx_scale_additional_modes_supported = B_FALSE;
161 #endif /* EFSYS_OPT_RX_SCALE */
162 
163 	encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
164 	/* Fragments must not span 4k boundaries. */
165 	encp->enc_tx_dma_desc_boundary = 4096;
166 
167 	/* Resource limits */
168 	rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
169 	if (rc != 0) {
170 		if (rc != ENOTSUP)
171 			goto fail2;
172 
173 		nevq = 1024;
174 		nrxq = EFX_RXQ_LIMIT_TARGET;
175 		ntxq = EFX_TXQ_LIMIT_TARGET;
176 	}
177 	encp->enc_evq_limit = nevq;
178 	encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
179 	encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
180 
181 	encp->enc_txq_max_ndescs = 4096;
182 
183 	encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
184 	    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
185 	    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
186 
187 	encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
188 	encp->enc_fw_assisted_tso_enabled = B_FALSE;
189 	encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
190 	encp->enc_fw_assisted_tso_v2_n_contexts = 0;
191 	encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
192 	encp->enc_rx_packed_stream_supported = B_FALSE;
193 	encp->enc_rx_var_packed_stream_supported = B_FALSE;
194 	encp->enc_rx_es_super_buffer_supported = B_FALSE;
195 	encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
196 
197 	/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
198 	encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
199 	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
200 
201 	encp->enc_nvram_update_verify_result_supported = B_FALSE;
202 
203 	encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
204 
205 	encp->enc_filter_action_flag_supported = B_FALSE;
206 	encp->enc_filter_action_mark_supported = B_FALSE;
207 	encp->enc_filter_action_mark_max = 0;
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
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
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
318 siena_nic_probe(
319 	__in		efx_nic_t *enp)
320 {
321 	efx_port_t *epp = &(enp->en_port);
322 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
323 	siena_link_state_t sls;
324 	unsigned int mask;
325 	efx_oword_t oword;
326 	efx_rc_t rc;
327 
328 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
329 
330 	/* Test BIU */
331 	if ((rc = siena_nic_biu_test(enp)) != 0)
332 		goto fail1;
333 
334 	/* Clear the region register */
335 	EFX_POPULATE_OWORD_4(oword,
336 	    FRF_AZ_ADR_REGION0, 0,
337 	    FRF_AZ_ADR_REGION1, (1 << 16),
338 	    FRF_AZ_ADR_REGION2, (2 << 16),
339 	    FRF_AZ_ADR_REGION3, (3 << 16));
340 	EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
341 
342 	/* Read clear any assertion state */
343 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
344 		goto fail2;
345 
346 	/* Exit the assertion handler */
347 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
348 		goto fail3;
349 
350 	/* Wrestle control from the BMC */
351 	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
352 		goto fail4;
353 
354 	if ((rc = siena_board_cfg(enp)) != 0)
355 		goto fail5;
356 
357 	if ((rc = siena_phy_cfg(enp)) != 0)
358 		goto fail6;
359 
360 	/* Obtain the default PHY advertised capabilities */
361 	if ((rc = siena_nic_reset(enp)) != 0)
362 		goto fail7;
363 	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
364 		goto fail8;
365 	epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
366 	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
367 
368 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
369 	if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
370 		goto fail9;
371 	enp->en_u.siena.enu_partn_mask = mask;
372 #endif
373 
374 #if EFSYS_OPT_MAC_STATS
375 	/* Wipe the MAC statistics */
376 	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
377 		goto fail10;
378 #endif
379 
380 #if EFSYS_OPT_LOOPBACK
381 	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
382 		goto fail11;
383 #endif
384 
385 #if EFSYS_OPT_MON_STATS
386 	if ((rc = mcdi_mon_cfg_build(enp)) != 0)
387 		goto fail12;
388 #endif
389 
390 	encp->enc_features = enp->en_features;
391 
392 	return (0);
393 
394 #if EFSYS_OPT_MON_STATS
395 fail12:
396 	EFSYS_PROBE(fail12);
397 #endif
398 #if EFSYS_OPT_LOOPBACK
399 fail11:
400 	EFSYS_PROBE(fail11);
401 #endif
402 #if EFSYS_OPT_MAC_STATS
403 fail10:
404 	EFSYS_PROBE(fail10);
405 #endif
406 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
407 fail9:
408 	EFSYS_PROBE(fail9);
409 #endif
410 fail8:
411 	EFSYS_PROBE(fail8);
412 fail7:
413 	EFSYS_PROBE(fail7);
414 fail6:
415 	EFSYS_PROBE(fail6);
416 fail5:
417 	EFSYS_PROBE(fail5);
418 fail4:
419 	EFSYS_PROBE(fail4);
420 fail3:
421 	EFSYS_PROBE(fail3);
422 fail2:
423 	EFSYS_PROBE(fail2);
424 fail1:
425 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
426 
427 	return (rc);
428 }
429 
430 	__checkReturn	efx_rc_t
431 siena_nic_reset(
432 	__in		efx_nic_t *enp)
433 {
434 	efx_mcdi_req_t req;
435 	efx_rc_t rc;
436 
437 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
438 
439 	/* siena_nic_reset() is called to recover from BADASSERT failures. */
440 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
441 		goto fail1;
442 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
443 		goto fail2;
444 
445 	/*
446 	 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
447 	 * for backwards compatibility with PORT_RESET_IN_LEN.
448 	 */
449 	EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
450 
451 	req.emr_cmd = MC_CMD_ENTITY_RESET;
452 	req.emr_in_buf = NULL;
453 	req.emr_in_length = 0;
454 	req.emr_out_buf = NULL;
455 	req.emr_out_length = 0;
456 
457 	efx_mcdi_execute(enp, &req);
458 
459 	if (req.emr_rc != 0) {
460 		rc = req.emr_rc;
461 		goto fail3;
462 	}
463 
464 	return (0);
465 
466 fail3:
467 	EFSYS_PROBE(fail3);
468 fail2:
469 	EFSYS_PROBE(fail2);
470 fail1:
471 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
472 
473 	return (0);
474 }
475 
476 static			void
477 siena_nic_rx_cfg(
478 	__in		efx_nic_t *enp)
479 {
480 	efx_oword_t oword;
481 
482 	/*
483 	 * RX_INGR_EN is always enabled on Siena, because we rely on
484 	 * the RX parser to be resiliant to missing SOP/EOP.
485 	 */
486 	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
487 	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
488 	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
489 
490 	/* Disable parsing of additional 802.1Q in Q packets */
491 	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
492 	EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
493 	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
494 }
495 
496 static			void
497 siena_nic_usrev_dis(
498 	__in		efx_nic_t *enp)
499 {
500 	efx_oword_t	oword;
501 
502 	EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
503 	EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
504 }
505 
506 	__checkReturn	efx_rc_t
507 siena_nic_init(
508 	__in		efx_nic_t *enp)
509 {
510 	efx_rc_t rc;
511 
512 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
513 
514 	/* Enable reporting of some events (e.g. link change) */
515 	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
516 		goto fail1;
517 
518 	siena_sram_init(enp);
519 
520 	/* Configure Siena's RX block */
521 	siena_nic_rx_cfg(enp);
522 
523 	/* Disable USR_EVents for now */
524 	siena_nic_usrev_dis(enp);
525 
526 	/* bug17057: Ensure set_link is called */
527 	if ((rc = siena_phy_reconfigure(enp)) != 0)
528 		goto fail2;
529 
530 	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
531 
532 	return (0);
533 
534 fail2:
535 	EFSYS_PROBE(fail2);
536 fail1:
537 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
538 
539 	return (rc);
540 }
541 
542 			void
543 siena_nic_fini(
544 	__in		efx_nic_t *enp)
545 {
546 	_NOTE(ARGUNUSED(enp))
547 }
548 
549 			void
550 siena_nic_unprobe(
551 	__in		efx_nic_t *enp)
552 {
553 #if EFSYS_OPT_MON_STATS
554 	mcdi_mon_cfg_free(enp);
555 #endif /* EFSYS_OPT_MON_STATS */
556 	(void) efx_mcdi_drv_attach(enp, B_FALSE);
557 }
558 
559 #if EFSYS_OPT_DIAG
560 
561 static siena_register_set_t __siena_registers[] = {
562 	{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
563 	{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
564 	{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
565 	{ FR_AZ_TX_CFG_REG_OFST, 0, 1 },
566 	{ FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
567 	{ FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
568 	{ FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
569 	{ FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
570 	{ FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
571 	{ FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
572 	{ FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
573 	{ FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
574 	{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
575 };
576 
577 static const uint32_t __siena_register_masks[] = {
578 	0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
579 	0x000103FF, 0x00000000, 0x00000000, 0x00000000,
580 	0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
581 	0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
582 	0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
583 	0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
584 	0x00000003, 0x00000000, 0x00000000, 0x00000000,
585 	0x000003FF, 0x00000000, 0x00000000, 0x00000000,
586 	0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
587 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
588 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
589 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
590 	0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
591 };
592 
593 static siena_register_set_t __siena_tables[] = {
594 	{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
595 	    FR_AZ_RX_FILTER_TBL0_ROWS },
596 	{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
597 	    FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
598 	{ FR_AZ_RX_DESC_PTR_TBL_OFST,
599 	    FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
600 	{ FR_AZ_TX_DESC_PTR_TBL_OFST,
601 	    FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
602 	{ FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
603 	{ FR_CZ_TX_FILTER_TBL0_OFST,
604 	    FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
605 	{ FR_CZ_TX_MAC_FILTER_TBL0_OFST,
606 	    FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
607 };
608 
609 static const uint32_t __siena_table_masks[] = {
610 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
611 	0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
612 	0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
613 	0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
614 	0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
615 	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
616 	0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
617 };
618 
619 	__checkReturn	efx_rc_t
620 siena_nic_test_registers(
621 	__in		efx_nic_t *enp,
622 	__in		siena_register_set_t *rsp,
623 	__in		size_t count)
624 {
625 	unsigned int bit;
626 	efx_oword_t original;
627 	efx_oword_t reg;
628 	efx_oword_t buf;
629 	efx_rc_t rc;
630 
631 	while (count > 0) {
632 		/* This function is only suitable for registers */
633 		EFSYS_ASSERT(rsp->rows == 1);
634 
635 		/* bit sweep on and off */
636 		EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
637 			    B_TRUE);
638 		for (bit = 0; bit < 128; bit++) {
639 			/* Is this bit in the mask? */
640 			if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
641 				continue;
642 
643 			/* Test this bit can be set in isolation */
644 			reg = original;
645 			EFX_AND_OWORD(reg, rsp->mask);
646 			EFX_SET_OWORD_BIT(reg, bit);
647 
648 			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
649 				    B_TRUE);
650 			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
651 				    B_TRUE);
652 
653 			EFX_AND_OWORD(buf, rsp->mask);
654 			if (memcmp(&reg, &buf, sizeof (reg))) {
655 				rc = EIO;
656 				goto fail1;
657 			}
658 
659 			/* Test this bit can be cleared in isolation */
660 			EFX_OR_OWORD(reg, rsp->mask);
661 			EFX_CLEAR_OWORD_BIT(reg, bit);
662 
663 			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
664 				    B_TRUE);
665 			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
666 				    B_TRUE);
667 
668 			EFX_AND_OWORD(buf, rsp->mask);
669 			if (memcmp(&reg, &buf, sizeof (reg))) {
670 				rc = EIO;
671 				goto fail2;
672 			}
673 		}
674 
675 		/* Restore the old value */
676 		EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
677 			    B_TRUE);
678 
679 		--count;
680 		++rsp;
681 	}
682 
683 	return (0);
684 
685 fail2:
686 	EFSYS_PROBE(fail2);
687 fail1:
688 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
689 
690 	/* Restore the old value */
691 	EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
692 
693 	return (rc);
694 }
695 
696 	__checkReturn	efx_rc_t
697 siena_nic_test_tables(
698 	__in		efx_nic_t *enp,
699 	__in		siena_register_set_t *rsp,
700 	__in		efx_pattern_type_t pattern,
701 	__in		size_t count)
702 {
703 	efx_sram_pattern_fn_t func;
704 	unsigned int index;
705 	unsigned int address;
706 	efx_oword_t reg;
707 	efx_oword_t buf;
708 	efx_rc_t rc;
709 
710 	EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
711 	func = __efx_sram_pattern_fns[pattern];
712 
713 	while (count > 0) {
714 		/* Write */
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_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
721 
722 			address += rsp->step;
723 		}
724 
725 		/* Read */
726 		address = rsp->address;
727 		for (index = 0; index < rsp->rows; ++index) {
728 			func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
729 			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
730 			EFX_AND_OWORD(reg, rsp->mask);
731 			EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
732 			if (memcmp(&reg, &buf, sizeof (reg))) {
733 				rc = EIO;
734 				goto fail1;
735 			}
736 
737 			address += rsp->step;
738 		}
739 
740 		++rsp;
741 		--count;
742 	}
743 
744 	return (0);
745 
746 fail1:
747 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
748 
749 	return (rc);
750 }
751 
752 	__checkReturn	efx_rc_t
753 siena_nic_register_test(
754 	__in		efx_nic_t *enp)
755 {
756 	siena_register_set_t *rsp;
757 	const uint32_t *dwordp;
758 	unsigned int nitems;
759 	unsigned int count;
760 	efx_rc_t rc;
761 
762 	/* Fill out the register mask entries */
763 	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
764 		    == EFX_ARRAY_SIZE(__siena_registers) * 4);
765 
766 	nitems = EFX_ARRAY_SIZE(__siena_registers);
767 	dwordp = __siena_register_masks;
768 	for (count = 0; count < nitems; ++count) {
769 		rsp = __siena_registers + count;
770 		rsp->mask.eo_u32[0] = *dwordp++;
771 		rsp->mask.eo_u32[1] = *dwordp++;
772 		rsp->mask.eo_u32[2] = *dwordp++;
773 		rsp->mask.eo_u32[3] = *dwordp++;
774 	}
775 
776 	/* Fill out the register table entries */
777 	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
778 		    == EFX_ARRAY_SIZE(__siena_tables) * 4);
779 
780 	nitems = EFX_ARRAY_SIZE(__siena_tables);
781 	dwordp = __siena_table_masks;
782 	for (count = 0; count < nitems; ++count) {
783 		rsp = __siena_tables + count;
784 		rsp->mask.eo_u32[0] = *dwordp++;
785 		rsp->mask.eo_u32[1] = *dwordp++;
786 		rsp->mask.eo_u32[2] = *dwordp++;
787 		rsp->mask.eo_u32[3] = *dwordp++;
788 	}
789 
790 	if ((rc = siena_nic_test_registers(enp, __siena_registers,
791 	    EFX_ARRAY_SIZE(__siena_registers))) != 0)
792 		goto fail1;
793 
794 	if ((rc = siena_nic_test_tables(enp, __siena_tables,
795 	    EFX_PATTERN_BYTE_ALTERNATE,
796 	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
797 		goto fail2;
798 
799 	if ((rc = siena_nic_test_tables(enp, __siena_tables,
800 	    EFX_PATTERN_BYTE_CHANGING,
801 	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
802 		goto fail3;
803 
804 	if ((rc = siena_nic_test_tables(enp, __siena_tables,
805 	    EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
806 		goto fail4;
807 
808 	return (0);
809 
810 fail4:
811 	EFSYS_PROBE(fail4);
812 fail3:
813 	EFSYS_PROBE(fail3);
814 fail2:
815 	EFSYS_PROBE(fail2);
816 fail1:
817 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
818 
819 	return (rc);
820 }
821 
822 #endif	/* EFSYS_OPT_DIAG */
823 
824 #endif	/* EFSYS_OPT_SIENA */
825