blob: ead738709ea59b38d39a0050805974f7207f149e [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>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include "hif_io32.h"
35#include <hif.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036#include "regtable.h"
37#include <a_debug.h>
38#include "hif_main.h"
39#include "ce_api.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053040#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080041#ifdef CONFIG_CNSS
42#include <net/cnss.h>
43#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080044#include "hif_debug.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080045
Komal Seelam5584a7c2016-02-24 19:22:48 +053046void
47hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,
48 uint32_t address, uint32_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080049{
Komal Seelam644263d2016-02-22 20:45:49 +053050 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051 uint32_t loc = address;
52 uint32_t val = 0;
53 uint32_t j = 0;
54 u8 *temp = ramdump_base;
55
Houston Hoffmanbac94542016-03-14 21:11:59 -070056 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
57 return;
58
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059 while (j < size) {
60 val = hif_read32_mb(scn->mem + loc + j);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053061 qdf_mem_copy(temp, &val, 4);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062 j += 4;
63 temp += 4;
64 }
Houston Hoffmanbac94542016-03-14 21:11:59 -070065
66 Q_TARGET_ACCESS_END(scn);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067}
68/*
69 * TBDXXX: Should be a function call specific to each Target-type.
70 * This convoluted macro converts from Target CPU Virtual Address
71 * Space to CE Address Space. As part of this process, we
72 * conservatively fetch the current PCIE_BAR. MOST of the time,
73 * this should match the upper bits of PCI space for this device;
74 * but that's not guaranteed.
75 */
76#ifdef QCA_WIFI_3_0
77#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
78 (scn->mem_pa + addr)
79#else
80#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \
81 (((hif_read32_mb((pci_addr) + \
82 (SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
83 | 0x100000 | ((addr) & 0xfffff))
84#endif
85/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
86#define DIAG_ACCESS_CE_TIMEOUT_MS 10
87
88/*
89 * Diagnostic read/write access is provided for startup/config/debug usage.
90 * Caller must guarantee proper alignment, when applicable, and single user
91 * at any moment.
92 */
93
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053094QDF_STATUS
Komal Seelam5584a7c2016-02-24 19:22:48 +053095hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
96 uint8_t *data, int nbytes)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097{
Komal Seelam644263d2016-02-22 20:45:49 +053098 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +053099 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530100 QDF_STATUS status = QDF_STATUS_SUCCESS;
101 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
103 unsigned int id;
104 unsigned int flags;
105 struct CE_handle *ce_diag;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530106 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
107 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800108 void *data_buf = NULL;
109 int i;
110 unsigned int mux_id = 0;
111 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530112 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800113 unsigned int toeplitz_hash_result;
114 unsigned int user_flags = 0;
115
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116 transaction_id = (mux_id & MUX_ID_MASK) |
117 (transaction_id & TRANSACTION_ID_MASK);
118#ifdef QCA_WIFI_3_0
119 user_flags &= DESC_DATA_FLAG_MASK;
120#endif
121
122 /* This code cannot handle reads to non-memory space. Redirect to the
123 * register read fn but preserve the multi word read capability of
124 * this fn
125 */
126 if (address < DRAM_BASE_ADDRESS) {
127
128 if ((address & 0x3) || ((uintptr_t) data & 0x3))
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530129 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800130
131 while ((nbytes >= 4) &&
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530132 (QDF_STATUS_SUCCESS == (status =
Komal Seelam644263d2016-02-22 20:45:49 +0530133 hif_diag_read_access(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800134 (uint32_t *)data)))) {
135
136 nbytes -= sizeof(uint32_t);
137 address += sizeof(uint32_t);
138 data += sizeof(uint32_t);
139
140 }
141
142 return status;
143 }
144 ce_diag = hif_state->ce_diag;
145
146 A_TARGET_ACCESS_LIKELY(scn);
147
148 /*
149 * Allocate a temporary bounce buffer to hold caller's data
150 * to be DMA'ed from Target. This guarantees
151 * 1) 4-byte alignment
152 * 2) Buffer in DMA-able space
153 */
154 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530155 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
156 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800157 if (!data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530158 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159 goto done;
160 }
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530161 qdf_mem_set(data_buf, orig_nbytes, 0);
162 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163 orig_nbytes, DMA_FROM_DEVICE);
164
165 remaining_bytes = orig_nbytes;
166 CE_data = CE_data_base;
167 while (remaining_bytes) {
168 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
169 {
170 status = ce_recv_buf_enqueue(ce_diag, NULL, CE_data);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530171 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 goto done;
173 }
174
175 { /* Request CE to send from Target(!)
176 * address to Host buffer */
177 /*
178 * The address supplied by the caller is in the
179 * Target CPU virtual address space.
180 *
181 * In order to use this address with the diagnostic CE,
182 * convert it from
183 * Target CPU virtual address space
184 * to
185 * CE address space
186 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700187 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700188 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 ce_phy_addr =
190 TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700191 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700192 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193
194 status =
195 ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
196 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530197 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198 goto done;
199 }
200
201 i = 0;
202 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
203 &completed_nbytes, &id, NULL, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530204 &toeplitz_hash_result) != QDF_STATUS_SUCCESS) {
205 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530207 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208 goto done;
209 }
210 }
211 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530212 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 goto done;
214 }
215 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530216 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217 goto done;
218 }
219
220 i = 0;
221 while (ce_completed_recv_next
222 (ce_diag, NULL, NULL, &buf,
223 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530224 &flags) != QDF_STATUS_SUCCESS) {
225 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530227 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 goto done;
229 }
230 }
231 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530232 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233 goto done;
234 }
235 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530236 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800237 goto done;
238 }
239
240 remaining_bytes -= nbytes;
241 address += nbytes;
242 CE_data += nbytes;
243 }
244
245done:
246 A_TARGET_ACCESS_UNLIKELY(scn);
247
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530248 if (status == QDF_STATUS_SUCCESS)
249 qdf_mem_copy(data, data_buf, orig_nbytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800250 else
251 HIF_ERROR("%s failure (0x%x)", __func__, address);
252
253 if (data_buf)
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530254 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
255 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800256
257 return status;
258}
259
260/* Read 4-byte aligned data from Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530261QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 uint32_t address, uint32_t *data)
263{
Komal Seelam644263d2016-02-22 20:45:49 +0530264 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800266 if (address >= DRAM_BASE_ADDRESS) {
267 /* Assume range doesn't cross this boundary */
Komal Seelam644263d2016-02-22 20:45:49 +0530268 return hif_diag_read_mem(hif_ctx, address, (uint8_t *) data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800269 sizeof(uint32_t));
270 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700271 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700272 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800273 *data = A_TARGET_READ(scn, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700274 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700275 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530277 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278 }
279}
280
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530281QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800282 uint32_t address, uint8_t *data, int nbytes)
283{
Komal Seelam644263d2016-02-22 20:45:49 +0530284 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Komal Seelam02cf2f82016-02-22 20:44:25 +0530285 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530286 QDF_STATUS status = QDF_STATUS_SUCCESS;
287 qdf_dma_addr_t buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800288 unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
289 unsigned int id;
290 unsigned int flags;
291 struct CE_handle *ce_diag;
292 void *data_buf = NULL;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530293 qdf_dma_addr_t CE_data; /* Host buffer address in CE space */
294 qdf_dma_addr_t CE_data_base = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 int i;
296 unsigned int mux_id = 0;
297 unsigned int transaction_id = 0xffff;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530298 qdf_dma_addr_t ce_phy_addr = address;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800299 unsigned int toeplitz_hash_result;
300 unsigned int user_flags = 0;
301
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302 ce_diag = hif_state->ce_diag;
303 transaction_id = (mux_id & MUX_ID_MASK) |
304 (transaction_id & TRANSACTION_ID_MASK);
305#ifdef QCA_WIFI_3_0
306 user_flags &= DESC_DATA_FLAG_MASK;
307#endif
308
309 A_TARGET_ACCESS_LIKELY(scn);
310
311 /*
312 * Allocate a temporary bounce buffer to hold caller's data
313 * to be DMA'ed to Target. This guarantees
314 * 1) 4-byte alignment
315 * 2) Buffer in DMA-able space
316 */
317 orig_nbytes = nbytes;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530318 data_buf = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
319 orig_nbytes, &CE_data_base);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800320 if (!data_buf) {
321 status = A_NO_MEMORY;
322 goto done;
323 }
324
325 /* Copy caller's data to allocated DMA buf */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530326 qdf_mem_copy(data_buf, data, orig_nbytes);
327 qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800328 orig_nbytes, DMA_TO_DEVICE);
329
330 /*
331 * The address supplied by the caller is in the
332 * Target CPU virtual address space.
333 *
334 * In order to use this address with the diagnostic CE,
335 * convert it from
336 * Target CPU virtual address space
337 * to
338 * CE address space
339 */
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700340 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700341 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800342 ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700343 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700344 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345
346 remaining_bytes = orig_nbytes;
347 CE_data = CE_data_base;
348 while (remaining_bytes) {
349 nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
350
351 { /* Set up to receive directly into Target(!) address */
352 status = ce_recv_buf_enqueue(ce_diag,
353 NULL, ce_phy_addr);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530354 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355 goto done;
356 }
357
358 {
359 /*
360 * Request CE to send caller-supplied data that
361 * was copied to bounce buffer to Target(!) address.
362 */
363 status =
364 ce_send(ce_diag, NULL,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530365 (qdf_dma_addr_t) CE_data, nbytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 transaction_id, 0, user_flags);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530367 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368 goto done;
369 }
370
371 i = 0;
372 while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
373 &completed_nbytes, &id,
374 NULL, NULL, &toeplitz_hash_result) !=
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530375 QDF_STATUS_SUCCESS) {
376 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530378 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 goto done;
380 }
381 }
382
383 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530384 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800385 goto done;
386 }
387
388 if (buf != CE_data) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530389 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390 goto done;
391 }
392
393 i = 0;
394 while (ce_completed_recv_next
395 (ce_diag, NULL, NULL, &buf,
396 &completed_nbytes, &id,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530397 &flags) != QDF_STATUS_SUCCESS) {
398 qdf_mdelay(1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530400 status = QDF_STATUS_E_BUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800401 goto done;
402 }
403 }
404
405 if (nbytes != completed_nbytes) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530406 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 goto done;
408 }
409
410 if (buf != ce_phy_addr) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530411 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412 goto done;
413 }
414
415 remaining_bytes -= nbytes;
416 address += nbytes;
417 CE_data += nbytes;
418 }
419
420done:
421 A_TARGET_ACCESS_UNLIKELY(scn);
422
423 if (data_buf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530424 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
425 orig_nbytes, data_buf, CE_data_base, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 }
427
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530428 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 HIF_ERROR("%s failure (0x%llu)", __func__,
430 (uint64_t)ce_phy_addr);
431 }
432
433 return status;
434}
435
436/* Write 4B data to Target memory or register */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530437QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *hif_ctx,
Komal Seelam5584a7c2016-02-24 19:22:48 +0530438 uint32_t address, uint32_t data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439{
Komal Seelam644263d2016-02-22 20:45:49 +0530440 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 if (address >= DRAM_BASE_ADDRESS) {
443 /* Assume range doesn't cross this boundary */
444 uint32_t data_buf = data;
445
Komal Seelam644263d2016-02-22 20:45:49 +0530446 return hif_diag_write_mem(hif_ctx, address,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 (uint8_t *) &data_buf,
448 sizeof(uint32_t));
449 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700450 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700451 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 A_TARGET_WRITE(scn, address, data);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700453 if (Q_TARGET_ACCESS_END(scn) < 0)
Houston Hoffman987ab442016-03-14 21:12:02 -0700454 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530456 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 }
458}