blob: 14d89107038fd106f624ec7fa446bc38c9386c1b [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Komal Seelam02cf2f82016-02-22 20:44:25 +05302 * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
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
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080028#include "targcfg.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053029#include "qdf_lock.h"
30#include "qdf_status.h"
31#include "qdf_status.h"
32#include <qdf_atomic.h> /* qdf_atomic_read */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080033#include <targaddrs.h>
34#include <bmi_msg.h>
35#include "hif_io32.h"
36#include <hif.h>
37#include <htc_services.h>
38#include "regtable.h"
39#include <a_debug.h>
40#include "hif_main.h"
41#include "ce_api.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053042#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080043#ifdef CONFIG_CNSS
44#include <net/cnss.h>
45#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080046#include "hif_debug.h"
47#include "epping_main.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048
Komal Seelam5584a7c2016-02-24 19:22:48 +053049void
50hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,
51 uint32_t address, uint32_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052{
Komal Seelam644263d2016-02-22 20:45:49 +053053 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054 uint32_t loc = address;
55 uint32_t val = 0;
56 uint32_t j = 0;
57 u8 *temp = ramdump_base;
58
Houston Hoffmanbac94542016-03-14 21:11:59 -070059 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
60 return;
61
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062 while (j < size) {
63 val = hif_read32_mb(scn->mem + loc + j);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053064 qdf_mem_copy(temp, &val, 4);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065 j += 4;
66 temp += 4;
67 }
Houston Hoffmanbac94542016-03-14 21:11:59 -070068
69 Q_TARGET_ACCESS_END(scn);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070}
71/*
72 * TBDXXX: Should be a function call specific to each Target-type.
73 * This convoluted macro converts from Target CPU Virtual Address
74 * Space to CE Address Space. As part of this process, we
75 * conservatively fetch the current PCIE_BAR. MOST of the time,
76 * this should match the upper bits of PCI space for this device;
77 * but that's not guaranteed.
78 */
79#ifdef QCA_WIFI_3_0
80#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
81 (scn->mem_pa + addr)
82#else
83#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
84 (((hif_read32_mb((pci_addr) + \
85 (SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
86 | 0x100000 | ((addr) & 0xfffff))
87#endif
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 * Diagnostic read/write access is provided for startup/config/debug usage.
93 * Caller must guarantee proper alignment, when applicable, and single user
94 * at any moment.
95 */
96
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053097QDF_STATUS
Komal Seelam5584a7c2016-02-24 19:22:48 +053098hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
99 uint8_t *data, int nbytes)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100{
Komal Seelam644263d2016-02-22 20:45:49 +0530101 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +0530102 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530103 QDF_STATUS status = QDF_STATUS_SUCCESS;
104 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
106 unsigned int id;
107 unsigned int flags;
108 struct CE_handle *ce_diag;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530109 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
110 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800111 void *data_buf = NULL;
112 int i;
113 unsigned int mux_id = 0;
114 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530115 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116 unsigned int toeplitz_hash_result;
117 unsigned int user_flags = 0;
118
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800119 transaction_id = (mux_id & MUX_ID_MASK) |
120 (transaction_id & TRANSACTION_ID_MASK);
121#ifdef QCA_WIFI_3_0
122 user_flags &= DESC_DATA_FLAG_MASK;
123#endif
124
125 /* This code cannot handle reads to non-memory space. Redirect to the
126 * register read fn but preserve the multi word read capability of
127 * this fn
128 */
129 if (address < DRAM_BASE_ADDRESS) {
130
131 if ((address & 0x3) || ((uintptr_t) data & 0x3))
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530132 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800133
134 while ((nbytes >= 4) &&
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530135 (QDF_STATUS_SUCCESS == (status =
Komal Seelam644263d2016-02-22 20:45:49 +0530136 hif_diag_read_access(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137 (uint32_t *)data)))) {
138
139 nbytes -= sizeof(uint32_t);
140 address += sizeof(uint32_t);
141 data += sizeof(uint32_t);
142
143 }
144
145 return status;
146 }
147 ce_diag = hif_state->ce_diag;
148
149 A_TARGET_ACCESS_LIKELY(scn);
150
151 /*
152 * Allocate a temporary bounce buffer to hold caller's data
153 * to be DMA'ed from Target. This guarantees
154 * 1) 4-byte alignment
155 * 2) Buffer in DMA-able space
156 */
157 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530158 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
159 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160 if (!data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530161 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162 goto done;
163 }
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530164 qdf_mem_set(data_buf, orig_nbytes, 0);
165 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166 orig_nbytes, DMA_FROM_DEVICE);
167
168 remaining_bytes = orig_nbytes;
169 CE_data = CE_data_base;
170 while (remaining_bytes) {
171 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
172 {
173 status = ce_recv_buf_enqueue(ce_diag, NULL, CE_data);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530174 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175 goto done;
176 }
177
178 { /* Request CE to send from Target(!)
179 * address to Host buffer */
180 /*
181 * The address supplied by the caller is in the
182 * Target CPU virtual address space.
183 *
184 * In order to use this address with the diagnostic CE,
185 * convert it from
186 * Target CPU virtual address space
187 * to
188 * CE address space
189 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700190 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700191 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192 ce_phy_addr =
193 TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700194 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700195 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196
197 status =
198 ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
199 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530200 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800201 goto done;
202 }
203
204 i = 0;
205 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
206 &completed_nbytes, &id, NULL, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530207 &toeplitz_hash_result) != QDF_STATUS_SUCCESS) {
208 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530210 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800211 goto done;
212 }
213 }
214 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530215 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 goto done;
217 }
218 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530219 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220 goto done;
221 }
222
223 i = 0;
224 while (ce_completed_recv_next
225 (ce_diag, NULL, NULL, &buf,
226 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530227 &flags) != QDF_STATUS_SUCCESS) {
228 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530230 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231 goto done;
232 }
233 }
234 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530235 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800236 goto done;
237 }
238 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530239 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240 goto done;
241 }
242
243 remaining_bytes -= nbytes;
244 address += nbytes;
245 CE_data += nbytes;
246 }
247
248done:
249 A_TARGET_ACCESS_UNLIKELY(scn);
250
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530251 if (status == QDF_STATUS_SUCCESS)
252 qdf_mem_copy(data, data_buf, orig_nbytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800253 else
254 HIF_ERROR("%s failure (0x%x)", __func__, address);
255
256 if (data_buf)
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530257 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
258 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259
260 return status;
261}
262
263/* Read 4-byte aligned data from Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530264QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265 uint32_t address, uint32_t *data)
266{
Komal Seelam644263d2016-02-22 20:45:49 +0530267 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800269 if (address >= DRAM_BASE_ADDRESS) {
270 /* Assume range doesn't cross this boundary */
Komal Seelam644263d2016-02-22 20:45:49 +0530271 return hif_diag_read_mem(hif_ctx, address, (uint8_t *) data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272 sizeof(uint32_t));
273 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700274 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700275 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 *data = A_TARGET_READ(scn, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700277 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700278 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530280 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281 }
282}
283
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530284QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285 uint32_t address, uint8_t *data, int nbytes)
286{
Komal Seelam644263d2016-02-22 20:45:49 +0530287 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +0530288 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530289 QDF_STATUS status = QDF_STATUS_SUCCESS;
290 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800291 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
292 unsigned int id;
293 unsigned int flags;
294 struct CE_handle *ce_diag;
295 void *data_buf = NULL;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530296 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
297 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298 int i;
299 unsigned int mux_id = 0;
300 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530301 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302 unsigned int toeplitz_hash_result;
303 unsigned int user_flags = 0;
304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305 ce_diag = hif_state->ce_diag;
306 transaction_id = (mux_id & MUX_ID_MASK) |
307 (transaction_id & TRANSACTION_ID_MASK);
308#ifdef QCA_WIFI_3_0
309 user_flags &= DESC_DATA_FLAG_MASK;
310#endif
311
312 A_TARGET_ACCESS_LIKELY(scn);
313
314 /*
315 * Allocate a temporary bounce buffer to hold caller's data
316 * to be DMA'ed to Target. This guarantees
317 * 1) 4-byte alignment
318 * 2) Buffer in DMA-able space
319 */
320 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530321 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
322 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 if (!data_buf) {
324 status = A_NO_MEMORY;
325 goto done;
326 }
327
328 /* Copy caller's data to allocated DMA buf */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530329 qdf_mem_copy(data_buf, data, orig_nbytes);
330 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331 orig_nbytes, DMA_TO_DEVICE);
332
333 /*
334 * The address supplied by the caller is in the
335 * Target CPU virtual address space.
336 *
337 * In order to use this address with the diagnostic CE,
338 * convert it from
339 * Target CPU virtual address space
340 * to
341 * CE address space
342 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700343 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700344 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345 ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700346 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700347 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348
349 remaining_bytes = orig_nbytes;
350 CE_data = CE_data_base;
351 while (remaining_bytes) {
352 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
353
354 { /* Set up to receive directly into Target(!) address */
355 status = ce_recv_buf_enqueue(ce_diag,
356 NULL, ce_phy_addr);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530357 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358 goto done;
359 }
360
361 {
362 /*
363 * Request CE to send caller-supplied data that
364 * was copied to bounce buffer to Target(!) address.
365 */
366 status =
367 ce_send(ce_diag, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530368 (qdf_dma_addr_t) CE_data, nbytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800369 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530370 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800371 goto done;
372 }
373
374 i = 0;
375 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
376 &completed_nbytes, &id,
377 NULL, NULL, &toeplitz_hash_result) !=
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530378 QDF_STATUS_SUCCESS) {
379 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530381 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800382 goto done;
383 }
384 }
385
386 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530387 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 goto done;
389 }
390
391 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530392 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393 goto done;
394 }
395
396 i = 0;
397 while (ce_completed_recv_next
398 (ce_diag, NULL, NULL, &buf,
399 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530400 &flags) != QDF_STATUS_SUCCESS) {
401 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530403 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404 goto done;
405 }
406 }
407
408 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530409 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 goto done;
411 }
412
413 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530414 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 goto done;
416 }
417
418 remaining_bytes -= nbytes;
419 address += nbytes;
420 CE_data += nbytes;
421 }
422
423done:
424 A_TARGET_ACCESS_UNLIKELY(scn);
425
426 if (data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530427 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
428 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 }
430
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530431 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432 HIF_ERROR("%s failure (0x%llu)", __func__,
433 (uint64_t)ce_phy_addr);
434 }
435
436 return status;
437}
438
439/* Write 4B data to Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530440QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *hif_ctx,
Komal Seelam5584a7c2016-02-24 19:22:48 +0530441 uint32_t address, uint32_t data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442{
Komal Seelam644263d2016-02-22 20:45:49 +0530443 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445 if (address >= DRAM_BASE_ADDRESS) {
446 /* Assume range doesn't cross this boundary */
447 uint32_t data_buf = data;
448
Komal Seelam644263d2016-02-22 20:45:49 +0530449 return hif_diag_write_mem(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 (uint8_t *) &data_buf,
451 sizeof(uint32_t));
452 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700453 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700454 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 A_TARGET_WRITE(scn, address, data);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700456 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700457 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530459 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 }
461}