blob: 3ac963c5cdf797ced3f7c2fcf3bfbf4de0329289 [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
28#include <osdep.h>
29#include "a_types.h"
30#include "athdefs.h"
31#include "osapi_linux.h"
32#include "targcfg.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053033#include "qdf_lock.h"
34#include "qdf_status.h"
35#include "qdf_status.h"
36#include <qdf_atomic.h> /* qdf_atomic_read */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080037#include <targaddrs.h>
38#include <bmi_msg.h>
39#include "hif_io32.h"
40#include <hif.h>
41#include <htc_services.h>
42#include "regtable.h"
43#include <a_debug.h>
44#include "hif_main.h"
45#include "ce_api.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053046#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#ifdef CONFIG_CNSS
48#include <net/cnss.h>
49#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include "hif_debug.h"
51#include "epping_main.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052
Komal Seelam5584a7c2016-02-24 19:22:48 +053053void
54hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,
55 uint32_t address, uint32_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056{
Komal Seelam644263d2016-02-22 20:45:49 +053057 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058 uint32_t loc = address;
59 uint32_t val = 0;
60 uint32_t j = 0;
61 u8 *temp = ramdump_base;
62
Houston Hoffmanbac94542016-03-14 21:11:59 -070063 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
64 return;
65
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066 while (j < size) {
67 val = hif_read32_mb(scn->mem + loc + j);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053068 qdf_mem_copy(temp, &val, 4);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069 j += 4;
70 temp += 4;
71 }
Houston Hoffmanbac94542016-03-14 21:11:59 -070072
73 Q_TARGET_ACCESS_END(scn);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080074}
75/*
76 * TBDXXX: Should be a function call specific to each Target-type.
77 * This convoluted macro converts from Target CPU Virtual Address
78 * Space to CE Address Space. As part of this process, we
79 * conservatively fetch the current PCIE_BAR. MOST of the time,
80 * this should match the upper bits of PCI space for this device;
81 * but that's not guaranteed.
82 */
83#ifdef QCA_WIFI_3_0
84#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
85 (scn->mem_pa + addr)
86#else
87#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
88 (((hif_read32_mb((pci_addr) + \
89 (SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
90 | 0x100000 | ((addr) & 0xfffff))
91#endif
92/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
93#define DIAG_ACCESS_CE_TIMEOUT_MS 10
94
95/*
96 * Diagnostic read/write access is provided for startup/config/debug usage.
97 * Caller must guarantee proper alignment, when applicable, and single user
98 * at any moment.
99 */
100
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530101QDF_STATUS
Komal Seelam5584a7c2016-02-24 19:22:48 +0530102hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
103 uint8_t *data, int nbytes)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800104{
Komal Seelam644263d2016-02-22 20:45:49 +0530105 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +0530106 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530107 QDF_STATUS status = QDF_STATUS_SUCCESS;
108 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
110 unsigned int id;
111 unsigned int flags;
112 struct CE_handle *ce_diag;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530113 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
114 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 void *data_buf = NULL;
116 int i;
117 unsigned int mux_id = 0;
118 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530119 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800120 unsigned int toeplitz_hash_result;
121 unsigned int user_flags = 0;
122
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123 transaction_id = (mux_id & MUX_ID_MASK) |
124 (transaction_id & TRANSACTION_ID_MASK);
125#ifdef QCA_WIFI_3_0
126 user_flags &= DESC_DATA_FLAG_MASK;
127#endif
128
129 /* This code cannot handle reads to non-memory space. Redirect to the
130 * register read fn but preserve the multi word read capability of
131 * this fn
132 */
133 if (address < DRAM_BASE_ADDRESS) {
134
135 if ((address & 0x3) || ((uintptr_t) data & 0x3))
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530136 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137
138 while ((nbytes >= 4) &&
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530139 (QDF_STATUS_SUCCESS == (status =
Komal Seelam644263d2016-02-22 20:45:49 +0530140 hif_diag_read_access(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141 (uint32_t *)data)))) {
142
143 nbytes -= sizeof(uint32_t);
144 address += sizeof(uint32_t);
145 data += sizeof(uint32_t);
146
147 }
148
149 return status;
150 }
151 ce_diag = hif_state->ce_diag;
152
153 A_TARGET_ACCESS_LIKELY(scn);
154
155 /*
156 * Allocate a temporary bounce buffer to hold caller's data
157 * to be DMA'ed from Target. This guarantees
158 * 1) 4-byte alignment
159 * 2) Buffer in DMA-able space
160 */
161 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530162 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
163 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164 if (!data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530165 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166 goto done;
167 }
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530168 qdf_mem_set(data_buf, orig_nbytes, 0);
169 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800170 orig_nbytes, DMA_FROM_DEVICE);
171
172 remaining_bytes = orig_nbytes;
173 CE_data = CE_data_base;
174 while (remaining_bytes) {
175 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
176 {
177 status = ce_recv_buf_enqueue(ce_diag, NULL, CE_data);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530178 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 goto done;
180 }
181
182 { /* Request CE to send from Target(!)
183 * address to Host buffer */
184 /*
185 * The address supplied by the caller is in the
186 * Target CPU virtual address space.
187 *
188 * In order to use this address with the diagnostic CE,
189 * convert it from
190 * Target CPU virtual address space
191 * to
192 * CE address space
193 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700194 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700195 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196 ce_phy_addr =
197 TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700198 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700199 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800200
201 status =
202 ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
203 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530204 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205 goto done;
206 }
207
208 i = 0;
209 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
210 &completed_nbytes, &id, NULL, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530211 &toeplitz_hash_result) != QDF_STATUS_SUCCESS) {
212 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530214 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800215 goto done;
216 }
217 }
218 if (nbytes != completed_nbytes) {
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 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530223 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 goto done;
225 }
226
227 i = 0;
228 while (ce_completed_recv_next
229 (ce_diag, NULL, NULL, &buf,
230 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530231 &flags) != QDF_STATUS_SUCCESS) {
232 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530234 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 goto done;
236 }
237 }
238 if (nbytes != completed_nbytes) {
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 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530243 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244 goto done;
245 }
246
247 remaining_bytes -= nbytes;
248 address += nbytes;
249 CE_data += nbytes;
250 }
251
252done:
253 A_TARGET_ACCESS_UNLIKELY(scn);
254
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530255 if (status == QDF_STATUS_SUCCESS)
256 qdf_mem_copy(data, data_buf, orig_nbytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257 else
258 HIF_ERROR("%s failure (0x%x)", __func__, address);
259
260 if (data_buf)
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530261 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
262 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263
264 return status;
265}
266
267/* Read 4-byte aligned data from Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530268QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800269 uint32_t address, uint32_t *data)
270{
Komal Seelam644263d2016-02-22 20:45:49 +0530271 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800273 if (address >= DRAM_BASE_ADDRESS) {
274 /* Assume range doesn't cross this boundary */
Komal Seelam644263d2016-02-22 20:45:49 +0530275 return hif_diag_read_mem(hif_ctx, address, (uint8_t *) data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 sizeof(uint32_t));
277 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700278 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700279 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800280 *data = A_TARGET_READ(scn, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700281 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700282 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530284 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285 }
286}
287
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530288QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800289 uint32_t address, uint8_t *data, int nbytes)
290{
Komal Seelam644263d2016-02-22 20:45:49 +0530291 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +0530292 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530293 QDF_STATUS status = QDF_STATUS_SUCCESS;
294 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
296 unsigned int id;
297 unsigned int flags;
298 struct CE_handle *ce_diag;
299 void *data_buf = NULL;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530300 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
301 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302 int i;
303 unsigned int mux_id = 0;
304 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530305 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800306 unsigned int toeplitz_hash_result;
307 unsigned int user_flags = 0;
308
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309 ce_diag = hif_state->ce_diag;
310 transaction_id = (mux_id & MUX_ID_MASK) |
311 (transaction_id & TRANSACTION_ID_MASK);
312#ifdef QCA_WIFI_3_0
313 user_flags &= DESC_DATA_FLAG_MASK;
314#endif
315
316 A_TARGET_ACCESS_LIKELY(scn);
317
318 /*
319 * Allocate a temporary bounce buffer to hold caller's data
320 * to be DMA'ed to Target. This guarantees
321 * 1) 4-byte alignment
322 * 2) Buffer in DMA-able space
323 */
324 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530325 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
326 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 if (!data_buf) {
328 status = A_NO_MEMORY;
329 goto done;
330 }
331
332 /* Copy caller's data to allocated DMA buf */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530333 qdf_mem_copy(data_buf, data, orig_nbytes);
334 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335 orig_nbytes, DMA_TO_DEVICE);
336
337 /*
338 * The address supplied by the caller is in the
339 * Target CPU virtual address space.
340 *
341 * In order to use this address with the diagnostic CE,
342 * convert it from
343 * Target CPU virtual address space
344 * to
345 * CE address space
346 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700347 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700348 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349 ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700350 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700351 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352
353 remaining_bytes = orig_nbytes;
354 CE_data = CE_data_base;
355 while (remaining_bytes) {
356 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
357
358 { /* Set up to receive directly into Target(!) address */
359 status = ce_recv_buf_enqueue(ce_diag,
360 NULL, ce_phy_addr);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530361 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 goto done;
363 }
364
365 {
366 /*
367 * Request CE to send caller-supplied data that
368 * was copied to bounce buffer to Target(!) address.
369 */
370 status =
371 ce_send(ce_diag, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530372 (qdf_dma_addr_t) CE_data, nbytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800373 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530374 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 goto done;
376 }
377
378 i = 0;
379 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
380 &completed_nbytes, &id,
381 NULL, NULL, &toeplitz_hash_result) !=
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530382 QDF_STATUS_SUCCESS) {
383 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530385 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800386 goto done;
387 }
388 }
389
390 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530391 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800392 goto done;
393 }
394
395 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530396 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800397 goto done;
398 }
399
400 i = 0;
401 while (ce_completed_recv_next
402 (ce_diag, NULL, NULL, &buf,
403 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530404 &flags) != QDF_STATUS_SUCCESS) {
405 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530407 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800408 goto done;
409 }
410 }
411
412 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530413 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 goto done;
415 }
416
417 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530418 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800419 goto done;
420 }
421
422 remaining_bytes -= nbytes;
423 address += nbytes;
424 CE_data += nbytes;
425 }
426
427done:
428 A_TARGET_ACCESS_UNLIKELY(scn);
429
430 if (data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530431 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
432 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433 }
434
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530435 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 HIF_ERROR("%s failure (0x%llu)", __func__,
437 (uint64_t)ce_phy_addr);
438 }
439
440 return status;
441}
442
443/* Write 4B data to Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530444QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *hif_ctx,
Komal Seelam5584a7c2016-02-24 19:22:48 +0530445 uint32_t address, uint32_t data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446{
Komal Seelam644263d2016-02-22 20:45:49 +0530447 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 if (address >= DRAM_BASE_ADDRESS) {
450 /* Assume range doesn't cross this boundary */
451 uint32_t data_buf = data;
452
Komal Seelam644263d2016-02-22 20:45:49 +0530453 return hif_diag_write_mem(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 (uint8_t *) &data_buf,
455 sizeof(uint32_t));
456 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700457 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700458 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 A_TARGET_WRITE(scn, address, data);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700460 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700461 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530463 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 }
465}