1 /* 2 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "targcfg.h" 20 #include "target_type.h" 21 #include "qdf_lock.h" 22 #include "qdf_status.h" 23 #include "qdf_status.h" 24 #include <qdf_atomic.h> /* qdf_atomic_read */ 25 #include <targaddrs.h> 26 #include "hif_io32.h" 27 #include <hif.h> 28 #include "regtable.h" 29 #include <a_debug.h> 30 #include "hif_main.h" 31 #include "ce_api.h" 32 #include "qdf_trace.h" 33 #include "hif_debug.h" 34 #include "qdf_module.h" 35 36 void 37 hif_ce_dump_target_memory(struct hif_softc *scn, void *ramdump_base, 38 uint32_t address, uint32_t size) 39 { 40 uint32_t loc = address; 41 uint32_t val = 0; 42 uint32_t j = 0; 43 u8 *temp = ramdump_base; 44 45 if (Q_TARGET_ACCESS_BEGIN(scn) < 0) 46 return; 47 48 while (j < size) { 49 val = hif_read32_mb(scn, scn->mem + loc + j); 50 qdf_mem_copy(temp, &val, 4); 51 j += 4; 52 temp += 4; 53 } 54 55 Q_TARGET_ACCESS_END(scn); 56 } 57 /* 58 * TBDXXX: Should be a function call specific to each Target-type. 59 * This convoluted macro converts from Target CPU Virtual Address 60 * Space to CE Address Space. As part of this process, we 61 * conservatively fetch the current PCIE_BAR. MOST of the time, 62 * this should match the upper bits of PCI space for this device; 63 * but that's not guaranteed. 64 */ 65 #ifdef QCA_WIFI_3_0 66 #define TARG_CPU_SPACE_TO_CE_SPACE(sc, pci_addr, addr) \ 67 (scn->mem_pa + addr) 68 #else 69 #define TARG_CPU_SPACE_TO_CE_SPACE(sc, pci_addr, addr) \ 70 (((hif_read32_mb(sc, (pci_addr) + \ 71 (SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \ 72 | 0x100000 | ((addr) & 0xfffff)) 73 #endif 74 75 #define TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(scn, pci_addr, addr) \ 76 (hif_read32_mb(scn, (pci_addr) + (WIFICMN_PCIE_BAR_REG_ADDRESS)) \ 77 | ((addr) & 0xfffff)) 78 79 #define TARG_CPU_SPACE_TO_CE_SPACE_AR900B(scn, pci_addr, addr) \ 80 (hif_read32_mb(scn, (pci_addr) + (WIFICMN_PCIE_BAR_REG_ADDRESS)) \ 81 | 0x100000 | ((addr) & 0xfffff)) 82 83 #define SRAM_BASE_ADDRESS 0xc0000 84 #define SRAM_END_ADDRESS 0x100000 85 #define WIFI0_IPQ4019_BAR 0xa000000 86 #define WIFI1_IPQ4019_BAR 0xa800000 87 88 /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ 89 #define DIAG_ACCESS_CE_TIMEOUT_MS 10 90 91 /** 92 * get_ce_phy_addr() - get the physical address of an soc virtual address 93 * @sc: hif context 94 * @address: soc virtual address 95 * @target_type: target type being used. 96 * 97 * Return: soc physical address 98 */ 99 static qdf_dma_addr_t get_ce_phy_addr(struct hif_softc *sc, uint32_t address, 100 unsigned int target_type) 101 { 102 qdf_dma_addr_t ce_phy_addr; 103 struct hif_softc *scn = sc; 104 unsigned int region = address & 0xfffff; 105 unsigned int bar = address & 0xfff00000; 106 unsigned int sramregion = 0; 107 108 if ((target_type == TARGET_TYPE_IPQ4019) && 109 (region >= SRAM_BASE_ADDRESS && region <= SRAM_END_ADDRESS) 110 && (bar == WIFI0_IPQ4019_BAR || 111 bar == WIFI1_IPQ4019_BAR || bar == 0)) { 112 sramregion = 1; 113 } 114 115 if ((target_type == TARGET_TYPE_IPQ4019) && sramregion == 1) { 116 ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(sc, sc->mem, 117 address); 118 } else if ((target_type == TARGET_TYPE_AR900B) || 119 (target_type == TARGET_TYPE_QCA9984) || 120 (target_type == TARGET_TYPE_IPQ4019) || 121 (target_type == TARGET_TYPE_QCA9888)) { 122 ce_phy_addr = 123 TARG_CPU_SPACE_TO_CE_SPACE_AR900B(sc, sc->mem, address); 124 } else { 125 ce_phy_addr = 126 TARG_CPU_SPACE_TO_CE_SPACE(sc, sc->mem, address); 127 } 128 129 return ce_phy_addr; 130 } 131 132 /* 133 * Diagnostic read/write access is provided for startup/config/debug usage. 134 * Caller must guarantee proper alignment, when applicable, and single user 135 * at any moment. 136 */ 137 138 #define FW_SRAM_ADDRESS 0x000C0000 139 140 QDF_STATUS hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, 141 uint32_t address, uint8_t *data, int nbytes) 142 { 143 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); 144 145 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); 146 QDF_STATUS status = QDF_STATUS_SUCCESS; 147 qdf_dma_addr_t buf; 148 unsigned int completed_nbytes, orig_nbytes, remaining_bytes; 149 unsigned int id; 150 unsigned int flags; 151 struct CE_handle *ce_diag; 152 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */ 153 qdf_dma_addr_t CE_data_base = 0; 154 void *data_buf = NULL; 155 int i; 156 unsigned int mux_id = 0; 157 unsigned int transaction_id = 0xffff; 158 qdf_dma_addr_t ce_phy_addr = address; 159 unsigned int toeplitz_hash_result; 160 unsigned int user_flags = 0; 161 unsigned int target_type = 0; 162 unsigned int boundary_addr = 0; 163 164 ce_diag = hif_state->ce_diag; 165 if (ce_diag == NULL) { 166 HIF_ERROR("%s: DIAG CE not present", __func__); 167 return QDF_STATUS_E_INVAL; 168 } 169 /* not supporting diag ce on srng based systems, therefore we know this 170 * isn't an srng based system */ 171 172 transaction_id = (mux_id & MUX_ID_MASK) | 173 (transaction_id & TRANSACTION_ID_MASK); 174 #ifdef QCA_WIFI_3_0 175 user_flags &= DESC_DATA_FLAG_MASK; 176 #endif 177 target_type = (hif_get_target_info_handle(hif_ctx))->target_type; 178 179 /* This code cannot handle reads to non-memory space. Redirect to the 180 * register read fn but preserve the multi word read capability of 181 * this fn 182 */ 183 if ((target_type == TARGET_TYPE_IPQ4019) || 184 (target_type == TARGET_TYPE_AR900B) || 185 (target_type == TARGET_TYPE_QCA9984) || 186 (target_type == TARGET_TYPE_AR9888) || 187 (target_type == TARGET_TYPE_QCA9888)) 188 boundary_addr = FW_SRAM_ADDRESS; 189 else 190 boundary_addr = DRAM_BASE_ADDRESS; 191 192 if (address < boundary_addr) { 193 194 if ((address & 0x3) || ((uintptr_t) data & 0x3)) 195 return QDF_STATUS_E_INVAL; 196 197 while ((nbytes >= 4) && 198 (QDF_STATUS_SUCCESS == (status = 199 hif_diag_read_access(hif_ctx, address, 200 (uint32_t *)data)))) { 201 202 nbytes -= sizeof(uint32_t); 203 address += sizeof(uint32_t); 204 data += sizeof(uint32_t); 205 206 } 207 208 return status; 209 } 210 211 A_TARGET_ACCESS_LIKELY(scn); 212 213 /* 214 * Allocate a temporary bounce buffer to hold caller's data 215 * to be DMA'ed from Target. This guarantees 216 * 1) 4-byte alignment 217 * 2) Buffer in DMA-able space 218 */ 219 orig_nbytes = nbytes; 220 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev, 221 orig_nbytes, &CE_data_base); 222 if (!data_buf) { 223 status = QDF_STATUS_E_NOMEM; 224 goto done; 225 } 226 qdf_mem_set(data_buf, orig_nbytes, 0); 227 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base, 228 orig_nbytes, DMA_FROM_DEVICE); 229 230 remaining_bytes = orig_nbytes; 231 CE_data = CE_data_base; 232 while (remaining_bytes) { 233 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT); 234 { 235 status = ce_recv_buf_enqueue(ce_diag, NULL, CE_data); 236 if (status != QDF_STATUS_SUCCESS) 237 goto done; 238 } 239 240 if (Q_TARGET_ACCESS_BEGIN(scn) < 0) { 241 status = QDF_STATUS_E_FAILURE; 242 goto done; 243 } 244 245 /* convert soc virtual address to physical address */ 246 ce_phy_addr = get_ce_phy_addr(scn, address, target_type); 247 248 if (Q_TARGET_ACCESS_END(scn) < 0) { 249 status = QDF_STATUS_E_FAILURE; 250 goto done; 251 } 252 253 /* Request CE to send from Target(!) 254 * address to Host buffer 255 */ 256 status = ce_send(ce_diag, NULL, ce_phy_addr, nbytes, 257 transaction_id, 0, user_flags); 258 if (status != QDF_STATUS_SUCCESS) 259 goto done; 260 261 i = 0; 262 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf, 263 &completed_nbytes, &id, NULL, NULL, 264 &toeplitz_hash_result) != QDF_STATUS_SUCCESS) { 265 qdf_mdelay(1); 266 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { 267 status = QDF_STATUS_E_BUSY; 268 goto done; 269 } 270 } 271 if (nbytes != completed_nbytes) { 272 status = QDF_STATUS_E_FAILURE; 273 goto done; 274 } 275 if (buf != ce_phy_addr) { 276 status = QDF_STATUS_E_FAILURE; 277 goto done; 278 } 279 280 i = 0; 281 while (ce_completed_recv_next 282 (ce_diag, NULL, NULL, &buf, 283 &completed_nbytes, &id, 284 &flags) != QDF_STATUS_SUCCESS) { 285 qdf_mdelay(1); 286 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { 287 status = QDF_STATUS_E_BUSY; 288 goto done; 289 } 290 } 291 if (nbytes != completed_nbytes) { 292 status = QDF_STATUS_E_FAILURE; 293 goto done; 294 } 295 if (buf != CE_data) { 296 status = QDF_STATUS_E_FAILURE; 297 goto done; 298 } 299 300 remaining_bytes -= nbytes; 301 address += nbytes; 302 CE_data += nbytes; 303 } 304 305 done: 306 A_TARGET_ACCESS_UNLIKELY(scn); 307 308 if (status == QDF_STATUS_SUCCESS) 309 qdf_mem_copy(data, data_buf, orig_nbytes); 310 else 311 HIF_ERROR("%s failure (0x%x)", __func__, address); 312 313 if (data_buf) 314 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, 315 orig_nbytes, data_buf, CE_data_base, 0); 316 317 return status; 318 } 319 qdf_export_symbol(hif_diag_read_mem); 320 321 /* Read 4-byte aligned data from Target memory or register */ 322 QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx, 323 uint32_t address, uint32_t *data) 324 { 325 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); 326 327 if (address >= DRAM_BASE_ADDRESS) { 328 /* Assume range doesn't cross this boundary */ 329 return hif_diag_read_mem(hif_ctx, address, (uint8_t *) data, 330 sizeof(uint32_t)); 331 } else { 332 if (Q_TARGET_ACCESS_BEGIN(scn) < 0) 333 return QDF_STATUS_E_FAILURE; 334 *data = A_TARGET_READ(scn, address); 335 if (Q_TARGET_ACCESS_END(scn) < 0) 336 return QDF_STATUS_E_FAILURE; 337 338 return QDF_STATUS_SUCCESS; 339 } 340 } 341 342 /** 343 * hif_diag_write_mem() - write data into the soc memory 344 * @hif_ctx: hif context 345 * @address: soc virtual address 346 * @data: data to copy into the soc address 347 * @nbytes: number of bytes to coppy 348 */ 349 QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx, 350 uint32_t address, uint8_t *data, int nbytes) 351 { 352 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); 353 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx); 354 QDF_STATUS status = QDF_STATUS_SUCCESS; 355 qdf_dma_addr_t buf; 356 unsigned int completed_nbytes, orig_nbytes, remaining_bytes; 357 unsigned int id; 358 unsigned int flags; 359 struct CE_handle *ce_diag; 360 void *data_buf = NULL; 361 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */ 362 qdf_dma_addr_t CE_data_base = 0; 363 int i; 364 unsigned int mux_id = 0; 365 unsigned int transaction_id = 0xffff; 366 qdf_dma_addr_t ce_phy_addr = address; 367 unsigned int toeplitz_hash_result; 368 unsigned int user_flags = 0; 369 unsigned int target_type = 0; 370 371 ce_diag = hif_state->ce_diag; 372 if (ce_diag == NULL) { 373 HIF_ERROR("%s: DIAG CE not present", __func__); 374 return QDF_STATUS_E_INVAL; 375 } 376 /* not supporting diag ce on srng based systems, therefore we know this 377 * isn't an srng based system */ 378 379 transaction_id = (mux_id & MUX_ID_MASK) | 380 (transaction_id & TRANSACTION_ID_MASK); 381 #ifdef QCA_WIFI_3_0 382 user_flags &= DESC_DATA_FLAG_MASK; 383 #endif 384 385 A_TARGET_ACCESS_LIKELY(scn); 386 387 /* 388 * Allocate a temporary bounce buffer to hold caller's data 389 * to be DMA'ed to Target. This guarantees 390 * 1) 4-byte alignment 391 * 2) Buffer in DMA-able space 392 */ 393 orig_nbytes = nbytes; 394 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev, 395 orig_nbytes, &CE_data_base); 396 if (!data_buf) { 397 status = QDF_STATUS_E_NOMEM; 398 goto done; 399 } 400 401 /* Copy caller's data to allocated DMA buf */ 402 qdf_mem_copy(data_buf, data, orig_nbytes); 403 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base, 404 orig_nbytes, DMA_TO_DEVICE); 405 406 target_type = (hif_get_target_info_handle(hif_ctx))->target_type; 407 408 if (Q_TARGET_ACCESS_BEGIN(scn) < 0) { 409 status = QDF_STATUS_E_FAILURE; 410 goto done; 411 } 412 413 /* convert soc virtual address to physical address */ 414 ce_phy_addr = get_ce_phy_addr(scn, address, target_type); 415 416 if (Q_TARGET_ACCESS_END(scn) < 0) { 417 status = QDF_STATUS_E_FAILURE; 418 goto done; 419 } 420 421 remaining_bytes = orig_nbytes; 422 CE_data = CE_data_base; 423 while (remaining_bytes) { 424 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT); 425 426 /* Set up to receive directly into Target(!) address */ 427 status = ce_recv_buf_enqueue(ce_diag, NULL, ce_phy_addr); 428 if (status != QDF_STATUS_SUCCESS) 429 goto done; 430 431 /* 432 * Request CE to send caller-supplied data that 433 * was copied to bounce buffer to Target(!) address. 434 */ 435 status = ce_send(ce_diag, NULL, (qdf_dma_addr_t) CE_data, 436 nbytes, transaction_id, 0, user_flags); 437 438 if (status != QDF_STATUS_SUCCESS) 439 goto done; 440 441 /* poll for transfer complete */ 442 i = 0; 443 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf, 444 &completed_nbytes, &id, 445 NULL, NULL, &toeplitz_hash_result) != 446 QDF_STATUS_SUCCESS) { 447 qdf_mdelay(1); 448 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { 449 status = QDF_STATUS_E_BUSY; 450 goto done; 451 } 452 } 453 454 if (nbytes != completed_nbytes) { 455 status = QDF_STATUS_E_FAILURE; 456 goto done; 457 } 458 459 if (buf != CE_data) { 460 status = QDF_STATUS_E_FAILURE; 461 goto done; 462 } 463 464 i = 0; 465 while (ce_completed_recv_next 466 (ce_diag, NULL, NULL, &buf, 467 &completed_nbytes, &id, 468 &flags) != QDF_STATUS_SUCCESS) { 469 qdf_mdelay(1); 470 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { 471 status = QDF_STATUS_E_BUSY; 472 goto done; 473 } 474 } 475 476 if (nbytes != completed_nbytes) { 477 status = QDF_STATUS_E_FAILURE; 478 goto done; 479 } 480 481 if (buf != ce_phy_addr) { 482 status = QDF_STATUS_E_FAILURE; 483 goto done; 484 } 485 486 remaining_bytes -= nbytes; 487 address += nbytes; 488 CE_data += nbytes; 489 } 490 491 done: 492 A_TARGET_ACCESS_UNLIKELY(scn); 493 494 if (data_buf) { 495 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, 496 orig_nbytes, data_buf, CE_data_base, 0); 497 } 498 499 if (status != QDF_STATUS_SUCCESS) { 500 HIF_ERROR("%s failure (0x%llx)", __func__, 501 (uint64_t)ce_phy_addr); 502 } 503 504 return status; 505 } 506 507 /* Write 4B data to Target memory or register */ 508 QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *hif_ctx, 509 uint32_t address, uint32_t data) 510 { 511 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); 512 513 if (address >= DRAM_BASE_ADDRESS) { 514 /* Assume range doesn't cross this boundary */ 515 uint32_t data_buf = data; 516 517 return hif_diag_write_mem(hif_ctx, address, 518 (uint8_t *) &data_buf, 519 sizeof(uint32_t)); 520 } else { 521 if (Q_TARGET_ACCESS_BEGIN(scn) < 0) 522 return QDF_STATUS_E_FAILURE; 523 A_TARGET_WRITE(scn, address, data); 524 if (Q_TARGET_ACCESS_END(scn) < 0) 525 return QDF_STATUS_E_FAILURE; 526 527 return QDF_STATUS_SUCCESS; 528 } 529 } 530