1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2009-2019 Solarflare Communications Inc. 5 */ 6 7 #include "efx.h" 8 #include "efx_impl.h" 9 10 #if EFSYS_OPT_SIENA 11 12 void 13 siena_sram_init( 14 __in efx_nic_t *enp) 15 { 16 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 17 efx_oword_t oword; 18 uint32_t rx_base, tx_base; 19 20 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 21 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 22 23 rx_base = encp->enc_buftbl_limit; 24 tx_base = rx_base + (encp->enc_rxq_limit * 25 EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE)); 26 27 /* Initialize the transmit descriptor cache */ 28 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base); 29 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); 30 31 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE); 32 EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword); 33 34 /* Initialize the receive descriptor cache */ 35 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base); 36 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); 37 38 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE); 39 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword); 40 41 /* Set receive descriptor pre-fetch low water mark */ 42 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56); 43 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword); 44 45 /* Set the event queue to use for SRAM updates */ 46 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0); 47 EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword); 48 } 49 50 #if EFSYS_OPT_DIAG 51 52 __checkReturn efx_rc_t 53 siena_sram_test( 54 __in efx_nic_t *enp, 55 __in efx_sram_pattern_fn_t func) 56 { 57 efx_oword_t oword; 58 efx_qword_t qword; 59 efx_qword_t verify; 60 size_t rows; 61 unsigned int wptr; 62 unsigned int rptr; 63 efx_rc_t rc; 64 65 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 66 67 /* Reconfigure into HALF buffer table mode */ 68 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0); 69 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 70 71 /* 72 * Move the descriptor caches up to the top of SRAM, and test 73 * all of SRAM below them. We only miss out one row here. 74 */ 75 rows = SIENA_SRAM_ROWS - 1; 76 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows); 77 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); 78 79 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1); 80 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); 81 82 /* 83 * Write the pattern through BUF_HALF_TBL. Write 84 * in 64 entry batches, waiting 1us in between each batch 85 * to guarantee not to overflow the SRAM fifo 86 */ 87 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { 88 func(wptr, B_FALSE, &qword); 89 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); 90 91 if ((wptr - rptr) < 64 && wptr < rows - 1) 92 continue; 93 94 EFSYS_SPIN(1); 95 96 for (; rptr <= wptr; ++rptr) { 97 func(rptr, B_FALSE, &qword); 98 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, 99 &verify); 100 101 if (!EFX_QWORD_IS_EQUAL(verify, qword)) { 102 rc = EFAULT; 103 goto fail1; 104 } 105 } 106 } 107 108 /* And do the same negated */ 109 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { 110 func(wptr, B_TRUE, &qword); 111 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); 112 113 if ((wptr - rptr) < 64 && wptr < rows - 1) 114 continue; 115 116 EFSYS_SPIN(1); 117 118 for (; rptr <= wptr; ++rptr) { 119 func(rptr, B_TRUE, &qword); 120 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, 121 &verify); 122 123 if (!EFX_QWORD_IS_EQUAL(verify, qword)) { 124 rc = EFAULT; 125 goto fail2; 126 } 127 } 128 } 129 130 /* Restore back to FULL buffer table mode */ 131 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); 132 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 133 134 /* 135 * We don't need to reconfigure SRAM again because the API 136 * requires efx_nic_fini() to be called after an sram test. 137 */ 138 return (0); 139 140 fail2: 141 EFSYS_PROBE(fail2); 142 fail1: 143 EFSYS_PROBE1(fail1, efx_rc_t, rc); 144 145 /* Restore back to FULL buffer table mode */ 146 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); 147 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 148 149 return (rc); 150 } 151 152 #endif /* EFSYS_OPT_DIAG */ 153 154 #endif /* EFSYS_OPT_SIENA */ 155