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