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