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