1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2007-2019 Solarflare Communications Inc. 5 */ 6 7 #include "efx.h" 8 #include "efx_impl.h" 9 10 __checkReturn efx_rc_t 11 efx_sram_buf_tbl_set( 12 __in efx_nic_t *enp, 13 __in uint32_t id, 14 __in efsys_mem_t *esmp, 15 __in size_t n) 16 { 17 efx_qword_t qword; 18 uint32_t start = id; 19 uint32_t stop = start + n; 20 efsys_dma_addr_t addr; 21 efx_oword_t oword; 22 unsigned int count; 23 efx_rc_t rc; 24 25 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 26 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 27 28 #if EFX_OPTS_EF10() 29 if (EFX_FAMILY_IS_EF10(enp)) { 30 /* 31 * FIXME: the efx_sram_buf_tbl_*() functionality needs to be 32 * pulled inside the Falcon/Siena queue create/destroy code, 33 * and then the original functions can be removed (see bug30834 34 * comment #1). But, for now, we just ensure that they are 35 * no-ops for EF10, to allow bringing up existing drivers 36 * without modification. 37 */ 38 39 return (0); 40 } 41 #endif /* EFX_OPTS_EF10() */ 42 43 if (stop >= EFX_BUF_TBL_SIZE) { 44 rc = EFBIG; 45 goto fail1; 46 } 47 48 /* Add the entries into the buffer table */ 49 addr = EFSYS_MEM_ADDR(esmp); 50 for (id = start; id != stop; id++) { 51 EFX_POPULATE_QWORD_5(qword, 52 FRF_AZ_IP_DAT_BUF_SIZE, 0, FRF_AZ_BUF_ADR_REGION, 0, 53 FRF_AZ_BUF_ADR_FBUF_DW0, 54 (uint32_t)((addr >> 12) & 0xffffffff), 55 FRF_AZ_BUF_ADR_FBUF_DW1, 56 (uint32_t)((addr >> 12) >> 32), 57 FRF_AZ_BUF_OWNER_ID_FBUF, 0); 58 59 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_FULL_TBL, 60 id, &qword); 61 62 addr += EFX_BUF_SIZE; 63 } 64 65 EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1); 66 67 /* Flush the write buffer */ 68 EFX_POPULATE_OWORD_2(oword, FRF_AZ_BUF_UPD_CMD, 1, 69 FRF_AZ_BUF_CLR_CMD, 0); 70 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); 71 72 /* Poll for the last entry being written to the buffer table */ 73 EFSYS_ASSERT3U(id, ==, stop); 74 addr -= EFX_BUF_SIZE; 75 76 count = 0; 77 do { 78 EFSYS_PROBE1(wait, unsigned int, count); 79 80 /* Spin for 1 ms */ 81 EFSYS_SPIN(1000); 82 83 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL, 84 id - 1, &qword); 85 86 if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) == 87 (uint32_t)((addr >> 12) & 0xffffffff) && 88 EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) == 89 (uint32_t)((addr >> 12) >> 32)) 90 goto verify; 91 92 } while (++count < 100); 93 94 rc = ETIMEDOUT; 95 goto fail2; 96 97 verify: 98 /* Verify the rest of the entries in the buffer table */ 99 while (--id != start) { 100 addr -= EFX_BUF_SIZE; 101 102 /* Read the buffer table entry */ 103 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL, 104 id - 1, &qword); 105 106 if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) != 107 (uint32_t)((addr >> 12) & 0xffffffff) || 108 EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) != 109 (uint32_t)((addr >> 12) >> 32)) { 110 rc = EFAULT; 111 goto fail3; 112 } 113 } 114 115 return (0); 116 117 fail3: 118 EFSYS_PROBE(fail3); 119 120 id = stop; 121 122 fail2: 123 EFSYS_PROBE(fail2); 124 125 EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0, 126 FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, id - 1, 127 FRF_AZ_BUF_CLR_START_ID, start); 128 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); 129 130 fail1: 131 EFSYS_PROBE1(fail1, efx_rc_t, rc); 132 133 return (rc); 134 } 135 136 void 137 efx_sram_buf_tbl_clear( 138 __in efx_nic_t *enp, 139 __in uint32_t id, 140 __in size_t n) 141 { 142 efx_oword_t oword; 143 uint32_t start = id; 144 uint32_t stop = start + n; 145 146 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 147 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 148 149 #if EFX_OPTS_EF10() 150 if (EFX_FAMILY_IS_EF10(enp)) { 151 /* 152 * FIXME: the efx_sram_buf_tbl_*() functionality needs to be 153 * pulled inside the Falcon/Siena queue create/destroy code, 154 * and then the original functions can be removed (see bug30834 155 * comment #1). But, for now, we just ensure that they are 156 * no-ops for EF10, to allow bringing up existing drivers 157 * without modification. 158 */ 159 160 return; 161 } 162 #endif /* EFX_OPTS_EF10() */ 163 164 EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE); 165 166 EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1); 167 168 EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0, 169 FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, stop - 1, 170 FRF_AZ_BUF_CLR_START_ID, start); 171 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); 172 } 173 174 175 #if EFSYS_OPT_DIAG 176 177 static void 178 efx_sram_byte_increment_set( 179 __in size_t row, 180 __in boolean_t negate, 181 __out efx_qword_t *eqp) 182 { 183 size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; 184 unsigned int index; 185 186 _NOTE(ARGUNUSED(negate)) 187 188 for (index = 0; index < sizeof (efx_qword_t); index++) 189 eqp->eq_u8[index] = offset + index; 190 } 191 192 static void 193 efx_sram_all_the_same_set( 194 __in size_t row, 195 __in boolean_t negate, 196 __out efx_qword_t *eqp) 197 { 198 _NOTE(ARGUNUSED(row)) 199 200 if (negate) 201 EFX_SET_QWORD(*eqp); 202 else 203 EFX_ZERO_QWORD(*eqp); 204 } 205 206 static void 207 efx_sram_bit_alternate_set( 208 __in size_t row, 209 __in boolean_t negate, 210 __out efx_qword_t *eqp) 211 { 212 _NOTE(ARGUNUSED(row)) 213 214 EFX_POPULATE_QWORD_2(*eqp, 215 EFX_DWORD_0, (negate) ? 0x55555555 : 0xaaaaaaaa, 216 EFX_DWORD_1, (negate) ? 0x55555555 : 0xaaaaaaaa); 217 } 218 219 static void 220 efx_sram_byte_alternate_set( 221 __in size_t row, 222 __in boolean_t negate, 223 __out efx_qword_t *eqp) 224 { 225 _NOTE(ARGUNUSED(row)) 226 227 EFX_POPULATE_QWORD_2(*eqp, 228 EFX_DWORD_0, (negate) ? 0x00ff00ff : 0xff00ff00, 229 EFX_DWORD_1, (negate) ? 0x00ff00ff : 0xff00ff00); 230 } 231 232 static void 233 efx_sram_byte_changing_set( 234 __in size_t row, 235 __in boolean_t negate, 236 __out efx_qword_t *eqp) 237 { 238 size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; 239 unsigned int index; 240 241 for (index = 0; index < sizeof (efx_qword_t); index++) { 242 uint8_t byte; 243 244 if (offset / 256 == 0) 245 byte = (uint8_t)((offset % 257) % 256); 246 else 247 byte = (uint8_t)(~((offset - 8) % 257) % 256); 248 249 eqp->eq_u8[index] = (negate) ? ~byte : byte; 250 } 251 } 252 253 static void 254 efx_sram_bit_sweep_set( 255 __in size_t row, 256 __in boolean_t negate, 257 __out efx_qword_t *eqp) 258 { 259 size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; 260 261 if (negate) { 262 EFX_SET_QWORD(*eqp); 263 EFX_CLEAR_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64); 264 } else { 265 EFX_ZERO_QWORD(*eqp); 266 EFX_SET_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64); 267 } 268 } 269 270 efx_sram_pattern_fn_t __efx_sram_pattern_fns[] = { 271 efx_sram_byte_increment_set, 272 efx_sram_all_the_same_set, 273 efx_sram_bit_alternate_set, 274 efx_sram_byte_alternate_set, 275 efx_sram_byte_changing_set, 276 efx_sram_bit_sweep_set 277 }; 278 279 __checkReturn efx_rc_t 280 efx_sram_test( 281 __in efx_nic_t *enp, 282 __in efx_pattern_type_t type) 283 { 284 efx_sram_pattern_fn_t func; 285 286 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 287 288 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 289 290 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 291 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 292 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 293 294 /* SRAM testing is only available on Siena. */ 295 if (enp->en_family != EFX_FAMILY_SIENA) 296 return (0); 297 298 /* Select pattern generator */ 299 EFSYS_ASSERT3U(type, <, EFX_PATTERN_NTYPES); 300 func = __efx_sram_pattern_fns[type]; 301 302 return (siena_sram_test(enp, func)); 303 } 304 305 #endif /* EFSYS_OPT_DIAG */ 306