|
@@ -82,20 +82,77 @@ hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,
|
|
(SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
|
|
(SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
|
|
| 0x100000 | ((addr) & 0xfffff))
|
|
| 0x100000 | ((addr) & 0xfffff))
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+#define TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(pci_addr, addr) \
|
|
|
|
+ (hif_read32_mb((pci_addr)+(WIFICMN_PCIE_BAR_REG_ADDRESS)) \
|
|
|
|
+ | ((addr) & 0xfffff))
|
|
|
|
+
|
|
|
|
+#define TARG_CPU_SPACE_TO_CE_SPACE_AR900B(pci_addr, addr) \
|
|
|
|
+ (hif_read32_mb((pci_addr)+(WIFICMN_PCIE_BAR_REG_ADDRESS)) \
|
|
|
|
+ | 0x100000 | ((addr) & 0xfffff))
|
|
|
|
+
|
|
|
|
+#define SRAM_BASE_ADDRESS 0xc0000
|
|
|
|
+#define SRAM_END_ADDRESS 0x100000
|
|
|
|
+#define WIFI0_IPQ4019_BAR 0xa000000
|
|
|
|
+#define WIFI1_IPQ4019_BAR 0xa800000
|
|
|
|
+
|
|
/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
|
|
/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
|
|
#define DIAG_ACCESS_CE_TIMEOUT_MS 10
|
|
#define DIAG_ACCESS_CE_TIMEOUT_MS 10
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * get_ce_phy_addr() - get the physical address of an soc virtual address
|
|
|
|
+ * @sc: hif context
|
|
|
|
+ * @address: soc virtual address
|
|
|
|
+ * @target_type: target type being used.
|
|
|
|
+ *
|
|
|
|
+ * Return: soc physical address
|
|
|
|
+ */
|
|
|
|
+qdf_dma_addr_t get_ce_phy_addr(struct hif_softc *sc, uint32_t address,
|
|
|
|
+ unsigned int target_type)
|
|
|
|
+{
|
|
|
|
+ qdf_dma_addr_t ce_phy_addr;
|
|
|
|
+ struct hif_softc *scn = sc;
|
|
|
|
+ unsigned int region = address & 0xfffff;
|
|
|
|
+ unsigned int bar = address & 0xfff00000;
|
|
|
|
+ unsigned int sramregion = 0;
|
|
|
|
+
|
|
|
|
+ if ((target_type == TARGET_TYPE_IPQ4019) &&
|
|
|
|
+ (region >= SRAM_BASE_ADDRESS && region <= SRAM_END_ADDRESS)
|
|
|
|
+ && (bar == WIFI0_IPQ4019_BAR ||
|
|
|
|
+ bar == WIFI1_IPQ4019_BAR || bar == 0)) {
|
|
|
|
+ sramregion = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((target_type == TARGET_TYPE_IPQ4019) && sramregion == 1) {
|
|
|
|
+ ce_phy_addr =
|
|
|
|
+ TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(sc->mem, address);
|
|
|
|
+ } else if ((target_type == TARGET_TYPE_AR900B) ||
|
|
|
|
+ (target_type == TARGET_TYPE_QCA9984) ||
|
|
|
|
+ (target_type == TARGET_TYPE_IPQ4019) ||
|
|
|
|
+ (target_type == TARGET_TYPE_QCA9888)) {
|
|
|
|
+ ce_phy_addr =
|
|
|
|
+ TARG_CPU_SPACE_TO_CE_SPACE_AR900B(sc->mem, address);
|
|
|
|
+ } else {
|
|
|
|
+ ce_phy_addr =
|
|
|
|
+ TARG_CPU_SPACE_TO_CE_SPACE(sc->mem, address);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ce_phy_addr;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Diagnostic read/write access is provided for startup/config/debug usage.
|
|
* Diagnostic read/write access is provided for startup/config/debug usage.
|
|
* Caller must guarantee proper alignment, when applicable, and single user
|
|
* Caller must guarantee proper alignment, when applicable, and single user
|
|
* at any moment.
|
|
* at any moment.
|
|
*/
|
|
*/
|
|
|
|
|
|
-QDF_STATUS
|
|
|
|
-hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
|
|
|
|
- uint8_t *data, int nbytes)
|
|
|
|
|
|
+#define FW_SRAM_ADDRESS 0x000C0000
|
|
|
|
+
|
|
|
|
+QDF_STATUS hif_diag_read_mem(struct hif_opaque_softc *hif_ctx,
|
|
|
|
+ uint32_t address, uint8_t *data, int nbytes)
|
|
{
|
|
{
|
|
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
|
|
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
|
|
|
|
+
|
|
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
|
|
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
|
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
|
qdf_dma_addr_t buf;
|
|
qdf_dma_addr_t buf;
|
|
@@ -112,18 +169,30 @@ hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
|
|
qdf_dma_addr_t ce_phy_addr = address;
|
|
qdf_dma_addr_t ce_phy_addr = address;
|
|
unsigned int toeplitz_hash_result;
|
|
unsigned int toeplitz_hash_result;
|
|
unsigned int user_flags = 0;
|
|
unsigned int user_flags = 0;
|
|
|
|
+ unsigned int target_type = 0;
|
|
|
|
+ unsigned int boundary_addr = 0;
|
|
|
|
|
|
transaction_id = (mux_id & MUX_ID_MASK) |
|
|
transaction_id = (mux_id & MUX_ID_MASK) |
|
|
(transaction_id & TRANSACTION_ID_MASK);
|
|
(transaction_id & TRANSACTION_ID_MASK);
|
|
#ifdef QCA_WIFI_3_0
|
|
#ifdef QCA_WIFI_3_0
|
|
user_flags &= DESC_DATA_FLAG_MASK;
|
|
user_flags &= DESC_DATA_FLAG_MASK;
|
|
#endif
|
|
#endif
|
|
|
|
+ target_type = (hif_get_target_info_handle(hif_ctx))->target_type;
|
|
|
|
|
|
/* This code cannot handle reads to non-memory space. Redirect to the
|
|
/* This code cannot handle reads to non-memory space. Redirect to the
|
|
* register read fn but preserve the multi word read capability of
|
|
* register read fn but preserve the multi word read capability of
|
|
* this fn
|
|
* this fn
|
|
*/
|
|
*/
|
|
- if (address < DRAM_BASE_ADDRESS) {
|
|
|
|
|
|
+ if ((target_type == TARGET_TYPE_IPQ4019) ||
|
|
|
|
+ (target_type == TARGET_TYPE_AR900B) ||
|
|
|
|
+ (target_type == TARGET_TYPE_QCA9984) ||
|
|
|
|
+ (target_type == TARGET_TYPE_IPQ4019) ||
|
|
|
|
+ (target_type == TARGET_TYPE_QCA9888))
|
|
|
|
+ boundary_addr = FW_SRAM_ADDRESS;
|
|
|
|
+ else
|
|
|
|
+ boundary_addr = DRAM_BASE_ADDRESS;
|
|
|
|
+
|
|
|
|
+ if (address < boundary_addr) {
|
|
|
|
|
|
if ((address & 0x3) || ((uintptr_t) data & 0x3))
|
|
if ((address & 0x3) || ((uintptr_t) data & 0x3))
|
|
return QDF_STATUS_E_INVAL;
|
|
return QDF_STATUS_E_INVAL;
|
|
@@ -172,31 +241,21 @@ hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
|
|
- { /* Request CE to send from Target(!)
|
|
|
|
- * address to Host buffer */
|
|
|
|
- /*
|
|
|
|
- * The address supplied by the caller is in the
|
|
|
|
- * Target CPU virtual address space.
|
|
|
|
- *
|
|
|
|
- * In order to use this address with the diagnostic CE,
|
|
|
|
- * convert it from
|
|
|
|
- * Target CPU virtual address space
|
|
|
|
- * to
|
|
|
|
- * CE address space
|
|
|
|
- */
|
|
|
|
- if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
|
|
|
|
- return QDF_STATUS_E_FAILURE;
|
|
|
|
- ce_phy_addr =
|
|
|
|
- TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
|
|
|
|
- if (Q_TARGET_ACCESS_END(scn) < 0)
|
|
|
|
- return QDF_STATUS_E_FAILURE;
|
|
|
|
-
|
|
|
|
- status =
|
|
|
|
- ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
|
|
|
|
- transaction_id, 0, user_flags);
|
|
|
|
- if (status != QDF_STATUS_SUCCESS)
|
|
|
|
- goto done;
|
|
|
|
- }
|
|
|
|
|
|
+ if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
|
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
|
+
|
|
|
|
+ /* convert soc virtual address to physical address */
|
|
|
|
+ ce_phy_addr = get_ce_phy_addr(scn, address, target_type);
|
|
|
|
+
|
|
|
|
+ if (Q_TARGET_ACCESS_END(scn) < 0)
|
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
|
+
|
|
|
|
+ /* Request CE to send from Target(!)
|
|
|
|
+ * address to Host buffer */
|
|
|
|
+ status = ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
|
|
|
|
+ transaction_id, 0, user_flags);
|
|
|
|
+ if (status != QDF_STATUS_SUCCESS)
|
|
|
|
+ goto done;
|
|
|
|
|
|
i = 0;
|
|
i = 0;
|
|
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
|
|
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
|
|
@@ -278,6 +337,13 @@ QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * hif_diag_write_mem() - write data into the soc memory
|
|
|
|
+ * @hif_ctx: hif context
|
|
|
|
+ * @address: soc virtual address
|
|
|
|
+ * @data: data to copy into the soc address
|
|
|
|
+ * @nbytes: number of bytes to coppy
|
|
|
|
+ */
|
|
QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
|
|
QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
|
|
uint32_t address, uint8_t *data, int nbytes)
|
|
uint32_t address, uint8_t *data, int nbytes)
|
|
{
|
|
{
|
|
@@ -298,7 +364,7 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
|
|
qdf_dma_addr_t ce_phy_addr = address;
|
|
qdf_dma_addr_t ce_phy_addr = address;
|
|
unsigned int toeplitz_hash_result;
|
|
unsigned int toeplitz_hash_result;
|
|
unsigned int user_flags = 0;
|
|
unsigned int user_flags = 0;
|
|
-
|
|
|
|
|
|
+ unsigned int target_type = 0;
|
|
ce_diag = hif_state->ce_diag;
|
|
ce_diag = hif_state->ce_diag;
|
|
transaction_id = (mux_id & MUX_ID_MASK) |
|
|
transaction_id = (mux_id & MUX_ID_MASK) |
|
|
(transaction_id & TRANSACTION_ID_MASK);
|
|
(transaction_id & TRANSACTION_ID_MASK);
|
|
@@ -327,19 +393,14 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
|
|
qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
|
|
qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
|
|
orig_nbytes, DMA_TO_DEVICE);
|
|
orig_nbytes, DMA_TO_DEVICE);
|
|
|
|
|
|
- /*
|
|
|
|
- * The address supplied by the caller is in the
|
|
|
|
- * Target CPU virtual address space.
|
|
|
|
- *
|
|
|
|
- * In order to use this address with the diagnostic CE,
|
|
|
|
- * convert it from
|
|
|
|
- * Target CPU virtual address space
|
|
|
|
- * to
|
|
|
|
- * CE address space
|
|
|
|
- */
|
|
|
|
|
|
+ target_type = (hif_get_target_info_handle(hif_ctx))->target_type;
|
|
|
|
+
|
|
if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
|
|
if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
|
|
return QDF_STATUS_E_FAILURE;
|
|
return QDF_STATUS_E_FAILURE;
|
|
- ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
|
|
|
|
|
|
+
|
|
|
|
+ /* convert soc virtual address to physical address */
|
|
|
|
+ ce_phy_addr = get_ce_phy_addr(scn, address, target_type);
|
|
|
|
+
|
|
if (Q_TARGET_ACCESS_END(scn) < 0)
|
|
if (Q_TARGET_ACCESS_END(scn) < 0)
|
|
return QDF_STATUS_E_FAILURE;
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
|
|
|
@@ -348,26 +409,22 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
|
|
while (remaining_bytes) {
|
|
while (remaining_bytes) {
|
|
nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
|
|
nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
|
|
|
|
|
|
- { /* Set up to receive directly into Target(!) address */
|
|
|
|
- status = ce_recv_buf_enqueue(ce_diag,
|
|
|
|
- NULL, ce_phy_addr);
|
|
|
|
- if (status != QDF_STATUS_SUCCESS)
|
|
|
|
- goto done;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Set up to receive directly into Target(!) address */
|
|
|
|
+ status = ce_recv_buf_enqueue(ce_diag, NULL, ce_phy_addr);
|
|
|
|
+ if (status != QDF_STATUS_SUCCESS)
|
|
|
|
+ goto done;
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- * Request CE to send caller-supplied data that
|
|
|
|
- * was copied to bounce buffer to Target(!) address.
|
|
|
|
- */
|
|
|
|
- status =
|
|
|
|
- ce_send(ce_diag, NULL,
|
|
|
|
- (qdf_dma_addr_t) CE_data, nbytes,
|
|
|
|
- transaction_id, 0, user_flags);
|
|
|
|
- if (status != QDF_STATUS_SUCCESS)
|
|
|
|
- goto done;
|
|
|
|
- }
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Request CE to send caller-supplied data that
|
|
|
|
+ * was copied to bounce buffer to Target(!) address.
|
|
|
|
+ */
|
|
|
|
+ status = ce_send(ce_diag, NULL, (qdf_dma_addr_t) CE_data,
|
|
|
|
+ nbytes, transaction_id, 0, user_flags);
|
|
|
|
+
|
|
|
|
+ if (status != QDF_STATUS_SUCCESS)
|
|
|
|
+ goto done;
|
|
|
|
|
|
|
|
+ /* poll for transfer complete */
|
|
i = 0;
|
|
i = 0;
|
|
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
|
|
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
|
|
&completed_nbytes, &id,
|
|
&completed_nbytes, &id,
|