blob: d79ba203e761ed3c3c8a8e45b655a6210c3d4ff9 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
2 * Copyright (c) 2013-2015 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#include <osdep.h>
28#include "a_types.h"
29#include "athdefs.h"
30#include "osapi_linux.h"
31#include "targcfg.h"
32#include "cdf_lock.h"
33#include "cdf_status.h"
34#include <cdf_atomic.h> /* cdf_atomic_read */
35#include <targaddrs.h>
36#include <bmi_msg.h>
37#include "hif_io32.h"
38#include <hif.h>
39#include "regtable.h"
40#define ATH_MODULE_NAME hif
41#include <a_debug.h>
42#include "hif_main.h"
43#ifdef HIF_PCI
44#include "ce_bmi.h"
45#endif
46#include "ce_api.h"
47#include "cdf_trace.h"
48#include "cds_api.h"
49#ifdef CONFIG_CNSS
50#include <net/cnss.h>
51#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080052#include "epping_main.h"
53#include "hif_debug.h"
54#include "ce_internal.h"
55#include "ce_reg.h"
56#include "ce_assignment.h"
57#include "ce_tasklet.h"
58#ifdef HIF_PCI
59#include "icnss_stub.h"
60#else
61#include <soc/qcom/icnss.h>
62#endif
63#include "qwlan_version.h"
Chandrasekaran, Manishekar681d1372015-11-05 10:42:48 +053064#include "cds_concurrency.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080065
66#define CE_POLL_TIMEOUT 10 /* ms */
67
68/* Forward references */
69static int hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info);
70
71/*
72 * Fix EV118783, poll to check whether a BMI response comes
73 * other than waiting for the interruption which may be lost.
74 */
75/* #define BMI_RSP_POLLING */
76#define BMI_RSP_TO_MILLISEC 1000
77
78
79static int hif_post_recv_buffers(struct ol_softc *scn);
80
81static void ce_poll_timeout(void *arg)
82{
83 struct CE_state *CE_state = (struct CE_state *)arg;
84 if (CE_state->timer_inited) {
85 ce_per_engine_service(CE_state->scn, CE_state->id);
86 cdf_softirq_timer_mod(&CE_state->poll_timer, CE_POLL_TIMEOUT);
87 }
88}
89
90static unsigned int roundup_pwr2(unsigned int n)
91{
92 int i;
93 unsigned int test_pwr2;
94
95 if (!(n & (n - 1)))
96 return n; /* already a power of 2 */
97
98 test_pwr2 = 4;
99 for (i = 0; i < 29; i++) {
100 if (test_pwr2 > n)
101 return test_pwr2;
102 test_pwr2 = test_pwr2 << 1;
103 }
104
105 CDF_ASSERT(0); /* n too large */
106 return 0;
107}
108
109/*
110 * Initialize a Copy Engine based on caller-supplied attributes.
111 * This may be called once to initialize both source and destination
112 * rings or it may be called twice for separate source and destination
113 * initialization. It may be that only one side or the other is
114 * initialized by software/firmware.
115 */
116struct CE_handle *ce_init(struct ol_softc *scn,
117 unsigned int CE_id, struct CE_attr *attr)
118{
119 struct CE_state *CE_state;
120 uint32_t ctrl_addr;
121 unsigned int nentries;
122 cdf_dma_addr_t base_addr;
123 bool malloc_CE_state = false;
124 bool malloc_src_ring = false;
125
126 CDF_ASSERT(CE_id < scn->ce_count);
127 ctrl_addr = CE_BASE_ADDRESS(CE_id);
128 cdf_spin_lock(&scn->target_lock);
129 CE_state = scn->ce_id_to_state[CE_id];
130
131 if (!CE_state) {
132 cdf_spin_unlock(&scn->target_lock);
133 CE_state =
134 (struct CE_state *)cdf_mem_malloc(sizeof(*CE_state));
135 if (!CE_state) {
136 HIF_ERROR("%s: CE_state has no mem", __func__);
137 return NULL;
138 } else
139 malloc_CE_state = true;
140 cdf_mem_zero(CE_state, sizeof(*CE_state));
141 cdf_spin_lock(&scn->target_lock);
142 if (!scn->ce_id_to_state[CE_id]) { /* re-check under lock */
143 scn->ce_id_to_state[CE_id] = CE_state;
144
145 CE_state->id = CE_id;
146 CE_state->ctrl_addr = ctrl_addr;
147 CE_state->state = CE_RUNNING;
148 CE_state->attr_flags = attr->flags;
149 } else {
150 /*
151 * We released target_lock in order to allocate
152 * CE state, but someone else beat us to it.
153 * Continue, using that CE_state
154 * (and free the one we allocated).
155 */
156 cdf_mem_free(CE_state);
157 malloc_CE_state = false;
158 CE_state = scn->ce_id_to_state[CE_id];
159 }
160 }
161 CE_state->scn = scn;
162 cdf_spin_unlock(&scn->target_lock);
163
164 cdf_atomic_init(&CE_state->rx_pending);
165 if (attr == NULL) {
166 /* Already initialized; caller wants the handle */
167 return (struct CE_handle *)CE_state;
168 }
169
170#ifdef ADRASTEA_SHADOW_REGISTERS
171 HIF_ERROR("%s: Using Shadow Registers instead of CE Registers\n",
172 __func__);
173#endif
174
175 if (CE_state->src_sz_max)
176 CDF_ASSERT(CE_state->src_sz_max == attr->src_sz_max);
177 else
178 CE_state->src_sz_max = attr->src_sz_max;
179
180 /* source ring setup */
181 nentries = attr->src_nentries;
182 if (nentries) {
183 struct CE_ring_state *src_ring;
184 unsigned CE_nbytes;
185 char *ptr;
186 uint64_t dma_addr;
187 nentries = roundup_pwr2(nentries);
188 if (CE_state->src_ring) {
189 CDF_ASSERT(CE_state->src_ring->nentries == nentries);
190 } else {
191 CE_nbytes = sizeof(struct CE_ring_state)
192 + (nentries * sizeof(void *));
193 ptr = cdf_mem_malloc(CE_nbytes);
194 if (!ptr) {
195 /* cannot allocate src ring. If the
196 * CE_state is allocated locally free
197 * CE_State and return error.
198 */
199 HIF_ERROR("%s: src ring has no mem", __func__);
200 if (malloc_CE_state) {
201 /* allocated CE_state locally */
202 cdf_spin_lock(&scn->target_lock);
203 scn->ce_id_to_state[CE_id] = NULL;
204 cdf_spin_unlock(&scn->target_lock);
205 cdf_mem_free(CE_state);
206 malloc_CE_state = false;
207 }
208 return NULL;
209 } else {
210 /* we can allocate src ring.
211 * Mark that the src ring is
212 * allocated locally
213 */
214 malloc_src_ring = true;
215 }
216 cdf_mem_zero(ptr, CE_nbytes);
217
218 src_ring = CE_state->src_ring =
219 (struct CE_ring_state *)ptr;
220 ptr += sizeof(struct CE_ring_state);
221 src_ring->nentries = nentries;
222 src_ring->nentries_mask = nentries - 1;
223 A_TARGET_ACCESS_BEGIN_RET_PTR(scn);
224 src_ring->hw_index =
225 CE_SRC_RING_READ_IDX_GET(scn, ctrl_addr);
226 src_ring->sw_index = src_ring->hw_index;
227 src_ring->write_index =
228 CE_SRC_RING_WRITE_IDX_GET(scn, ctrl_addr);
229 A_TARGET_ACCESS_END_RET_PTR(scn);
230 src_ring->low_water_mark_nentries = 0;
231 src_ring->high_water_mark_nentries = nentries;
232 src_ring->per_transfer_context = (void **)ptr;
233
234 /* Legacy platforms that do not support cache
235 * coherent DMA are unsupported
236 */
237 src_ring->base_addr_owner_space_unaligned =
238 cdf_os_mem_alloc_consistent(scn->cdf_dev,
239 (nentries *
240 sizeof(struct CE_src_desc) +
241 CE_DESC_RING_ALIGN),
242 &base_addr, 0);
243 if (src_ring->base_addr_owner_space_unaligned
244 == NULL) {
245 HIF_ERROR("%s: src ring has no DMA mem",
246 __func__);
247 goto error_no_dma_mem;
248 }
249 src_ring->base_addr_CE_space_unaligned = base_addr;
250
251 if (src_ring->
252 base_addr_CE_space_unaligned & (CE_DESC_RING_ALIGN
253 - 1)) {
254 src_ring->base_addr_CE_space =
255 (src_ring->base_addr_CE_space_unaligned
256 + CE_DESC_RING_ALIGN -
257 1) & ~(CE_DESC_RING_ALIGN - 1);
258
259 src_ring->base_addr_owner_space =
260 (void
261 *)(((size_t) src_ring->
262 base_addr_owner_space_unaligned +
263 CE_DESC_RING_ALIGN -
264 1) & ~(CE_DESC_RING_ALIGN - 1));
265 } else {
266 src_ring->base_addr_CE_space =
267 src_ring->base_addr_CE_space_unaligned;
268 src_ring->base_addr_owner_space =
269 src_ring->
270 base_addr_owner_space_unaligned;
271 }
272 /*
273 * Also allocate a shadow src ring in
274 * regular mem to use for faster access.
275 */
276 src_ring->shadow_base_unaligned =
277 cdf_mem_malloc(nentries *
278 sizeof(struct CE_src_desc) +
279 CE_DESC_RING_ALIGN);
280 if (src_ring->shadow_base_unaligned == NULL) {
281 HIF_ERROR("%s: src ring no shadow_base mem",
282 __func__);
283 goto error_no_dma_mem;
284 }
285 src_ring->shadow_base = (struct CE_src_desc *)
286 (((size_t) src_ring->shadow_base_unaligned +
287 CE_DESC_RING_ALIGN - 1) &
288 ~(CE_DESC_RING_ALIGN - 1));
289
290 A_TARGET_ACCESS_BEGIN_RET_PTR(scn);
291 dma_addr = src_ring->base_addr_CE_space;
292 CE_SRC_RING_BASE_ADDR_SET(scn, ctrl_addr,
293 (uint32_t)(dma_addr & 0xFFFFFFFF));
294#ifdef WLAN_ENABLE_QCA6180
295 {
296 uint32_t tmp;
297 tmp = CE_SRC_RING_BASE_ADDR_HIGH_GET(
298 scn, ctrl_addr);
299 tmp &= ~0x1F;
300 dma_addr = ((dma_addr >> 32) & 0x1F)|tmp;
301 CE_SRC_RING_BASE_ADDR_HIGH_SET(scn,
302 ctrl_addr, (uint32_t)dma_addr);
303 }
304#endif
305 CE_SRC_RING_SZ_SET(scn, ctrl_addr, nentries);
306 CE_SRC_RING_DMAX_SET(scn, ctrl_addr, attr->src_sz_max);
307#ifdef BIG_ENDIAN_HOST
308 /* Enable source ring byte swap for big endian host */
309 CE_SRC_RING_BYTE_SWAP_SET(scn, ctrl_addr, 1);
310#endif
311 CE_SRC_RING_LOWMARK_SET(scn, ctrl_addr, 0);
312 CE_SRC_RING_HIGHMARK_SET(scn, ctrl_addr, nentries);
313 A_TARGET_ACCESS_END_RET_PTR(scn);
314 }
315 }
316
317 /* destination ring setup */
318 nentries = attr->dest_nentries;
319 if (nentries) {
320 struct CE_ring_state *dest_ring;
321 unsigned CE_nbytes;
322 char *ptr;
323 uint64_t dma_addr;
324
325 nentries = roundup_pwr2(nentries);
326 if (CE_state->dest_ring) {
327 CDF_ASSERT(CE_state->dest_ring->nentries == nentries);
328 } else {
329 CE_nbytes = sizeof(struct CE_ring_state)
330 + (nentries * sizeof(void *));
331 ptr = cdf_mem_malloc(CE_nbytes);
332 if (!ptr) {
333 /* cannot allocate dst ring. If the CE_state
334 * or src ring is allocated locally free
335 * CE_State and src ring and return error.
336 */
337 HIF_ERROR("%s: dest ring has no mem",
338 __func__);
339 if (malloc_src_ring) {
340 cdf_mem_free(CE_state->src_ring);
341 CE_state->src_ring = NULL;
342 malloc_src_ring = false;
343 }
344 if (malloc_CE_state) {
345 /* allocated CE_state locally */
346 cdf_spin_lock(&scn->target_lock);
347 scn->ce_id_to_state[CE_id] = NULL;
348 cdf_spin_unlock(&scn->target_lock);
349 cdf_mem_free(CE_state);
350 malloc_CE_state = false;
351 }
352 return NULL;
353 }
354 cdf_mem_zero(ptr, CE_nbytes);
355
356 dest_ring = CE_state->dest_ring =
357 (struct CE_ring_state *)ptr;
358 ptr += sizeof(struct CE_ring_state);
359 dest_ring->nentries = nentries;
360 dest_ring->nentries_mask = nentries - 1;
361 A_TARGET_ACCESS_BEGIN_RET_PTR(scn);
362 dest_ring->sw_index =
363 CE_DEST_RING_READ_IDX_GET(scn, ctrl_addr);
364 dest_ring->write_index =
365 CE_DEST_RING_WRITE_IDX_GET(scn, ctrl_addr);
366 A_TARGET_ACCESS_END_RET_PTR(scn);
367 dest_ring->low_water_mark_nentries = 0;
368 dest_ring->high_water_mark_nentries = nentries;
369 dest_ring->per_transfer_context = (void **)ptr;
370
371 /* Legacy platforms that do not support cache
372 * coherent DMA are unsupported */
373 dest_ring->base_addr_owner_space_unaligned =
374 cdf_os_mem_alloc_consistent(scn->cdf_dev,
375 (nentries *
376 sizeof(struct CE_dest_desc) +
377 CE_DESC_RING_ALIGN),
378 &base_addr, 0);
379 if (dest_ring->base_addr_owner_space_unaligned
380 == NULL) {
381 HIF_ERROR("%s: dest ring has no DMA mem",
382 __func__);
383 goto error_no_dma_mem;
384 }
385 dest_ring->base_addr_CE_space_unaligned = base_addr;
386
387 /* Correctly initialize memory to 0 to
388 * prevent garbage data crashing system
389 * when download firmware
390 */
391 cdf_mem_zero(dest_ring->base_addr_owner_space_unaligned,
392 nentries * sizeof(struct CE_dest_desc) +
393 CE_DESC_RING_ALIGN);
394
395 if (dest_ring->
396 base_addr_CE_space_unaligned & (CE_DESC_RING_ALIGN -
397 1)) {
398
399 dest_ring->base_addr_CE_space =
400 (dest_ring->
401 base_addr_CE_space_unaligned +
402 CE_DESC_RING_ALIGN -
403 1) & ~(CE_DESC_RING_ALIGN - 1);
404
405 dest_ring->base_addr_owner_space =
406 (void
407 *)(((size_t) dest_ring->
408 base_addr_owner_space_unaligned +
409 CE_DESC_RING_ALIGN -
410 1) & ~(CE_DESC_RING_ALIGN - 1));
411 } else {
412 dest_ring->base_addr_CE_space =
413 dest_ring->base_addr_CE_space_unaligned;
414 dest_ring->base_addr_owner_space =
415 dest_ring->
416 base_addr_owner_space_unaligned;
417 }
418
419 A_TARGET_ACCESS_BEGIN_RET_PTR(scn);
420 dma_addr = dest_ring->base_addr_CE_space;
421 CE_DEST_RING_BASE_ADDR_SET(scn, ctrl_addr,
422 (uint32_t)(dma_addr & 0xFFFFFFFF));
423#ifdef WLAN_ENABLE_QCA6180
424 {
425 uint32_t tmp;
426 tmp = CE_DEST_RING_BASE_ADDR_HIGH_GET(scn,
427 ctrl_addr);
428 tmp &= ~0x1F;
429 dma_addr = ((dma_addr >> 32) & 0x1F)|tmp;
430 CE_DEST_RING_BASE_ADDR_HIGH_SET(scn,
431 ctrl_addr, (uint32_t)dma_addr);
432 }
433#endif
434 CE_DEST_RING_SZ_SET(scn, ctrl_addr, nentries);
435#ifdef BIG_ENDIAN_HOST
436 /* Enable Dest ring byte swap for big endian host */
437 CE_DEST_RING_BYTE_SWAP_SET(scn, ctrl_addr, 1);
438#endif
439 CE_DEST_RING_LOWMARK_SET(scn, ctrl_addr, 0);
440 CE_DEST_RING_HIGHMARK_SET(scn, ctrl_addr, nentries);
441 A_TARGET_ACCESS_END_RET_PTR(scn);
442
443 /* epping */
444 /* poll timer */
445 if ((CE_state->attr_flags & CE_ATTR_ENABLE_POLL)) {
446 cdf_softirq_timer_init(scn->cdf_dev,
447 &CE_state->poll_timer,
448 ce_poll_timeout,
449 CE_state,
450 CDF_TIMER_TYPE_SW);
451 CE_state->timer_inited = true;
452 cdf_softirq_timer_mod(&CE_state->poll_timer,
453 CE_POLL_TIMEOUT);
454 }
455 }
456 }
457
458 /* Enable CE error interrupts */
459 A_TARGET_ACCESS_BEGIN_RET_PTR(scn);
460 CE_ERROR_INTR_ENABLE(scn, ctrl_addr);
461 A_TARGET_ACCESS_END_RET_PTR(scn);
462
463 return (struct CE_handle *)CE_state;
464
465error_no_dma_mem:
466 ce_fini((struct CE_handle *)CE_state);
467 return NULL;
468}
469
470#ifdef WLAN_FEATURE_FASTPATH
471/**
472 * ce_h2t_tx_ce_cleanup() Place holder function for H2T CE cleanup.
473 * No processing is required inside this function.
474 * @ce_hdl: Cope engine handle
475 * Using an assert, this function makes sure that,
476 * the TX CE has been processed completely.
477 * Return: none
478 */
479void
480ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl)
481{
482 struct CE_state *ce_state = (struct CE_state *)ce_hdl;
483 struct CE_ring_state *src_ring = ce_state->src_ring;
484 struct ol_softc *sc = ce_state->scn;
485 uint32_t sw_index, write_index;
486
487 if (sc->fastpath_mode_on && (ce_state->id == CE_HTT_H2T_MSG)) {
488 HIF_INFO("%s %d Fastpath mode ON, Cleaning up HTT Tx CE\n",
489 __func__, __LINE__);
490 cdf_spin_lock_bh(&sc->target_lock);
491 sw_index = src_ring->sw_index;
492 write_index = src_ring->sw_index;
493 cdf_spin_unlock_bh(&sc->target_lock);
494
495 /* At this point Tx CE should be clean */
496 cdf_assert_always(sw_index == write_index);
497 }
498}
499#else
500void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl)
501{
502}
503#endif /* WLAN_FEATURE_FASTPATH */
504
505void ce_fini(struct CE_handle *copyeng)
506{
507 struct CE_state *CE_state = (struct CE_state *)copyeng;
508 unsigned int CE_id = CE_state->id;
509 struct ol_softc *scn = CE_state->scn;
510
511 CE_state->state = CE_UNUSED;
512 scn->ce_id_to_state[CE_id] = NULL;
513 if (CE_state->src_ring) {
514 /* Cleanup the HTT Tx ring */
515 ce_h2t_tx_ce_cleanup(copyeng);
516
517 if (CE_state->src_ring->shadow_base_unaligned)
518 cdf_mem_free(CE_state->src_ring->shadow_base_unaligned);
519 if (CE_state->src_ring->base_addr_owner_space_unaligned)
520 cdf_os_mem_free_consistent(scn->cdf_dev,
521 (CE_state->src_ring->nentries *
522 sizeof(struct CE_src_desc) +
523 CE_DESC_RING_ALIGN),
524 CE_state->src_ring->
525 base_addr_owner_space_unaligned,
526 CE_state->src_ring->
527 base_addr_CE_space, 0);
528 cdf_mem_free(CE_state->src_ring);
529 }
530 if (CE_state->dest_ring) {
531 if (CE_state->dest_ring->base_addr_owner_space_unaligned)
532 cdf_os_mem_free_consistent(scn->cdf_dev,
533 (CE_state->dest_ring->nentries *
534 sizeof(struct CE_dest_desc) +
535 CE_DESC_RING_ALIGN),
536 CE_state->dest_ring->
537 base_addr_owner_space_unaligned,
538 CE_state->dest_ring->
539 base_addr_CE_space, 0);
540 cdf_mem_free(CE_state->dest_ring);
541
542 /* epping */
543 if (CE_state->timer_inited) {
544 CE_state->timer_inited = false;
545 cdf_softirq_timer_free(&CE_state->poll_timer);
546 }
547 }
548 cdf_mem_free(CE_state);
549}
550
551void hif_detach_htc(struct ol_softc *scn)
552{
553 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
554
555 cdf_mem_zero(&hif_state->msg_callbacks_pending,
556 sizeof(hif_state->msg_callbacks_pending));
557 cdf_mem_zero(&hif_state->msg_callbacks_current,
558 sizeof(hif_state->msg_callbacks_current));
559}
560
561/* Send the first nbytes bytes of the buffer */
562CDF_STATUS
563hif_send_head(struct ol_softc *scn,
564 uint8_t pipe, unsigned int transfer_id, unsigned int nbytes,
565 cdf_nbuf_t nbuf, unsigned int data_attr)
566{
567 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
568 struct HIF_CE_pipe_info *pipe_info = &(hif_state->pipe_info[pipe]);
569 struct CE_handle *ce_hdl = pipe_info->ce_hdl;
570 int bytes = nbytes, nfrags = 0;
571 struct ce_sendlist sendlist;
572 int status, i = 0;
573 unsigned int mux_id = 0;
574
575 CDF_ASSERT(nbytes <= cdf_nbuf_len(nbuf));
576
577 transfer_id =
578 (mux_id & MUX_ID_MASK) |
579 (transfer_id & TRANSACTION_ID_MASK);
580 data_attr &= DESC_DATA_FLAG_MASK;
581 /*
582 * The common case involves sending multiple fragments within a
583 * single download (the tx descriptor and the tx frame header).
584 * So, optimize for the case of multiple fragments by not even
585 * checking whether it's necessary to use a sendlist.
586 * The overhead of using a sendlist for a single buffer download
587 * is not a big deal, since it happens rarely (for WMI messages).
588 */
589 ce_sendlist_init(&sendlist);
590 do {
591 uint32_t frag_paddr;
592 int frag_bytes;
593
594 frag_paddr = cdf_nbuf_get_frag_paddr_lo(nbuf, nfrags);
595 frag_bytes = cdf_nbuf_get_frag_len(nbuf, nfrags);
596 /*
597 * Clear the packet offset for all but the first CE desc.
598 */
599 if (i++ > 0)
600 data_attr &= ~CDF_CE_TX_PKT_OFFSET_BIT_M;
601
602 status = ce_sendlist_buf_add(&sendlist, frag_paddr,
603 frag_bytes >
604 bytes ? bytes : frag_bytes,
605 cdf_nbuf_get_frag_is_wordstream
606 (nbuf,
607 nfrags) ? 0 :
608 CE_SEND_FLAG_SWAP_DISABLE,
609 data_attr);
610 if (status != CDF_STATUS_SUCCESS) {
611 HIF_ERROR("%s: error, frag_num %d larger than limit",
612 __func__, nfrags);
613 return status;
614 }
615 bytes -= frag_bytes;
616 nfrags++;
617 } while (bytes > 0);
618
619 /* Make sure we have resources to handle this request */
620 cdf_spin_lock_bh(&pipe_info->completion_freeq_lock);
621 if (pipe_info->num_sends_allowed < nfrags) {
622 cdf_spin_unlock_bh(&pipe_info->completion_freeq_lock);
623 ce_pkt_error_count_incr(hif_state, HIF_PIPE_NO_RESOURCE);
624 return CDF_STATUS_E_RESOURCES;
625 }
626 pipe_info->num_sends_allowed -= nfrags;
627 cdf_spin_unlock_bh(&pipe_info->completion_freeq_lock);
628
629 if (cdf_unlikely(ce_hdl == NULL)) {
630 HIF_ERROR("%s: error CE handle is null", __func__);
631 return A_ERROR;
632 }
633
634 NBUF_UPDATE_TX_PKT_COUNT(nbuf, NBUF_TX_PKT_HIF);
635 DPTRACE(cdf_dp_trace(nbuf, CDF_DP_TRACE_HIF_PACKET_PTR_RECORD,
636 (uint8_t *)(cdf_nbuf_data(nbuf)),
637 sizeof(cdf_nbuf_data(nbuf))));
638 status = ce_sendlist_send(ce_hdl, nbuf, &sendlist, transfer_id);
639 CDF_ASSERT(status == CDF_STATUS_SUCCESS);
640
641 return status;
642}
643
644void hif_send_complete_check(struct ol_softc *scn, uint8_t pipe, int force)
645{
646 if (!force) {
647 int resources;
648 /*
649 * Decide whether to actually poll for completions, or just
650 * wait for a later chance. If there seem to be plenty of
651 * resources left, then just wait, since checking involves
652 * reading a CE register, which is a relatively expensive
653 * operation.
654 */
655 resources = hif_get_free_queue_number(scn, pipe);
656 /*
657 * If at least 50% of the total resources are still available,
658 * don't bother checking again yet.
659 */
660 if (resources > (host_ce_config[pipe].src_nentries >> 1)) {
661 return;
662 }
663 }
664#ifdef ATH_11AC_TXCOMPACT
665 ce_per_engine_servicereap(scn, pipe);
666#else
667 ce_per_engine_service(scn, pipe);
668#endif
669}
670
671uint16_t hif_get_free_queue_number(struct ol_softc *scn, uint8_t pipe)
672{
673 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
674 struct HIF_CE_pipe_info *pipe_info = &(hif_state->pipe_info[pipe]);
675 uint16_t rv;
676
677 cdf_spin_lock_bh(&pipe_info->completion_freeq_lock);
678 rv = pipe_info->num_sends_allowed;
679 cdf_spin_unlock_bh(&pipe_info->completion_freeq_lock);
680 return rv;
681}
682
683/* Called by lower (CE) layer when a send to Target completes. */
684void
685hif_pci_ce_send_done(struct CE_handle *copyeng, void *ce_context,
686 void *transfer_context, cdf_dma_addr_t CE_data,
687 unsigned int nbytes, unsigned int transfer_id,
688 unsigned int sw_index, unsigned int hw_index,
689 unsigned int toeplitz_hash_result)
690{
691 struct HIF_CE_pipe_info *pipe_info =
692 (struct HIF_CE_pipe_info *)ce_context;
693 struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state;
694 struct HIF_CE_completion_state *compl_state;
695 struct HIF_CE_completion_state *compl_queue_head, *compl_queue_tail;
696 unsigned int sw_idx = sw_index, hw_idx = hw_index;
697
698 compl_queue_head = compl_queue_tail = NULL;
699 do {
700 /*
701 * For the send completion of an item in sendlist, just increment
702 * num_sends_allowed. The upper layer callback will be triggered
703 * when last fragment is done with send.
704 */
705 if (transfer_context == CE_SENDLIST_ITEM_CTXT) {
706 cdf_spin_lock(&pipe_info->completion_freeq_lock);
707 pipe_info->num_sends_allowed++;
708 cdf_spin_unlock(&pipe_info->completion_freeq_lock);
709 continue;
710 }
711
712 cdf_spin_lock(&pipe_info->completion_freeq_lock);
713 compl_state = pipe_info->completion_freeq_head;
714 if (!compl_state) {
715 cdf_spin_unlock(&pipe_info->completion_freeq_lock);
716 HIF_ERROR("%s: ce_id:%d num_allowed:%d pipe_info:%p",
717 __func__, pipe_info->pipe_num,
718 pipe_info->num_sends_allowed,
719 pipe_info);
720 ASSERT(0);
721 break;
722 }
723 pipe_info->completion_freeq_head = compl_state->next;
724 cdf_spin_unlock(&pipe_info->completion_freeq_lock);
725
726 compl_state->next = NULL;
727 compl_state->send_or_recv = HIF_CE_COMPLETE_SEND;
728 compl_state->copyeng = copyeng;
729 compl_state->ce_context = ce_context;
730 compl_state->transfer_context = transfer_context;
731 compl_state->data = CE_data;
732 compl_state->nbytes = nbytes;
733 compl_state->transfer_id = transfer_id;
734 compl_state->flags = 0;
735 compl_state->toeplitz_hash_result = toeplitz_hash_result;
736
737 /* Enqueue at end of local queue */
738 if (compl_queue_tail) {
739 compl_queue_tail->next = compl_state;
740 } else {
741 compl_queue_head = compl_state;
742 }
743 compl_queue_tail = compl_state;
744 } while (ce_completed_send_next(copyeng,
745 &ce_context, &transfer_context,
746 &CE_data, &nbytes, &transfer_id,
747 &sw_idx, &hw_idx,
748 &toeplitz_hash_result) == CDF_STATUS_SUCCESS);
749
750 if (compl_queue_head == NULL) {
751 /*
752 * If only some of the items within a sendlist have completed,
753 * don't invoke completion processing until the entire sendlist
754 * has been sent.
755 */
756 return;
757 }
758
759 cdf_spin_lock(&hif_state->completion_pendingq_lock);
760
761 /* Enqueue the local completion queue on the
762 * per-device completion queue */
763 if (hif_state->completion_pendingq_head) {
764 hif_state->completion_pendingq_tail->next = compl_queue_head;
765 hif_state->completion_pendingq_tail = compl_queue_tail;
766 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
767 } else {
768 hif_state->completion_pendingq_head = compl_queue_head;
769 hif_state->completion_pendingq_tail = compl_queue_tail;
770 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
771
772 /* Alert the send completion service thread */
773 hif_completion_thread(hif_state);
774 }
775}
776
777/* Called by lower (CE) layer when data is received from the Target. */
778void
779hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
780 void *transfer_context, cdf_dma_addr_t CE_data,
781 unsigned int nbytes, unsigned int transfer_id,
782 unsigned int flags)
783{
784 struct HIF_CE_pipe_info *pipe_info =
785 (struct HIF_CE_pipe_info *)ce_context;
786 struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state;
787 struct ol_softc *scn = hif_state->scn;
788 struct HIF_CE_completion_state *compl_state;
789 struct HIF_CE_completion_state *compl_queue_head, *compl_queue_tail;
790
791 compl_queue_head = compl_queue_tail = NULL;
792 do {
793 cdf_spin_lock(&pipe_info->completion_freeq_lock);
794 compl_state = pipe_info->completion_freeq_head;
795 ASSERT(compl_state != NULL);
796 pipe_info->completion_freeq_head = compl_state->next;
797 cdf_spin_unlock(&pipe_info->completion_freeq_lock);
798
799 compl_state->next = NULL;
800 compl_state->send_or_recv = HIF_CE_COMPLETE_RECV;
801 compl_state->copyeng = copyeng;
802 compl_state->ce_context = ce_context;
803 compl_state->transfer_context = transfer_context;
804 compl_state->data = CE_data;
805 compl_state->nbytes = nbytes;
806 compl_state->transfer_id = transfer_id;
807 compl_state->flags = flags;
808
809 /* Enqueue at end of local queue */
810 if (compl_queue_tail) {
811 compl_queue_tail->next = compl_state;
812 } else {
813 compl_queue_head = compl_state;
814 }
815 compl_queue_tail = compl_state;
816
817 cdf_nbuf_unmap_single(scn->cdf_dev,
818 (cdf_nbuf_t) transfer_context,
819 CDF_DMA_FROM_DEVICE);
820
821 /*
822 * EV #112693 - [Peregrine][ES1][WB342][Win8x86][Performance]
823 * BSoD_0x133 occurred in VHT80 UDP_DL
824 * Break out DPC by force if number of loops in
825 * hif_pci_ce_recv_data reaches MAX_NUM_OF_RECEIVES to avoid
826 * spending too long time in DPC for each interrupt handling.
827 * Schedule another DPC to avoid data loss if we had taken
828 * force-break action before apply to Windows OS only
829 * currently, Linux/MAC os can expand to their platform
830 * if necessary
831 */
832
833 /* Set up force_break flag if num of receices reaches
834 * MAX_NUM_OF_RECEIVES */
835 scn->receive_count++;
836 if (cdf_unlikely(hif_max_num_receives_reached(
837 scn->receive_count))) {
838 scn->force_break = 1;
839 break;
840 }
841 } while (ce_completed_recv_next(copyeng, &ce_context, &transfer_context,
842 &CE_data, &nbytes, &transfer_id,
843 &flags) == CDF_STATUS_SUCCESS);
844
845 cdf_spin_lock(&hif_state->completion_pendingq_lock);
846
847 /* Enqueue the local completion queue on the
848 * per-device completion queue */
849 if (hif_state->completion_pendingq_head) {
850 hif_state->completion_pendingq_tail->next = compl_queue_head;
851 hif_state->completion_pendingq_tail = compl_queue_tail;
852 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
853 } else {
854 hif_state->completion_pendingq_head = compl_queue_head;
855 hif_state->completion_pendingq_tail = compl_queue_tail;
856 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
857
858 /* Alert the recv completion service thread */
859 hif_completion_thread(hif_state);
860 }
861}
862
863/* TBDXXX: Set CE High Watermark; invoke txResourceAvailHandler in response */
864
865void
866hif_post_init(struct ol_softc *scn, void *unused,
867 struct hif_msg_callbacks *callbacks)
868{
869 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
870
871#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
872 spin_lock_init(&pcie_access_log_lock);
873#endif
874 /* Save callbacks for later installation */
875 cdf_mem_copy(&hif_state->msg_callbacks_pending, callbacks,
876 sizeof(hif_state->msg_callbacks_pending));
877
878}
879
880static void hif_pci_free_complete_state(struct HIF_CE_pipe_info *pipe_info)
881{
882 struct HIF_CE_completion_state_list *tmp_list;
883
884 while (pipe_info->completion_space_list) {
885 tmp_list = pipe_info->completion_space_list;
886 pipe_info->completion_space_list = tmp_list->next;
887 cdf_mem_free(tmp_list);
888 }
889}
890
891static int hif_alloc_complete_state_list(
892 struct HIF_CE_pipe_info *pipe_info,
893 int completions_needed)
894{
895 struct HIF_CE_completion_state *compl_state;
896 struct HIF_CE_completion_state_list *tmp_list;
897 int i;
898 int idx;
899 int num_list;
900 int allocated_node;
901 int num_in_batch;
902 size_t len;
903
904 allocated_node = 0;
905 num_list = (completions_needed + HIF_CE_COMPLETE_STATE_NUM -1);
906 num_list /= HIF_CE_COMPLETE_STATE_NUM;
907 for (idx = 0; idx < num_list; idx++) {
908 if (completions_needed - allocated_node >=
909 HIF_CE_COMPLETE_STATE_NUM)
910 num_in_batch = HIF_CE_COMPLETE_STATE_NUM;
911 else
912 num_in_batch = completions_needed - allocated_node;
913 if (num_in_batch <= 0)
914 break;
915 len = num_in_batch * sizeof(struct HIF_CE_completion_state) +
916 sizeof(struct HIF_CE_completion_state_list);
917 /* Allocate structures to track pending send/recv completions */
918 tmp_list =
919 (struct HIF_CE_completion_state_list *)
920 cdf_mem_malloc(len);
921 if (!tmp_list) {
922 HIF_ERROR("%s: compl_state has no mem", __func__);
923 hif_pci_free_complete_state(pipe_info);
924 return -1;
925 }
926 cdf_mem_zero(tmp_list, len);
927 compl_state = (struct HIF_CE_completion_state *)
928 ((uint8_t *)tmp_list +
929 sizeof(struct HIF_CE_completion_state_list));
930 for (i = 0; i < num_in_batch; i++) {
931 compl_state->send_or_recv = HIF_CE_COMPLETE_FREE;
932 compl_state->next = NULL;
933 if (pipe_info->completion_freeq_head)
934 pipe_info->completion_freeq_tail->next =
935 compl_state;
936 else
937 pipe_info->completion_freeq_head =
938 compl_state;
939 pipe_info->completion_freeq_tail = compl_state;
940 compl_state++;
941 allocated_node++;
942 }
943 if (pipe_info->completion_space_list == NULL) {
944 pipe_info->completion_space_list = tmp_list;
945 tmp_list->next = NULL;
946 } else {
947 tmp_list->next =
948 pipe_info->completion_space_list;
949 pipe_info->completion_space_list = tmp_list;
950 }
951 }
952 cdf_spinlock_init(&pipe_info->completion_freeq_lock);
953 return 0;
954}
955int hif_completion_thread_startup(struct HIF_CE_state *hif_state)
956{
957 struct CE_handle *ce_diag = hif_state->ce_diag;
958 int pipe_num;
959 struct ol_softc *scn = hif_state->scn;
960
961 /* daemonize("hif_compl_thread"); */
962
963 cdf_spinlock_init(&hif_state->completion_pendingq_lock);
964 hif_state->completion_pendingq_head =
965 hif_state->completion_pendingq_tail = NULL;
966
967 if (scn->ce_count == 0) {
968 HIF_ERROR("%s: Invalid ce_count\n", __func__);
969 return -EINVAL;
970 }
971 A_TARGET_ACCESS_LIKELY(scn);
972 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
973 struct CE_attr attr;
974 struct HIF_CE_pipe_info *pipe_info;
975 int completions_needed;
976
977 pipe_info = &hif_state->pipe_info[pipe_num];
978 if (pipe_info->ce_hdl == ce_diag) {
979 continue; /* Handle Diagnostic CE specially */
980 }
981 attr = host_ce_config[pipe_num];
982 completions_needed = 0;
983 if (attr.src_nentries) {
984 /* pipe used to send to target */
985 HIF_INFO_MED("%s: pipe_num:%d pipe_info:0x%p",
986 __func__, pipe_num, pipe_info);
987 ce_send_cb_register(pipe_info->ce_hdl,
988 hif_pci_ce_send_done, pipe_info,
989 attr.flags & CE_ATTR_DISABLE_INTR);
990 completions_needed += attr.src_nentries;
991 pipe_info->num_sends_allowed = attr.src_nentries - 1;
992 }
993 if (attr.dest_nentries) {
994 /* pipe used to receive from target */
995 ce_recv_cb_register(pipe_info->ce_hdl,
996 hif_pci_ce_recv_data, pipe_info,
997 attr.flags & CE_ATTR_DISABLE_INTR);
998 completions_needed += attr.dest_nentries;
999 }
1000
1001 pipe_info->completion_freeq_head =
1002 pipe_info->completion_freeq_tail = NULL;
1003 if (completions_needed > 0) {
1004 int ret;
1005
1006 ret = hif_alloc_complete_state_list(pipe_info,
1007 completions_needed);
1008 if (ret != 0) {
1009 HIF_ERROR("%s: ce_id = %d, no mem",
1010 __func__, pipe_info->pipe_num);
1011 return ret;
1012 }
1013 }
1014 }
1015 A_TARGET_ACCESS_UNLIKELY(scn);
1016 return 0;
1017}
1018
1019void hif_completion_thread_shutdown(struct HIF_CE_state *hif_state)
1020{
1021 struct HIF_CE_completion_state *compl_state;
1022 struct HIF_CE_pipe_info *pipe_info;
1023 struct ol_softc *scn = hif_state->scn;
1024 int pipe_num;
1025
1026 /*
1027 * Drop pending completions. These have already been
1028 * reported by the CE layer to us but we have not yet
1029 * passed them upstack.
1030 */
1031 while ((compl_state = hif_state->completion_pendingq_head) != NULL) {
1032 cdf_nbuf_t netbuf;
1033
1034 netbuf = (cdf_nbuf_t) compl_state->transfer_context;
1035 cdf_nbuf_free(netbuf);
1036
1037 hif_state->completion_pendingq_head = compl_state->next;
1038
1039 /*
1040 * NB: Don't bother to place compl_state on pipe's free queue,
1041 * because we'll free underlying memory for the free queues
1042 * in a moment anyway.
1043 */
1044 }
1045
1046 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
1047 pipe_info = &hif_state->pipe_info[pipe_num];
1048 hif_pci_free_complete_state(pipe_info);
1049 cdf_spinlock_destroy(&pipe_info->completion_freeq_lock);
1050 }
1051
1052 /* hif_state->compl_thread = NULL; */
1053 /* complete_and_exit(&hif_state->compl_thread_done, 0); */
1054}
1055
1056/*
1057 * This thread provides a context in which send/recv completions
1058 * are handled.
1059 *
1060 * Note: HIF installs callback functions with the CE layer.
1061 * Those functions are called directly (e.g. in interrupt context).
1062 * Upper layers (e.g. HTC) have installed callbacks with HIF which
1063 * expect to be called in a thread context. This is where that
1064 * conversion occurs.
1065 *
1066 * TBDXXX: Currently we use just one thread for all pipes.
1067 * This might be sufficient or we might need multiple threads.
1068 */
1069int
1070/* hif_completion_thread(void *hif_dev) */
1071hif_completion_thread(struct HIF_CE_state *hif_state)
1072{
1073 struct hif_msg_callbacks *msg_callbacks =
1074 &hif_state->msg_callbacks_current;
1075 struct HIF_CE_completion_state *compl_state;
1076
1077 /* Allow only one instance of the thread to execute at a time to
1078 * prevent out of order processing of messages - this is bad for higher
1079 * layer code
1080 */
1081 if (!cdf_atomic_dec_and_test(&hif_state->hif_thread_idle)) {
1082 /* We were not the lucky one */
1083 cdf_atomic_inc(&hif_state->hif_thread_idle);
1084 return 0;
1085 }
1086
1087 if (!msg_callbacks->fwEventHandler
1088 || !msg_callbacks->txCompletionHandler
1089 || !msg_callbacks->rxCompletionHandler) {
1090 return 0;
1091 }
1092 while (atomic_read(&hif_state->fw_event_pending) > 0) {
1093 /*
1094 * Clear pending state before handling, in case there's
1095 * another while we process the first.
1096 */
1097 atomic_set(&hif_state->fw_event_pending, 0);
1098 msg_callbacks->fwEventHandler(msg_callbacks->Context,
1099 CDF_STATUS_E_FAILURE);
1100 }
1101
1102 if (hif_state->scn->target_status == OL_TRGET_STATUS_RESET)
1103 return 0;
1104
1105 for (;; ) {
1106 struct HIF_CE_pipe_info *pipe_info;
1107 int send_done = 0;
1108
1109 cdf_spin_lock(&hif_state->completion_pendingq_lock);
1110
1111 if (!hif_state->completion_pendingq_head) {
1112 /* We are atomically sure that
1113 * there is no pending work */
1114 cdf_atomic_inc(&hif_state->hif_thread_idle);
1115 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
1116 break; /* All pending completions are handled */
1117 }
1118
1119 /* Dequeue the first unprocessed but completed transfer */
1120 compl_state = hif_state->completion_pendingq_head;
1121 hif_state->completion_pendingq_head = compl_state->next;
1122 cdf_spin_unlock(&hif_state->completion_pendingq_lock);
1123
1124 pipe_info = (struct HIF_CE_pipe_info *)compl_state->ce_context;
1125 if (compl_state->send_or_recv == HIF_CE_COMPLETE_SEND) {
1126 msg_callbacks->txCompletionHandler(msg_callbacks->
1127 Context,
1128 compl_state->
1129 transfer_context,
1130 compl_state->
1131 transfer_id,
1132 compl_state->toeplitz_hash_result);
1133 send_done = 1;
1134 } else {
1135 /* compl_state->send_or_recv == HIF_CE_COMPLETE_RECV */
1136 cdf_nbuf_t netbuf;
1137 unsigned int nbytes;
1138
1139 atomic_inc(&pipe_info->recv_bufs_needed);
1140 hif_post_recv_buffers(hif_state->scn);
1141
1142 netbuf = (cdf_nbuf_t) compl_state->transfer_context;
1143 nbytes = compl_state->nbytes;
1144 /*
1145 * To see the following debug output,
1146 * enable the HIF_PCI_DEBUG flag in
1147 * the debug module declaration in this source file
1148 */
1149 HIF_DBG("%s: netbuf=%p, nbytes=%d",
1150 __func__, netbuf, nbytes);
1151 if (nbytes <= pipe_info->buf_sz) {
1152 cdf_nbuf_set_pktlen(netbuf, nbytes);
1153 msg_callbacks->
1154 rxCompletionHandler(msg_callbacks->Context,
1155 netbuf,
1156 pipe_info->pipe_num);
1157 } else {
1158 HIF_ERROR(
1159 "%s: Invalid Rx msg buf:%p nbytes:%d",
1160 __func__, netbuf, nbytes);
1161 cdf_nbuf_free(netbuf);
1162 }
1163 }
1164
1165 /* Recycle completion state back to the pipe it came from. */
1166 compl_state->next = NULL;
1167 compl_state->send_or_recv = HIF_CE_COMPLETE_FREE;
1168 cdf_spin_lock(&pipe_info->completion_freeq_lock);
1169 if (pipe_info->completion_freeq_head) {
1170 pipe_info->completion_freeq_tail->next = compl_state;
1171 } else {
1172 pipe_info->completion_freeq_head = compl_state;
1173 }
1174 pipe_info->completion_freeq_tail = compl_state;
1175 pipe_info->num_sends_allowed += send_done;
1176 cdf_spin_unlock(&pipe_info->completion_freeq_lock);
1177 }
1178
1179 return 0;
1180}
1181
1182/*
1183 * Install pending msg callbacks.
1184 *
1185 * TBDXXX: This hack is needed because upper layers install msg callbacks
1186 * for use with HTC before BMI is done; yet this HIF implementation
1187 * needs to continue to use BMI msg callbacks. Really, upper layers
1188 * should not register HTC callbacks until AFTER BMI phase.
1189 */
1190static void hif_msg_callbacks_install(struct ol_softc *scn)
1191{
1192 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1193
1194 cdf_mem_copy(&hif_state->msg_callbacks_current,
1195 &hif_state->msg_callbacks_pending,
1196 sizeof(hif_state->msg_callbacks_pending));
1197}
1198
1199void hif_claim_device(struct ol_softc *scn, void *claimedContext)
1200{
1201 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1202
1203 hif_state->claimedContext = claimedContext;
1204}
1205
1206void hif_release_device(struct ol_softc *scn)
1207{
1208 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1209
1210 hif_state->claimedContext = NULL;
1211}
1212
1213void
1214hif_get_default_pipe(struct ol_softc *scn, uint8_t *ULPipe, uint8_t *DLPipe)
1215{
1216 int ul_is_polled, dl_is_polled;
1217
1218 (void)hif_map_service_to_pipe(scn, HTC_CTRL_RSVD_SVC,
1219 ULPipe, DLPipe, &ul_is_polled, &dl_is_polled);
1220}
1221
1222/* TBDXXX - temporary mapping while we have too few CE's */
1223int
1224hif_map_service_to_pipe(struct ol_softc *scn, uint16_t ServiceId,
1225 uint8_t *ULPipe, uint8_t *DLPipe, int *ul_is_polled,
1226 int *dl_is_polled)
1227{
1228 int status = CDF_STATUS_SUCCESS;
1229
1230 *dl_is_polled = 0; /* polling for received messages not supported */
1231 switch (ServiceId) {
1232 case HTT_DATA_MSG_SVC:
1233 /*
1234 * Host->target HTT gets its own pipe, so it can be polled
1235 * while other pipes are interrupt driven.
1236 */
1237 *ULPipe = 4;
1238 /*
1239 * Use the same target->host pipe for HTC ctrl,
1240 * HTC raw streams, and HTT.
1241 */
1242 *DLPipe = 1;
1243 break;
1244
1245 case HTC_CTRL_RSVD_SVC:
1246 *ULPipe = 0;
1247 *DLPipe = 2;
1248 break;
1249
1250 case HTC_RAW_STREAMS_SVC:
1251 /*
1252 * Note: HTC_RAW_STREAMS_SVC is currently unused, and
1253 * HTC_CTRL_RSVD_SVC could share the same pipe as the
1254 * WMI services. So, if another CE is needed, change
1255 * this to *ULPipe = 3, which frees up CE 0.
1256 */
1257 /**ULPipe = 3; */
1258 *ULPipe = 0;
1259 *DLPipe = 2;
1260 break;
1261
1262 case WMI_DATA_BK_SVC:
1263 /*
1264 * To avoid some confusions, better to introduce new EP-ping
1265 * service instead of using existed services. Until the main
1266 * framework support this, keep this design.
1267 */
1268 if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
1269 *ULPipe = 4;
1270 *DLPipe = 1;
1271 break;
1272 }
1273 case WMI_DATA_BE_SVC:
1274 case WMI_DATA_VI_SVC:
1275 case WMI_DATA_VO_SVC:
1276
1277 case WMI_CONTROL_SVC:
1278 *ULPipe = 3;
1279 *DLPipe = 2;
1280 break;
1281
1282 case WDI_IPA_TX_SVC:
1283 *ULPipe = 5;
1284 break;
1285
1286 /* pipe 5 unused */
1287 /* pipe 6 reserved */
1288 /* pipe 7 reserved */
1289
1290 default:
1291 status = CDF_STATUS_E_INVAL;
1292 break;
1293 }
1294 *ul_is_polled =
1295 (host_ce_config[*ULPipe].flags & CE_ATTR_DISABLE_INTR) != 0;
1296
1297 return status;
1298}
1299
1300/**
1301 * hif_dump_pipe_debug_count() - Log error count
1302 * @scn: ol_softc pointer.
1303 *
1304 * Output the pipe error counts of each pipe to log file
1305 *
1306 * Return: N/A
1307 */
1308void hif_dump_pipe_debug_count(struct ol_softc *scn)
1309{
1310 struct HIF_CE_state *hif_state;
1311 int pipe_num;
1312
1313 if (scn == NULL) {
1314 HIF_ERROR("%s scn is NULL", __func__);
1315 return;
1316 }
1317 hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1318 if (hif_state == NULL) {
1319 HIF_ERROR("%s hif_state is NULL", __func__);
1320 return;
1321 }
1322 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
1323 struct HIF_CE_pipe_info *pipe_info;
1324
1325 pipe_info = &hif_state->pipe_info[pipe_num];
1326
1327 if (pipe_info->nbuf_alloc_err_count > 0 ||
1328 pipe_info->nbuf_dma_err_count > 0 ||
1329 pipe_info->nbuf_ce_enqueue_err_count)
1330 HIF_ERROR(
1331 "%s: pipe_id = %d, recv_bufs_needed = %d, nbuf_alloc_err_count = %u, nbuf_dma_err_count = %u, nbuf_ce_enqueue_err_count = %u",
1332 __func__, pipe_info->pipe_num,
1333 atomic_read(&pipe_info->recv_bufs_needed),
1334 pipe_info->nbuf_alloc_err_count,
1335 pipe_info->nbuf_dma_err_count,
1336 pipe_info->nbuf_ce_enqueue_err_count);
1337 }
1338}
1339
1340static int hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info)
1341{
1342 struct CE_handle *ce_hdl;
1343 cdf_size_t buf_sz;
1344 struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state;
1345 struct ol_softc *scn = hif_state->scn;
1346 CDF_STATUS ret;
1347 uint32_t bufs_posted = 0;
1348
1349 buf_sz = pipe_info->buf_sz;
1350 if (buf_sz == 0) {
1351 /* Unused Copy Engine */
1352 return 0;
1353 }
1354
1355 ce_hdl = pipe_info->ce_hdl;
1356
1357 cdf_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
1358 while (atomic_read(&pipe_info->recv_bufs_needed) > 0) {
1359 cdf_dma_addr_t CE_data; /* CE space buffer address */
1360 cdf_nbuf_t nbuf;
1361 int status;
1362
1363 atomic_dec(&pipe_info->recv_bufs_needed);
1364 cdf_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock);
1365
1366 nbuf = cdf_nbuf_alloc(scn->cdf_dev, buf_sz, 0, 4, false);
1367 if (!nbuf) {
1368 cdf_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
1369 pipe_info->nbuf_alloc_err_count++;
1370 cdf_spin_unlock_bh(
1371 &pipe_info->recv_bufs_needed_lock);
1372 HIF_ERROR(
1373 "%s buf alloc error [%d] needed %d, nbuf_alloc_err_count = %u",
1374 __func__, pipe_info->pipe_num,
1375 atomic_read(&pipe_info->recv_bufs_needed),
1376 pipe_info->nbuf_alloc_err_count);
1377 atomic_inc(&pipe_info->recv_bufs_needed);
1378 return 1;
1379 }
1380
1381 /*
1382 * cdf_nbuf_peek_header(nbuf, &data, &unused);
1383 * CE_data = dma_map_single(dev, data, buf_sz, );
1384 * DMA_FROM_DEVICE);
1385 */
1386 ret =
1387 cdf_nbuf_map_single(scn->cdf_dev, nbuf,
1388 CDF_DMA_FROM_DEVICE);
1389
1390 if (unlikely(ret != CDF_STATUS_SUCCESS)) {
1391 cdf_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
1392 pipe_info->nbuf_dma_err_count++;
1393 cdf_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock);
1394 HIF_ERROR(
1395 "%s buf alloc error [%d] needed %d, nbuf_dma_err_count = %u",
1396 __func__, pipe_info->pipe_num,
1397 atomic_read(&pipe_info->recv_bufs_needed),
1398 pipe_info->nbuf_dma_err_count);
1399 cdf_nbuf_free(nbuf);
1400 atomic_inc(&pipe_info->recv_bufs_needed);
1401 return 1;
1402 }
1403
1404 CE_data = cdf_nbuf_get_frag_paddr_lo(nbuf, 0);
1405
1406 cdf_os_mem_dma_sync_single_for_device(scn->cdf_dev, CE_data,
1407 buf_sz, DMA_FROM_DEVICE);
1408 status = ce_recv_buf_enqueue(ce_hdl, (void *)nbuf, CE_data);
1409 CDF_ASSERT(status == CDF_STATUS_SUCCESS);
1410 if (status != EOK) {
1411 cdf_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
1412 pipe_info->nbuf_ce_enqueue_err_count++;
1413 cdf_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock);
1414 HIF_ERROR(
1415 "%s buf alloc error [%d] needed %d, nbuf_alloc_err_count = %u",
1416 __func__, pipe_info->pipe_num,
1417 atomic_read(&pipe_info->recv_bufs_needed),
1418 pipe_info->nbuf_ce_enqueue_err_count);
1419 atomic_inc(&pipe_info->recv_bufs_needed);
1420 cdf_nbuf_free(nbuf);
1421 return 1;
1422 }
1423
1424 cdf_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
1425 bufs_posted++;
1426 }
1427 pipe_info->nbuf_alloc_err_count =
1428 (pipe_info->nbuf_alloc_err_count > bufs_posted)?
1429 pipe_info->nbuf_alloc_err_count - bufs_posted : 0;
1430 pipe_info->nbuf_dma_err_count =
1431 (pipe_info->nbuf_dma_err_count > bufs_posted)?
1432 pipe_info->nbuf_dma_err_count - bufs_posted : 0;
1433 pipe_info->nbuf_ce_enqueue_err_count =
1434 (pipe_info->nbuf_ce_enqueue_err_count > bufs_posted)?
1435 pipe_info->nbuf_ce_enqueue_err_count - bufs_posted : 0;
1436
1437 cdf_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock);
1438
1439 return 0;
1440}
1441
1442/*
1443 * Try to post all desired receive buffers for all pipes.
1444 * Returns 0 if all desired buffers are posted,
1445 * non-zero if were were unable to completely
1446 * replenish receive buffers.
1447 */
1448static int hif_post_recv_buffers(struct ol_softc *scn)
1449{
1450 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1451 int pipe_num, rv = 0;
1452
1453 A_TARGET_ACCESS_LIKELY(scn);
1454 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
1455 struct HIF_CE_pipe_info *pipe_info;
1456
1457 pipe_info = &hif_state->pipe_info[pipe_num];
1458 if (hif_post_recv_buffers_for_pipe(pipe_info)) {
1459 rv = 1;
1460 goto done;
1461 }
1462 }
1463
1464done:
1465 A_TARGET_ACCESS_UNLIKELY(scn);
1466
1467 return rv;
1468}
1469
1470CDF_STATUS hif_start(struct ol_softc *scn)
1471{
1472 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1473
1474 if (hif_completion_thread_startup(hif_state))
1475 return CDF_STATUS_E_FAILURE;
1476
1477 hif_msg_callbacks_install(scn);
1478
1479 /* Post buffers once to start things off. */
1480 (void)hif_post_recv_buffers(scn);
1481
1482 hif_state->started = true;
1483
1484 return CDF_STATUS_SUCCESS;
1485}
1486
1487#ifdef WLAN_FEATURE_FASTPATH
1488/**
1489 * hif_enable_fastpath() Update that we have enabled fastpath mode
1490 * @hif_device: HIF context
1491 *
1492 * For use in data path
1493 *
1494 * Retrun: void
1495 */
1496void
1497hif_enable_fastpath(struct ol_softc *hif_device)
1498{
1499 HIF_INFO("Enabling fastpath mode\n");
1500 hif_device->fastpath_mode_on = 1;
1501}
1502#endif /* WLAN_FEATURE_FASTPATH */
1503
1504void hif_recv_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info)
1505{
1506 struct ol_softc *scn;
1507 struct CE_handle *ce_hdl;
1508 uint32_t buf_sz;
1509 struct HIF_CE_state *hif_state;
1510 cdf_nbuf_t netbuf;
1511 cdf_dma_addr_t CE_data;
1512 void *per_CE_context;
1513
1514 buf_sz = pipe_info->buf_sz;
1515 if (buf_sz == 0) {
1516 /* Unused Copy Engine */
1517 return;
1518 }
1519
1520 hif_state = pipe_info->HIF_CE_state;
1521 if (!hif_state->started) {
1522 return;
1523 }
1524
1525 scn = hif_state->scn;
1526 ce_hdl = pipe_info->ce_hdl;
1527
1528 if (scn->cdf_dev == NULL) {
1529 return;
1530 }
1531 while (ce_revoke_recv_next
1532 (ce_hdl, &per_CE_context, (void **)&netbuf,
1533 &CE_data) == CDF_STATUS_SUCCESS) {
1534 cdf_nbuf_unmap_single(scn->cdf_dev, netbuf,
1535 CDF_DMA_FROM_DEVICE);
1536 cdf_nbuf_free(netbuf);
1537 }
1538}
1539
1540void hif_send_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info)
1541{
1542 struct CE_handle *ce_hdl;
1543 struct HIF_CE_state *hif_state;
1544 cdf_nbuf_t netbuf;
1545 void *per_CE_context;
1546 cdf_dma_addr_t CE_data;
1547 unsigned int nbytes;
1548 unsigned int id;
1549 uint32_t buf_sz;
1550 uint32_t toeplitz_hash_result;
1551
1552 buf_sz = pipe_info->buf_sz;
1553 if (buf_sz == 0) {
1554 /* Unused Copy Engine */
1555 return;
1556 }
1557
1558 hif_state = pipe_info->HIF_CE_state;
1559 if (!hif_state->started) {
1560 return;
1561 }
1562
1563 ce_hdl = pipe_info->ce_hdl;
1564
1565 while (ce_cancel_send_next
1566 (ce_hdl, &per_CE_context,
1567 (void **)&netbuf, &CE_data, &nbytes,
1568 &id, &toeplitz_hash_result) == CDF_STATUS_SUCCESS) {
1569 if (netbuf != CE_SENDLIST_ITEM_CTXT) {
1570 /*
1571 * Packets enqueued by htt_h2t_ver_req_msg() and
1572 * htt_h2t_rx_ring_cfg_msg_ll() have already been
1573 * freed in htt_htc_misc_pkt_pool_free() in
1574 * wlantl_close(), so do not free them here again
1575 * by checking whether it's the EndPoint
1576 * which they are queued in.
1577 */
1578 if (id == hif_state->scn->htc_endpoint)
1579 return;
1580 /* Indicate the completion to higer
1581 * layer to free the buffer */
1582 hif_state->msg_callbacks_current.
1583 txCompletionHandler(hif_state->
1584 msg_callbacks_current.Context,
1585 netbuf, id, toeplitz_hash_result);
1586 }
1587 }
1588}
1589
1590/*
1591 * Cleanup residual buffers for device shutdown:
1592 * buffers that were enqueued for receive
1593 * buffers that were to be sent
1594 * Note: Buffers that had completed but which were
1595 * not yet processed are on a completion queue. They
1596 * are handled when the completion thread shuts down.
1597 */
1598void hif_buffer_cleanup(struct HIF_CE_state *hif_state)
1599{
1600 int pipe_num;
1601
1602 for (pipe_num = 0; pipe_num < hif_state->scn->ce_count; pipe_num++) {
1603 struct HIF_CE_pipe_info *pipe_info;
1604
1605 pipe_info = &hif_state->pipe_info[pipe_num];
1606 hif_recv_buffer_cleanup_on_pipe(pipe_info);
1607 hif_send_buffer_cleanup_on_pipe(pipe_info);
1608 }
1609}
1610
1611void hif_flush_surprise_remove(struct ol_softc *scn)
1612{
1613 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1614 hif_buffer_cleanup(hif_state);
1615}
1616
1617void hif_stop(struct ol_softc *scn)
1618{
1619 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
1620 int pipe_num;
1621
1622 scn->hif_init_done = false;
1623 if (hif_state->started) {
1624 /* sync shutdown */
1625 hif_completion_thread_shutdown(hif_state);
1626 hif_completion_thread(hif_state);
1627 } else {
1628 hif_completion_thread_shutdown(hif_state);
1629 }
1630
1631 /*
1632 * At this point, asynchronous threads are stopped,
1633 * The Target should not DMA nor interrupt, Host code may
1634 * not initiate anything more. So we just need to clean
1635 * up Host-side state.
1636 */
1637
1638 if (scn->athdiag_procfs_inited) {
1639 athdiag_procfs_remove();
1640 scn->athdiag_procfs_inited = false;
1641 }
1642
1643 hif_buffer_cleanup(hif_state);
1644
1645 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
1646 struct HIF_CE_pipe_info *pipe_info;
1647
1648 pipe_info = &hif_state->pipe_info[pipe_num];
1649 if (pipe_info->ce_hdl) {
1650 ce_fini(pipe_info->ce_hdl);
1651 pipe_info->ce_hdl = NULL;
1652 pipe_info->buf_sz = 0;
1653 }
1654 }
1655
1656 if (hif_state->sleep_timer_init) {
1657 cdf_softirq_timer_cancel(&hif_state->sleep_timer);
1658 cdf_softirq_timer_free(&hif_state->sleep_timer);
1659 hif_state->sleep_timer_init = false;
1660 }
1661
1662 hif_state->started = false;
1663}
1664
1665#define ADRASTEA_SRC_WR_INDEX_OFFSET 0x3C
1666#define ADRASTEA_DST_WR_INDEX_OFFSET 0x40
1667
1668
1669static struct shadow_reg_cfg target_shadow_reg_cfg_map[] = {
1670 { 0, ADRASTEA_SRC_WR_INDEX_OFFSET},
1671 { 3, ADRASTEA_SRC_WR_INDEX_OFFSET},
1672 { 4, ADRASTEA_SRC_WR_INDEX_OFFSET},
1673 { 5, ADRASTEA_SRC_WR_INDEX_OFFSET},
1674 { 7, ADRASTEA_SRC_WR_INDEX_OFFSET},
1675 { 1, ADRASTEA_DST_WR_INDEX_OFFSET},
1676 { 2, ADRASTEA_DST_WR_INDEX_OFFSET},
1677 { 7, ADRASTEA_DST_WR_INDEX_OFFSET},
1678 { 8, ADRASTEA_DST_WR_INDEX_OFFSET},
1679};
1680
1681
1682
1683/* CE_PCI TABLE */
1684/*
1685 * NOTE: the table below is out of date, though still a useful reference.
1686 * Refer to target_service_to_ce_map and hif_map_service_to_pipe for the actual
1687 * mapping of HTC services to HIF pipes.
1688 */
1689/*
1690 * This authoritative table defines Copy Engine configuration and the mapping
1691 * of services/endpoints to CEs. A subset of this information is passed to
1692 * the Target during startup as a prerequisite to entering BMI phase.
1693 * See:
1694 * target_service_to_ce_map - Target-side mapping
1695 * hif_map_service_to_pipe - Host-side mapping
1696 * target_ce_config - Target-side configuration
1697 * host_ce_config - Host-side configuration
1698 ============================================================================
1699 Purpose | Service / Endpoint | CE | Dire | Xfer | Xfer
1700 | | | ctio | Size | Frequency
1701 | | | n | |
1702 ============================================================================
1703 tx | HTT_DATA (downlink) | CE 0 | h->t | medium - | very frequent
1704 descriptor | | | | O(100B) | and regular
1705 download | | | | |
1706 ----------------------------------------------------------------------------
1707 rx | HTT_DATA (uplink) | CE 1 | t->h | small - | frequent and
1708 indication | | | | O(10B) | regular
1709 upload | | | | |
1710 ----------------------------------------------------------------------------
1711 MSDU | DATA_BK (uplink) | CE 2 | t->h | large - | rare
1712 upload | | | | O(1000B) | (frequent
1713 e.g. noise | | | | | during IP1.0
1714 packets | | | | | testing)
1715 ----------------------------------------------------------------------------
1716 MSDU | DATA_BK (downlink) | CE 3 | h->t | large - | very rare
1717 download | | | | O(1000B) | (frequent
1718 e.g. | | | | | during IP1.0
1719 misdirecte | | | | | testing)
1720 d EAPOL | | | | |
1721 packets | | | | |
1722 ----------------------------------------------------------------------------
1723 n/a | DATA_BE, DATA_VI | CE 2 | t->h | | never(?)
1724 | DATA_VO (uplink) | | | |
1725 ----------------------------------------------------------------------------
1726 n/a | DATA_BE, DATA_VI | CE 3 | h->t | | never(?)
1727 | DATA_VO (downlink) | | | |
1728 ----------------------------------------------------------------------------
1729 WMI events | WMI_CONTROL (uplink) | CE 4 | t->h | medium - | infrequent
1730 | | | | O(100B) |
1731 ----------------------------------------------------------------------------
1732 WMI | WMI_CONTROL | CE 5 | h->t | medium - | infrequent
1733 messages | (downlink) | | | O(100B) |
1734 | | | | |
1735 ----------------------------------------------------------------------------
1736 n/a | HTC_CTRL_RSVD, | CE 1 | t->h | | never(?)
1737 | HTC_RAW_STREAMS | | | |
1738 | (uplink) | | | |
1739 ----------------------------------------------------------------------------
1740 n/a | HTC_CTRL_RSVD, | CE 0 | h->t | | never(?)
1741 | HTC_RAW_STREAMS | | | |
1742 | (downlink) | | | |
1743 ----------------------------------------------------------------------------
1744 diag | none (raw CE) | CE 7 | t<>h | 4 | Diag Window
1745 | | | | | infrequent
1746 ============================================================================
1747 */
1748
1749/*
1750 * Map from service/endpoint to Copy Engine.
1751 * This table is derived from the CE_PCI TABLE, above.
1752 * It is passed to the Target at startup for use by firmware.
1753 */
1754static struct service_to_pipe target_service_to_ce_map_wlan[] = {
1755 {
1756 WMI_DATA_VO_SVC,
1757 PIPEDIR_OUT, /* out = UL = host -> target */
1758 3,
1759 },
1760 {
1761 WMI_DATA_VO_SVC,
1762 PIPEDIR_IN, /* in = DL = target -> host */
1763 2,
1764 },
1765 {
1766 WMI_DATA_BK_SVC,
1767 PIPEDIR_OUT, /* out = UL = host -> target */
1768 3,
1769 },
1770 {
1771 WMI_DATA_BK_SVC,
1772 PIPEDIR_IN, /* in = DL = target -> host */
1773 2,
1774 },
1775 {
1776 WMI_DATA_BE_SVC,
1777 PIPEDIR_OUT, /* out = UL = host -> target */
1778 3,
1779 },
1780 {
1781 WMI_DATA_BE_SVC,
1782 PIPEDIR_IN, /* in = DL = target -> host */
1783 2,
1784 },
1785 {
1786 WMI_DATA_VI_SVC,
1787 PIPEDIR_OUT, /* out = UL = host -> target */
1788 3,
1789 },
1790 {
1791 WMI_DATA_VI_SVC,
1792 PIPEDIR_IN, /* in = DL = target -> host */
1793 2,
1794 },
1795 {
1796 WMI_CONTROL_SVC,
1797 PIPEDIR_OUT, /* out = UL = host -> target */
1798 3,
1799 },
1800 {
1801 WMI_CONTROL_SVC,
1802 PIPEDIR_IN, /* in = DL = target -> host */
1803 2,
1804 },
1805 {
1806 HTC_CTRL_RSVD_SVC,
1807 PIPEDIR_OUT, /* out = UL = host -> target */
1808 0, /* could be moved to 3 (share with WMI) */
1809 },
1810 {
1811 HTC_CTRL_RSVD_SVC,
1812 PIPEDIR_IN, /* in = DL = target -> host */
1813 2,
1814 },
1815 {
1816 HTC_RAW_STREAMS_SVC, /* not currently used */
1817 PIPEDIR_OUT, /* out = UL = host -> target */
1818 0,
1819 },
1820 {
1821 HTC_RAW_STREAMS_SVC, /* not currently used */
1822 PIPEDIR_IN, /* in = DL = target -> host */
1823 2,
1824 },
1825 {
1826 HTT_DATA_MSG_SVC,
1827 PIPEDIR_OUT, /* out = UL = host -> target */
1828 4,
1829 },
1830 {
1831 HTT_DATA_MSG_SVC,
1832 PIPEDIR_IN, /* in = DL = target -> host */
1833 1,
1834 },
1835 {
1836 WDI_IPA_TX_SVC,
1837 PIPEDIR_OUT, /* in = DL = target -> host */
1838 5,
1839 },
1840 /* (Additions here) */
1841
1842 { /* Must be last */
1843 0,
1844 0,
1845 0,
1846 },
1847};
1848
1849static struct service_to_pipe *target_service_to_ce_map =
1850 target_service_to_ce_map_wlan;
1851static int target_service_to_ce_map_sz = sizeof(target_service_to_ce_map_wlan);
1852
1853static struct shadow_reg_cfg *target_shadow_reg_cfg = target_shadow_reg_cfg_map;
1854static int shadow_cfg_sz = sizeof(target_shadow_reg_cfg_map);
1855
1856static struct service_to_pipe target_service_to_ce_map_wlan_epping[] = {
1857 {WMI_DATA_VO_SVC, PIPEDIR_OUT, 3,}, /* out = UL = host -> target */
1858 {WMI_DATA_VO_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1859 {WMI_DATA_BK_SVC, PIPEDIR_OUT, 4,}, /* out = UL = host -> target */
1860 {WMI_DATA_BK_SVC, PIPEDIR_IN, 1,}, /* in = DL = target -> host */
1861 {WMI_DATA_BE_SVC, PIPEDIR_OUT, 3,}, /* out = UL = host -> target */
1862 {WMI_DATA_BE_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1863 {WMI_DATA_VI_SVC, PIPEDIR_OUT, 3,}, /* out = UL = host -> target */
1864 {WMI_DATA_VI_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1865 {WMI_CONTROL_SVC, PIPEDIR_OUT, 3,}, /* out = UL = host -> target */
1866 {WMI_CONTROL_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1867 {HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0,}, /* out = UL = host -> target */
1868 {HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1869 {HTC_RAW_STREAMS_SVC, PIPEDIR_OUT, 0,}, /* out = UL = host -> target */
1870 {HTC_RAW_STREAMS_SVC, PIPEDIR_IN, 2,}, /* in = DL = target -> host */
1871 {HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4,}, /* out = UL = host -> target */
1872 {HTT_DATA_MSG_SVC, PIPEDIR_IN, 1,}, /* in = DL = target -> host */
1873 {0, 0, 0,}, /* Must be last */
1874};
1875
1876#ifdef HIF_PCI
1877/*
1878 * Send an interrupt to the device to wake up the Target CPU
1879 * so it has an opportunity to notice any changed state.
1880 */
1881void hif_wake_target_cpu(struct ol_softc *scn)
1882{
1883 CDF_STATUS rv;
1884 uint32_t core_ctrl;
1885
1886 rv = hif_diag_read_access(scn,
1887 SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS,
1888 &core_ctrl);
1889 CDF_ASSERT(rv == CDF_STATUS_SUCCESS);
1890 /* A_INUM_FIRMWARE interrupt to Target CPU */
1891 core_ctrl |= CORE_CTRL_CPU_INTR_MASK;
1892
1893 rv = hif_diag_write_access(scn,
1894 SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS,
1895 core_ctrl);
1896 CDF_ASSERT(rv == CDF_STATUS_SUCCESS);
1897}
1898#endif
1899
1900static void hif_sleep_entry(void *arg)
1901{
1902 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)arg;
1903 struct ol_softc *scn = hif_state->scn;
1904 uint32_t idle_ms;
1905 if (scn->recovery)
1906 return;
1907
1908 cdf_spin_lock_irqsave(&hif_state->keep_awake_lock);
1909 if (hif_state->verified_awake == false) {
1910 idle_ms = cdf_system_ticks_to_msecs(cdf_system_ticks()
1911 - hif_state->sleep_ticks);
1912 if (idle_ms >= HIF_MIN_SLEEP_INACTIVITY_TIME_MS) {
1913 if (!cdf_atomic_read(&scn->link_suspended)) {
1914 soc_wake_reset(scn);
1915 hif_state->fake_sleep = false;
1916 }
1917 } else {
1918 cdf_softirq_timer_cancel(&hif_state->sleep_timer);
1919 cdf_softirq_timer_start(&hif_state->sleep_timer,
1920 HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS);
1921 }
1922 } else {
1923 cdf_softirq_timer_cancel(&hif_state->sleep_timer);
1924 cdf_softirq_timer_start(&hif_state->sleep_timer,
1925 HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS);
1926 }
1927 cdf_spin_unlock_irqrestore(&hif_state->keep_awake_lock);
1928}
1929#define HIF_HIA_MAX_POLL_LOOP 1000000
1930#define HIF_HIA_POLLING_DELAY_MS 10
1931
1932#ifndef HIF_PCI
1933int hif_set_hia(struct ol_softc *scn)
1934{
1935 return 0;
1936}
1937#else
1938int hif_set_hia(struct ol_softc *scn)
1939{
1940 CDF_STATUS rv;
1941 uint32_t interconnect_targ_addr = 0;
1942 uint32_t pcie_state_targ_addr = 0;
1943 uint32_t pipe_cfg_targ_addr = 0;
1944 uint32_t svc_to_pipe_map = 0;
1945 uint32_t pcie_config_flags = 0;
1946 uint32_t flag2_value = 0;
1947 uint32_t flag2_targ_addr = 0;
1948#ifdef QCA_WIFI_3_0
1949 uint32_t host_interest_area = 0;
1950 uint8_t i;
1951#else
1952 uint32_t ealloc_value = 0;
1953 uint32_t ealloc_targ_addr = 0;
1954 uint8_t banks_switched = 1;
1955 uint32_t chip_id;
1956#endif
1957 uint32_t pipe_cfg_addr;
1958
1959 HIF_TRACE("%s: E", __func__);
1960
1961 if (IHELIUM_BU || ADRASTEA_BU)
1962 return CDF_STATUS_SUCCESS;
1963
1964#ifdef QCA_WIFI_3_0
1965 i = 0;
1966 while (i < HIF_HIA_MAX_POLL_LOOP) {
1967 host_interest_area = hif_read32_mb(scn->mem +
1968 A_SOC_CORE_SCRATCH_0_ADDRESS);
1969 if ((host_interest_area & 0x01) == 0) {
1970 cdf_mdelay(HIF_HIA_POLLING_DELAY_MS);
1971 host_interest_area = 0;
1972 i++;
1973 if (i > HIF_HIA_MAX_POLL_LOOP && (i % 1000 == 0)) {
1974 HIF_ERROR("%s: poll timeout(%d)", __func__, i);
1975 }
1976 } else {
1977 host_interest_area &= (~0x01);
1978 hif_write32_mb(scn->mem + 0x113014, 0);
1979 break;
1980 }
1981 }
1982
1983 if (i >= HIF_HIA_MAX_POLL_LOOP) {
1984 HIF_ERROR("%s: hia polling timeout", __func__);
1985 return -EIO;
1986 }
1987
1988 if (host_interest_area == 0) {
1989 HIF_ERROR("%s: host_interest_area = 0", __func__);
1990 return -EIO;
1991 }
1992
1993 interconnect_targ_addr = host_interest_area +
1994 offsetof(struct host_interest_area_t,
1995 hi_interconnect_state);
1996
1997 flag2_targ_addr = host_interest_area +
1998 offsetof(struct host_interest_area_t, hi_option_flag2);
1999
2000#else
2001 interconnect_targ_addr = hif_hia_item_address(scn->target_type,
2002 offsetof(struct host_interest_s, hi_interconnect_state));
2003 ealloc_targ_addr = hif_hia_item_address(scn->target_type,
2004 offsetof(struct host_interest_s, hi_early_alloc));
2005 flag2_targ_addr = hif_hia_item_address(scn->target_type,
2006 offsetof(struct host_interest_s, hi_option_flag2));
2007#endif
2008 /* Supply Target-side CE configuration */
2009 rv = hif_diag_read_access(scn, interconnect_targ_addr,
2010 &pcie_state_targ_addr);
2011 if (rv != CDF_STATUS_SUCCESS) {
2012 HIF_ERROR("%s: interconnect_targ_addr = 0x%0x, ret = %d",
2013 __func__, interconnect_targ_addr, rv);
2014 goto done;
2015 }
2016 if (pcie_state_targ_addr == 0) {
2017 rv = CDF_STATUS_E_FAILURE;
2018 HIF_ERROR("%s: pcie state addr is 0", __func__);
2019 goto done;
2020 }
2021 pipe_cfg_addr = pcie_state_targ_addr +
2022 offsetof(struct pcie_state_s,
2023 pipe_cfg_addr);
2024 rv = hif_diag_read_access(scn,
2025 pipe_cfg_addr,
2026 &pipe_cfg_targ_addr);
2027 if (rv != CDF_STATUS_SUCCESS) {
2028 HIF_ERROR("%s: pipe_cfg_addr = 0x%0x, ret = %d",
2029 __func__, pipe_cfg_addr, rv);
2030 goto done;
2031 }
2032 if (pipe_cfg_targ_addr == 0) {
2033 rv = CDF_STATUS_E_FAILURE;
2034 HIF_ERROR("%s: pipe cfg addr is 0", __func__);
2035 goto done;
2036 }
2037
2038 rv = hif_diag_write_mem(scn, pipe_cfg_targ_addr,
2039 (uint8_t *) target_ce_config,
2040 target_ce_config_sz);
2041
2042 if (rv != CDF_STATUS_SUCCESS) {
2043 HIF_ERROR("%s: write pipe cfg (%d)", __func__, rv);
2044 goto done;
2045 }
2046
2047 rv = hif_diag_read_access(scn,
2048 pcie_state_targ_addr +
2049 offsetof(struct pcie_state_s,
2050 svc_to_pipe_map),
2051 &svc_to_pipe_map);
2052 if (rv != CDF_STATUS_SUCCESS) {
2053 HIF_ERROR("%s: get svc/pipe map (%d)", __func__, rv);
2054 goto done;
2055 }
2056 if (svc_to_pipe_map == 0) {
2057 rv = CDF_STATUS_E_FAILURE;
2058 HIF_ERROR("%s: svc_to_pipe map is 0", __func__);
2059 goto done;
2060 }
2061
2062 rv = hif_diag_write_mem(scn,
2063 svc_to_pipe_map,
2064 (uint8_t *) target_service_to_ce_map,
2065 target_service_to_ce_map_sz);
2066 if (rv != CDF_STATUS_SUCCESS) {
2067 HIF_ERROR("%s: write svc/pipe map (%d)", __func__, rv);
2068 goto done;
2069 }
2070
2071 rv = hif_diag_read_access(scn,
2072 pcie_state_targ_addr +
2073 offsetof(struct pcie_state_s,
2074 config_flags),
2075 &pcie_config_flags);
2076 if (rv != CDF_STATUS_SUCCESS) {
2077 HIF_ERROR("%s: get pcie config_flags (%d)", __func__, rv);
2078 goto done;
2079 }
2080#if (CONFIG_PCIE_ENABLE_L1_CLOCK_GATE)
2081 pcie_config_flags |= PCIE_CONFIG_FLAG_ENABLE_L1;
2082#else
2083 pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1;
2084#endif /* CONFIG_PCIE_ENABLE_L1_CLOCK_GATE */
2085 pcie_config_flags |= PCIE_CONFIG_FLAG_CLK_SWITCH_WAIT;
2086#if (CONFIG_PCIE_ENABLE_AXI_CLK_GATE)
2087 pcie_config_flags |= PCIE_CONFIG_FLAG_AXI_CLK_GATE;
2088#endif
2089 rv = hif_diag_write_mem(scn,
2090 pcie_state_targ_addr +
2091 offsetof(struct pcie_state_s,
2092 config_flags),
2093 (uint8_t *) &pcie_config_flags,
2094 sizeof(pcie_config_flags));
2095 if (rv != CDF_STATUS_SUCCESS) {
2096 HIF_ERROR("%s: write pcie config_flags (%d)", __func__, rv);
2097 goto done;
2098 }
2099
2100#ifndef QCA_WIFI_3_0
2101 /* configure early allocation */
2102 ealloc_targ_addr = hif_hia_item_address(scn->target_type,
2103 offsetof(
2104 struct host_interest_s,
2105 hi_early_alloc));
2106
2107 rv = hif_diag_read_access(scn, ealloc_targ_addr,
2108 &ealloc_value);
2109 if (rv != CDF_STATUS_SUCCESS) {
2110 HIF_ERROR("%s: get early alloc val (%d)", __func__, rv);
2111 goto done;
2112 }
2113
2114 /* 1 bank is switched to IRAM, except ROME 1.0 */
2115 ealloc_value |=
2116 ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) &
2117 HI_EARLY_ALLOC_MAGIC_MASK);
2118
2119 rv = hif_diag_read_access(scn,
2120 CHIP_ID_ADDRESS |
2121 RTC_SOC_BASE_ADDRESS, &chip_id);
2122 if (rv != CDF_STATUS_SUCCESS) {
2123 HIF_ERROR("%s: get chip id val (%d)", __func__, rv);
2124 goto done;
2125 }
2126 if (CHIP_ID_VERSION_GET(chip_id) == 0xD) {
2127 scn->target_revision =
2128 CHIP_ID_REVISION_GET(chip_id);
2129 switch (CHIP_ID_REVISION_GET(chip_id)) {
2130 case 0x2: /* ROME 1.3 */
2131 /* 2 banks are switched to IRAM */
2132 banks_switched = 2;
2133 break;
2134 case 0x4: /* ROME 2.1 */
2135 case 0x5: /* ROME 2.2 */
2136 banks_switched = 6;
2137 break;
2138 case 0x8: /* ROME 3.0 */
2139 case 0x9: /* ROME 3.1 */
2140 case 0xA: /* ROME 3.2 */
2141 banks_switched = 9;
2142 break;
2143 case 0x0: /* ROME 1.0 */
2144 case 0x1: /* ROME 1.1 */
2145 default:
2146 /* 3 banks are switched to IRAM */
2147 banks_switched = 3;
2148 break;
2149 }
2150 }
2151
2152 ealloc_value |=
2153 ((banks_switched << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT)
2154 & HI_EARLY_ALLOC_IRAM_BANKS_MASK);
2155
2156 rv = hif_diag_write_access(scn,
2157 ealloc_targ_addr,
2158 ealloc_value);
2159 if (rv != CDF_STATUS_SUCCESS) {
2160 HIF_ERROR("%s: set early alloc val (%d)", __func__, rv);
2161 goto done;
2162 }
2163#endif
2164
2165 /* Tell Target to proceed with initialization */
2166 flag2_targ_addr = hif_hia_item_address(scn->target_type,
2167 offsetof(
2168 struct host_interest_s,
2169 hi_option_flag2));
2170
2171 rv = hif_diag_read_access(scn, flag2_targ_addr,
2172 &flag2_value);
2173 if (rv != CDF_STATUS_SUCCESS) {
2174 HIF_ERROR("%s: get option val (%d)", __func__, rv);
2175 goto done;
2176 }
2177
2178 flag2_value |= HI_OPTION_EARLY_CFG_DONE;
2179 rv = hif_diag_write_access(scn, flag2_targ_addr,
2180 flag2_value);
2181 if (rv != CDF_STATUS_SUCCESS) {
2182 HIF_ERROR("%s: set option val (%d)", __func__, rv);
2183 goto done;
2184 }
2185
2186 hif_wake_target_cpu(scn);
2187
2188done:
2189
2190 return rv;
2191}
2192#endif
2193
2194/**
2195 * hif_wlan_enable(): call the platform driver to enable wlan
2196 *
2197 * This function passes the con_mode and CE configuration to
2198 * platform driver to enable wlan.
2199 *
2200 * Return: void
2201 */
2202static int hif_wlan_enable(void)
2203{
2204 struct icnss_wlan_enable_cfg cfg;
2205 enum icnss_driver_mode mode;
2206 uint32_t con_mode = cds_get_conparam();
2207
2208 cfg.num_ce_tgt_cfg = target_ce_config_sz /
2209 sizeof(struct CE_pipe_config);
2210 cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *)target_ce_config;
2211 cfg.num_ce_svc_pipe_cfg = target_service_to_ce_map_sz /
2212 sizeof(struct service_to_pipe);
2213 cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *)target_service_to_ce_map;
2214 cfg.num_shadow_reg_cfg = shadow_cfg_sz / sizeof(struct shadow_reg_cfg);
2215 cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *) target_shadow_reg_cfg;
2216
2217 switch (con_mode) {
2218 case CDF_FTM_MODE:
2219 mode = ICNSS_FTM;
2220 break;
2221 case CDF_EPPING_MODE:
2222 mode = ICNSS_EPPING;
2223 break;
2224 default:
2225 mode = ICNSS_MISSION;
2226 break;
2227 }
2228 return icnss_wlan_enable(&cfg, mode, QWLAN_VERSIONSTR);
2229}
2230
2231#if ((!defined(QCA_WIFI_3_0_IHELIUM) && !defined(QCA_WIFI_3_0_ADRASTEA)) || defined(CONFIG_ICNSS))
2232static inline void cnss_pcie_notify_q6(void)
2233{
2234 return;
2235}
2236#endif
2237
2238/*
2239 * Called from PCI layer whenever a new PCI device is probed.
2240 * Initializes per-device HIF state and notifies the main
2241 * driver that a new HIF device is present.
2242 */
2243int hif_config_ce(hif_handle_t hif_hdl)
2244{
2245 struct HIF_CE_state *hif_state;
2246 struct HIF_CE_pipe_info *pipe_info;
2247 int pipe_num;
2248#ifdef ADRASTEA_SHADOW_REGISTERS
2249 int i;
2250#endif
2251 CDF_STATUS rv = CDF_STATUS_SUCCESS;
2252 int ret;
2253 struct ol_softc *scn = hif_hdl;
2254 struct icnss_soc_info soc_info;
2255
2256 /* if epping is enabled we need to use the epping configuration. */
2257 if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
2258 if (WLAN_IS_EPPING_IRQ(cds_get_conparam()))
2259 host_ce_config = host_ce_config_wlan_epping_irq;
2260 else
2261 host_ce_config = host_ce_config_wlan_epping_poll;
2262 target_ce_config = target_ce_config_wlan_epping;
2263 target_ce_config_sz = sizeof(target_ce_config_wlan_epping);
2264 target_service_to_ce_map =
2265 target_service_to_ce_map_wlan_epping;
2266 target_service_to_ce_map_sz =
2267 sizeof(target_service_to_ce_map_wlan_epping);
2268 }
2269
2270 ret = hif_wlan_enable();
2271
2272 if (ret) {
2273 HIF_ERROR("%s: hif_wlan_enable error = %d", __func__, ret);
2274 return CDF_STATUS_NOT_INITIALIZED;
2275 }
2276 if (IHELIUM_BU) {
2277 cnss_pcie_notify_q6();
2278 HIF_TRACE("%s: cnss_pcie_notify_q6 done, notice_send= %d",
2279 __func__, scn->notice_send);
2280 }
2281
2282 scn->notice_send = true;
2283
2284 cdf_mem_zero(&soc_info, sizeof(soc_info));
2285 ret = icnss_get_soc_info(&soc_info);
2286 if (ret < 0) {
2287 HIF_ERROR("%s: icnss_get_soc_info error = %d", __func__, ret);
2288 return CDF_STATUS_NOT_INITIALIZED;
2289 }
2290
2291 hif_state = (struct HIF_CE_state *)cdf_mem_malloc(sizeof(*hif_state));
2292 if (!hif_state) {
2293 return -ENOMEM;
2294 }
2295 cdf_mem_zero(hif_state, sizeof(*hif_state));
2296
2297 hif_state->scn = scn;
2298 scn->hif_hdl = hif_state;
2299 scn->mem = soc_info.v_addr;
2300 scn->mem_pa = soc_info.p_addr;
2301 scn->soc_version = soc_info.version;
2302
2303 cdf_spinlock_init(&hif_state->keep_awake_lock);
2304
2305 cdf_atomic_init(&hif_state->hif_thread_idle);
2306 cdf_atomic_inc(&hif_state->hif_thread_idle);
2307
2308 hif_state->keep_awake_count = 0;
2309
2310 hif_state->fake_sleep = false;
2311 hif_state->sleep_ticks = 0;
2312 cdf_softirq_timer_init(NULL, &hif_state->sleep_timer,
2313 hif_sleep_entry, (void *)hif_state,
2314 CDF_TIMER_TYPE_WAKE_APPS);
2315 hif_state->sleep_timer_init = true;
2316 hif_state->fw_indicator_address = FW_INDICATOR_ADDRESS;
2317#ifdef HIF_PCI
2318#if CONFIG_ATH_PCIE_MAX_PERF || CONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD
2319 /* Force AWAKE forever/till the driver is loaded */
2320 if (hif_target_sleep_state_adjust(scn, false, true) < 0)
2321 return -EACCES;
2322#endif
2323#endif
2324
2325 /* During CE initializtion */
2326 scn->ce_count = HOST_CE_COUNT;
2327 A_TARGET_ACCESS_LIKELY(scn);
2328 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
2329 struct CE_attr *attr;
2330
2331 pipe_info = &hif_state->pipe_info[pipe_num];
2332 pipe_info->pipe_num = pipe_num;
2333 pipe_info->HIF_CE_state = hif_state;
2334 attr = &host_ce_config[pipe_num];
2335 pipe_info->ce_hdl = ce_init(scn, pipe_num, attr);
2336 CDF_ASSERT(pipe_info->ce_hdl != NULL);
2337 if (pipe_info->ce_hdl == NULL) {
2338 rv = CDF_STATUS_E_FAILURE;
2339 A_TARGET_ACCESS_UNLIKELY(scn);
2340 goto err;
2341 }
2342
2343 if (pipe_num == DIAG_CE_ID) {
2344 /* Reserve the ultimate CE for
2345 * Diagnostic Window support */
2346 hif_state->ce_diag =
2347 hif_state->pipe_info[scn->ce_count - 1].ce_hdl;
2348 continue;
2349 }
2350
2351 pipe_info->buf_sz = (cdf_size_t) (attr->src_sz_max);
2352 cdf_spinlock_init(&pipe_info->recv_bufs_needed_lock);
2353 if (attr->dest_nentries > 0) {
2354 atomic_set(&pipe_info->recv_bufs_needed,
2355 init_buffer_count(attr->dest_nentries - 1));
2356 } else {
2357 atomic_set(&pipe_info->recv_bufs_needed, 0);
2358 }
2359 ce_tasklet_init(hif_state, (1 << pipe_num));
2360 ce_register_irq(hif_state, (1 << pipe_num));
2361 scn->request_irq_done = true;
2362 }
2363
2364 if (athdiag_procfs_init(scn) != 0) {
2365 A_TARGET_ACCESS_UNLIKELY(scn);
2366 goto err;
2367 }
2368 scn->athdiag_procfs_inited = true;
2369
2370 /*
2371 * Initially, establish CE completion handlers for use with BMI.
2372 * These are overwritten with generic handlers after we exit BMI phase.
2373 */
2374 pipe_info = &hif_state->pipe_info[BMI_CE_NUM_TO_TARG];
2375#ifdef HIF_PCI
2376 ce_send_cb_register(
2377 pipe_info->ce_hdl, hif_bmi_send_done, pipe_info, 0);
2378#ifndef BMI_RSP_POLLING
2379 pipe_info = &hif_state->pipe_info[BMI_CE_NUM_TO_HOST];
2380 ce_recv_cb_register(
2381 pipe_info->ce_hdl, hif_bmi_recv_data, pipe_info, 0);
2382#endif
2383#endif
2384 HIF_INFO_MED("%s: ce_init done", __func__);
2385
2386 rv = hif_set_hia(scn);
2387
2388 HIF_INFO_MED("%s: hif_set_hia done", __func__);
2389
2390 A_TARGET_ACCESS_UNLIKELY(scn);
2391
2392 if (rv != CDF_STATUS_SUCCESS)
2393 goto err;
2394 else
2395 init_tasklet_workers();
2396
2397 HIF_TRACE("%s: X, ret = %d\n", __func__, rv);
2398
2399#ifdef ADRASTEA_SHADOW_REGISTERS
2400 HIF_ERROR("Using Shadow Registers instead of CE Registers\n");
2401 for (i = 0; i < NUM_SHADOW_REGISTERS; i++) {
2402 HIF_ERROR("%s Shadow Register%d is mapped to address %x\n",
2403 __func__, i,
2404 (A_TARGET_READ(scn, (SHADOW_ADDRESS(i))) << 2));
2405 }
2406#endif
2407
2408
2409 return rv != CDF_STATUS_SUCCESS;
2410
2411err:
2412 /* Failure, so clean up */
2413 for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) {
2414 pipe_info = &hif_state->pipe_info[pipe_num];
2415 if (pipe_info->ce_hdl) {
2416 ce_unregister_irq(hif_state, (1 << pipe_num));
2417 scn->request_irq_done = false;
2418 ce_fini(pipe_info->ce_hdl);
2419 pipe_info->ce_hdl = NULL;
2420 pipe_info->buf_sz = 0;
2421 }
2422 }
2423 if (hif_state->sleep_timer_init) {
2424 cdf_softirq_timer_cancel(&hif_state->sleep_timer);
2425 cdf_softirq_timer_free(&hif_state->sleep_timer);
2426 hif_state->sleep_timer_init = false;
2427 }
2428 if (scn->hif_hdl) {
2429 scn->hif_hdl = NULL;
2430 cdf_mem_free(hif_state);
2431 }
2432 athdiag_procfs_remove();
2433 scn->athdiag_procfs_inited = false;
2434 HIF_TRACE("%s: X, ret = %d\n", __func__, rv);
2435 return CDF_STATUS_SUCCESS != CDF_STATUS_E_FAILURE;
2436}
2437
2438
2439
2440
2441
2442
2443#ifdef IPA_OFFLOAD
2444void hif_ipa_get_ce_resource(struct ol_softc *scn,
2445 uint32_t *ce_sr_base_paddr,
2446 uint32_t *ce_sr_ring_size,
2447 cdf_dma_addr_t *ce_reg_paddr)
2448{
2449 struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
2450 struct HIF_CE_pipe_info *pipe_info =
2451 &(hif_state->pipe_info[HIF_PCI_IPA_UC_ASSIGNED_CE]);
2452 struct CE_handle *ce_hdl = pipe_info->ce_hdl;
2453
2454 ce_ipa_get_resource(ce_hdl, ce_sr_base_paddr, ce_sr_ring_size,
2455 ce_reg_paddr);
2456 return;
2457}
2458#endif /* IPA_OFFLOAD */
2459
2460
2461#ifdef ADRASTEA_SHADOW_REGISTERS
2462
2463/*
2464 Current shadow register config
2465
2466 -----------------------------------------------------------
2467 Shadow Register | CE | src/dst write index
2468 -----------------------------------------------------------
2469 0 | 0 | src
2470 1 No Config - Doesn't point to anything
2471 2 No Config - Doesn't point to anything
2472 3 | 3 | src
2473 4 | 4 | src
2474 5 | 5 | src
2475 6 No Config - Doesn't point to anything
2476 7 | 7 | src
2477 8 No Config - Doesn't point to anything
2478 9 No Config - Doesn't point to anything
2479 10 No Config - Doesn't point to anything
2480 11 No Config - Doesn't point to anything
2481 -----------------------------------------------------------
2482 12 No Config - Doesn't point to anything
2483 13 | 1 | dst
2484 14 | 2 | dst
2485 15 No Config - Doesn't point to anything
2486 16 No Config - Doesn't point to anything
2487 17 No Config - Doesn't point to anything
2488 18 No Config - Doesn't point to anything
2489 19 | 7 | dst
2490 20 | 8 | dst
2491 21 No Config - Doesn't point to anything
2492 22 No Config - Doesn't point to anything
2493 23 No Config - Doesn't point to anything
2494 -----------------------------------------------------------
2495
2496
2497 ToDo - Move shadow register config to following in the future
2498 This helps free up a block of shadow registers towards the end.
2499 Can be used for other purposes
2500
2501 -----------------------------------------------------------
2502 Shadow Register | CE | src/dst write index
2503 -----------------------------------------------------------
2504 0 | 0 | src
2505 1 | 3 | src
2506 2 | 4 | src
2507 3 | 5 | src
2508 4 | 7 | src
2509 -----------------------------------------------------------
2510 5 | 1 | dst
2511 6 | 2 | dst
2512 7 | 7 | dst
2513 8 | 8 | dst
2514 -----------------------------------------------------------
2515 9 No Config - Doesn't point to anything
2516 12 No Config - Doesn't point to anything
2517 13 No Config - Doesn't point to anything
2518 14 No Config - Doesn't point to anything
2519 15 No Config - Doesn't point to anything
2520 16 No Config - Doesn't point to anything
2521 17 No Config - Doesn't point to anything
2522 18 No Config - Doesn't point to anything
2523 19 No Config - Doesn't point to anything
2524 20 No Config - Doesn't point to anything
2525 21 No Config - Doesn't point to anything
2526 22 No Config - Doesn't point to anything
2527 23 No Config - Doesn't point to anything
2528 -----------------------------------------------------------
2529*/
2530
2531u32 shadow_sr_wr_ind_addr(struct ol_softc *scn, u32 ctrl_addr)
2532{
2533 u32 addr = 0;
2534
2535 switch (COPY_ENGINE_ID(ctrl_addr)) {
2536 case 0:
2537 addr = SHADOW_VALUE0;
2538 break;
2539 case 3:
2540 addr = SHADOW_VALUE3;
2541 break;
2542 case 4:
2543 addr = SHADOW_VALUE4;
2544 break;
2545 case 5:
2546 addr = SHADOW_VALUE5;
2547 break;
2548 case 7:
2549 addr = SHADOW_VALUE7;
2550 break;
2551 default:
2552 printk("invalid CE ctrl_addr\n");
2553 CDF_ASSERT(0);
2554
2555 }
2556 return addr;
2557
2558}
2559
2560u32 shadow_dst_wr_ind_addr(struct ol_softc *scn, u32 ctrl_addr)
2561{
2562 u32 addr = 0;
2563
2564 switch (COPY_ENGINE_ID(ctrl_addr)) {
2565 case 1:
2566 addr = SHADOW_VALUE13;
2567 break;
2568 case 2:
2569 addr = SHADOW_VALUE14;
2570 break;
2571 case 7:
2572 addr = SHADOW_VALUE19;
2573 break;
2574 case 8:
2575 addr = SHADOW_VALUE20;
2576 break;
2577 default:
2578 printk("invalid CE ctrl_addr\n");
2579 CDF_ASSERT(0);
2580 }
2581
2582 return addr;
2583
2584}
2585#endif
2586
Dhanashri Atre65b674f2015-10-30 15:12:03 -07002587#if defined(FEATURE_LRO)
2588/**
2589 * ce_lro_flush_cb_register() - register the LRO flush
2590 * callback
2591 * @scn: HIF context
2592 * @handler: callback function
2593 * @data: opaque data pointer to be passed back
2594 *
2595 * Store the LRO flush callback provided
2596 *
2597 * Return: none
2598 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002599void ce_lro_flush_cb_register(struct ol_softc *scn,
2600 void (handler)(void *), void *data)
2601{
Dhanashri Atre65b674f2015-10-30 15:12:03 -07002602 uint8_t ul, dl;
2603 int ul_polled, dl_polled;
2604
2605 CDF_ASSERT(scn != NULL);
2606
2607 if (CDF_STATUS_SUCCESS !=
2608 hif_map_service_to_pipe(scn, HTT_DATA_MSG_SVC,
2609 &ul, &dl, &ul_polled, &dl_polled)) {
2610 printk("%s cannot map service to pipe\n", __FUNCTION__);
2611 return;
2612 } else {
2613 struct CE_state *ce_state;
2614 ce_state = scn->ce_id_to_state[dl];
2615 ce_state->lro_flush_cb = handler;
2616 ce_state->lro_data = data;
2617 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002618}
Dhanashri Atre65b674f2015-10-30 15:12:03 -07002619
2620/**
2621 * ce_lro_flush_cb_deregister() - deregister the LRO flush
2622 * callback
2623 * @scn: HIF context
2624 *
2625 * Remove the LRO flush callback
2626 *
2627 * Return: none
2628 */
2629void ce_lro_flush_cb_deregister(struct ol_softc *scn)
2630{
2631 uint8_t ul, dl;
2632 int ul_polled, dl_polled;
2633
2634 CDF_ASSERT(scn != NULL);
2635
2636 if (CDF_STATUS_SUCCESS !=
2637 hif_map_service_to_pipe(scn, HTT_DATA_MSG_SVC,
2638 &ul, &dl, &ul_polled, &dl_polled)) {
2639 printk("%s cannot map service to pipe\n", __FUNCTION__);
2640 return;
2641 } else {
2642 struct CE_state *ce_state;
2643 ce_state = scn->ce_id_to_state[dl];
2644 ce_state->lro_flush_cb = NULL;
2645 ce_state->lro_data = NULL;
2646 }
2647}
2648#endif