xref: /dpdk/drivers/common/sfc_efx/base/siena_sram.c (revision 672386c1e9e1f64f7aa3b1360ad22dc737ea8d72)
15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko  *
3*672386c1SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko  * Copyright(c) 2009-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko  */
65e111ed8SAndrew Rybchenko 
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko 
105e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
115e111ed8SAndrew Rybchenko 
125e111ed8SAndrew Rybchenko 			void
siena_sram_init(__in efx_nic_t * enp)135e111ed8SAndrew Rybchenko siena_sram_init(
145e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
155e111ed8SAndrew Rybchenko {
165e111ed8SAndrew Rybchenko 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
175e111ed8SAndrew Rybchenko 	efx_oword_t oword;
185e111ed8SAndrew Rybchenko 	uint32_t rx_base, tx_base;
195e111ed8SAndrew Rybchenko 
205e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
215e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
225e111ed8SAndrew Rybchenko 
235e111ed8SAndrew Rybchenko 	rx_base = encp->enc_buftbl_limit;
245e111ed8SAndrew Rybchenko 	tx_base = rx_base + (encp->enc_rxq_limit *
255e111ed8SAndrew Rybchenko 	    EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
265e111ed8SAndrew Rybchenko 
275e111ed8SAndrew Rybchenko 	/* Initialize the transmit descriptor cache */
285e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
295e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
305e111ed8SAndrew Rybchenko 
315e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);
325e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
335e111ed8SAndrew Rybchenko 
345e111ed8SAndrew Rybchenko 	/* Initialize the receive descriptor cache */
355e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
365e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
375e111ed8SAndrew Rybchenko 
385e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);
395e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
405e111ed8SAndrew Rybchenko 
415e111ed8SAndrew Rybchenko 	/* Set receive descriptor pre-fetch low water mark */
425e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
435e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
445e111ed8SAndrew Rybchenko 
455e111ed8SAndrew Rybchenko 	/* Set the event queue to use for SRAM updates */
465e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
475e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
485e111ed8SAndrew Rybchenko }
495e111ed8SAndrew Rybchenko 
505e111ed8SAndrew Rybchenko #if EFSYS_OPT_DIAG
515e111ed8SAndrew Rybchenko 
525e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
siena_sram_test(__in efx_nic_t * enp,__in efx_sram_pattern_fn_t func)535e111ed8SAndrew Rybchenko siena_sram_test(
545e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
555e111ed8SAndrew Rybchenko 	__in		efx_sram_pattern_fn_t func)
565e111ed8SAndrew Rybchenko {
575e111ed8SAndrew Rybchenko 	efx_oword_t oword;
585e111ed8SAndrew Rybchenko 	efx_qword_t qword;
595e111ed8SAndrew Rybchenko 	efx_qword_t verify;
605e111ed8SAndrew Rybchenko 	size_t rows;
615e111ed8SAndrew Rybchenko 	unsigned int wptr;
625e111ed8SAndrew Rybchenko 	unsigned int rptr;
635e111ed8SAndrew Rybchenko 	efx_rc_t rc;
645e111ed8SAndrew Rybchenko 
655e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
665e111ed8SAndrew Rybchenko 
675e111ed8SAndrew Rybchenko 	/* Reconfigure into HALF buffer table mode */
685e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0);
695e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
705e111ed8SAndrew Rybchenko 
715e111ed8SAndrew Rybchenko 	/*
725e111ed8SAndrew Rybchenko 	 * Move the descriptor caches up to the top of SRAM, and test
735e111ed8SAndrew Rybchenko 	 * all of SRAM below them. We only miss out one row here.
745e111ed8SAndrew Rybchenko 	 */
755e111ed8SAndrew Rybchenko 	rows = SIENA_SRAM_ROWS - 1;
765e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows);
775e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
785e111ed8SAndrew Rybchenko 
795e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1);
805e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
815e111ed8SAndrew Rybchenko 
825e111ed8SAndrew Rybchenko 	/*
835e111ed8SAndrew Rybchenko 	 * Write the pattern through BUF_HALF_TBL. Write
845e111ed8SAndrew Rybchenko 	 * in 64 entry batches, waiting 1us in between each batch
855e111ed8SAndrew Rybchenko 	 * to guarantee not to overflow the SRAM fifo
865e111ed8SAndrew Rybchenko 	 */
875e111ed8SAndrew Rybchenko 	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
885e111ed8SAndrew Rybchenko 		func(wptr, B_FALSE, &qword);
895e111ed8SAndrew Rybchenko 		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
905e111ed8SAndrew Rybchenko 
915e111ed8SAndrew Rybchenko 		if ((wptr - rptr) < 64 && wptr < rows - 1)
925e111ed8SAndrew Rybchenko 			continue;
935e111ed8SAndrew Rybchenko 
945e111ed8SAndrew Rybchenko 		EFSYS_SPIN(1);
955e111ed8SAndrew Rybchenko 
965e111ed8SAndrew Rybchenko 		for (; rptr <= wptr; ++rptr) {
975e111ed8SAndrew Rybchenko 			func(rptr, B_FALSE, &qword);
985e111ed8SAndrew Rybchenko 			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
995e111ed8SAndrew Rybchenko 			    &verify);
1005e111ed8SAndrew Rybchenko 
1015e111ed8SAndrew Rybchenko 			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
1025e111ed8SAndrew Rybchenko 				rc = EFAULT;
1035e111ed8SAndrew Rybchenko 				goto fail1;
1045e111ed8SAndrew Rybchenko 			}
1055e111ed8SAndrew Rybchenko 		}
1065e111ed8SAndrew Rybchenko 	}
1075e111ed8SAndrew Rybchenko 
1085e111ed8SAndrew Rybchenko 	/* And do the same negated */
1095e111ed8SAndrew Rybchenko 	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
1105e111ed8SAndrew Rybchenko 		func(wptr, B_TRUE, &qword);
1115e111ed8SAndrew Rybchenko 		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
1125e111ed8SAndrew Rybchenko 
1135e111ed8SAndrew Rybchenko 		if ((wptr - rptr) < 64 && wptr < rows - 1)
1145e111ed8SAndrew Rybchenko 			continue;
1155e111ed8SAndrew Rybchenko 
1165e111ed8SAndrew Rybchenko 		EFSYS_SPIN(1);
1175e111ed8SAndrew Rybchenko 
1185e111ed8SAndrew Rybchenko 		for (; rptr <= wptr; ++rptr) {
1195e111ed8SAndrew Rybchenko 			func(rptr, B_TRUE, &qword);
1205e111ed8SAndrew Rybchenko 			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
1215e111ed8SAndrew Rybchenko 			    &verify);
1225e111ed8SAndrew Rybchenko 
1235e111ed8SAndrew Rybchenko 			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
1245e111ed8SAndrew Rybchenko 				rc = EFAULT;
1255e111ed8SAndrew Rybchenko 				goto fail2;
1265e111ed8SAndrew Rybchenko 			}
1275e111ed8SAndrew Rybchenko 		}
1285e111ed8SAndrew Rybchenko 	}
1295e111ed8SAndrew Rybchenko 
1305e111ed8SAndrew Rybchenko 	/* Restore back to FULL buffer table mode */
1315e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
1325e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
1335e111ed8SAndrew Rybchenko 
1345e111ed8SAndrew Rybchenko 	/*
1355e111ed8SAndrew Rybchenko 	 * We don't need to reconfigure SRAM again because the API
1365e111ed8SAndrew Rybchenko 	 * requires efx_nic_fini() to be called after an sram test.
1375e111ed8SAndrew Rybchenko 	 */
1385e111ed8SAndrew Rybchenko 	return (0);
1395e111ed8SAndrew Rybchenko 
1405e111ed8SAndrew Rybchenko fail2:
1415e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
1425e111ed8SAndrew Rybchenko fail1:
1435e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1445e111ed8SAndrew Rybchenko 
1455e111ed8SAndrew Rybchenko 	/* Restore back to FULL buffer table mode */
1465e111ed8SAndrew Rybchenko 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
1475e111ed8SAndrew Rybchenko 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
1485e111ed8SAndrew Rybchenko 
1495e111ed8SAndrew Rybchenko 	return (rc);
1505e111ed8SAndrew Rybchenko }
1515e111ed8SAndrew Rybchenko 
1525e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_DIAG */
1535e111ed8SAndrew Rybchenko 
1545e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
155