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