1 /*- 2 * Copyright 2009 Solarflare Communications Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 #include "efsys.h" 26 #include "efx.h" 27 #include "efx_impl.h" 28 29 #if EFSYS_OPT_SIENA 30 31 void 32 siena_sram_init( 33 __in efx_nic_t *enp) 34 { 35 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 36 efx_oword_t oword; 37 uint32_t rx_base, tx_base; 38 39 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 40 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 41 42 rx_base = encp->enc_buftbl_limit; 43 tx_base = rx_base + (encp->enc_rxq_limit * 64); 44 45 /* Initialize the transmit descriptor cache */ 46 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base); 47 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); 48 49 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, 1); /* 16 descriptors */ 50 EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword); 51 52 /* Initialize the receive descriptor cache */ 53 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base); 54 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); 55 56 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, 3); /* 64 descriptors */ 57 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword); 58 59 /* Set receive descriptor pre-fetch low water mark */ 60 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56); 61 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword); 62 63 /* Set the event queue to use for SRAM updates */ 64 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0); 65 EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword); 66 } 67 68 #if EFSYS_OPT_DIAG 69 70 __checkReturn int 71 siena_sram_test( 72 __in efx_nic_t *enp, 73 __in efx_sram_pattern_fn_t func) 74 { 75 efx_oword_t oword; 76 efx_qword_t qword; 77 efx_qword_t verify; 78 size_t rows; 79 unsigned int wptr; 80 unsigned int rptr; 81 int rc; 82 83 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 84 85 /* Reconfigure into HALF buffer table mode */ 86 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0); 87 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 88 89 /* 90 * Move the descriptor caches up to the top of SRAM, and test 91 * all of SRAM below them. We only miss out one row here. 92 */ 93 rows = SIENA_SRAM_ROWS - 1; 94 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows); 95 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); 96 97 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1); 98 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); 99 100 /* 101 * Write the pattern through BUF_HALF_TBL. Write 102 * in 64 entry batches, waiting 1us in between each batch 103 * to guarantee not to overflow the SRAM fifo 104 */ 105 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { 106 func(wptr, B_FALSE, &qword); 107 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); 108 109 if ((wptr - rptr) < 64 && wptr < rows - 1) 110 continue; 111 112 EFSYS_SPIN(1); 113 114 for (; rptr <= wptr; ++rptr) { 115 func(rptr, B_FALSE, &qword); 116 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, 117 &verify); 118 119 if (!EFX_QWORD_IS_EQUAL(verify, qword)) { 120 rc = EFAULT; 121 goto fail1; 122 } 123 } 124 } 125 126 /* And do the same negated */ 127 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { 128 func(wptr, B_TRUE, &qword); 129 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); 130 131 if ((wptr - rptr) < 64 && wptr < rows - 1) 132 continue; 133 134 EFSYS_SPIN(1); 135 136 for (; rptr <= wptr; ++rptr) { 137 func(rptr, B_TRUE, &qword); 138 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, 139 &verify); 140 141 if (!EFX_QWORD_IS_EQUAL(verify, qword)) { 142 rc = EFAULT; 143 goto fail2; 144 } 145 } 146 } 147 148 /* Restore back to FULL buffer table mode */ 149 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); 150 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 151 152 /* 153 * We don't need to reconfigure SRAM again because the API 154 * requires efx_nic_fini() to be called after an sram test. 155 */ 156 return (0); 157 158 fail2: 159 EFSYS_PROBE(fail2); 160 fail1: 161 EFSYS_PROBE1(fail1, int, rc); 162 163 /* Restore back to FULL buffer table mode */ 164 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); 165 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); 166 167 return (rc); 168 } 169 170 #endif /* EFSYS_OPT_DIAG */ 171 172 #endif /* EFSYS_OPT_SIENA */ 173