blob: 178aa9ad30e92cd02d5d347d96430492e053b6eb [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Komal Seelam644263d2016-02-22 20:45:49 +05302 * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -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#ifndef __COPY_ENGINE_INTERNAL_H__
28#define __COPY_ENGINE_INTERNAL_H__
29
30#include <hif.h> /* A_TARGET_WRITE */
31
32/* Copy Engine operational state */
33enum CE_op_state {
34 CE_UNUSED,
35 CE_PAUSED,
36 CE_RUNNING,
37};
38
39enum ol_ath_hif_ce_ecodes {
40 CE_RING_DELTA_FAIL = 0
41};
42
43struct CE_src_desc;
44
45/* Copy Engine Ring internal state */
46struct CE_ring_state {
47
48 /* Number of entries in this ring; must be power of 2 */
49 unsigned int nentries;
50 unsigned int nentries_mask;
51
52 /*
53 * For dest ring, this is the next index to be processed
54 * by software after it was/is received into.
55 *
56 * For src ring, this is the last descriptor that was sent
57 * and completion processed by software.
58 *
59 * Regardless of src or dest ring, this is an invariant
60 * (modulo ring size):
61 * write index >= read index >= sw_index
62 */
63 unsigned int sw_index;
64 unsigned int write_index; /* cached copy */
65 /*
66 * For src ring, this is the next index not yet processed by HW.
67 * This is a cached copy of the real HW index (read index), used
68 * for avoiding reading the HW index register more often than
69 * necessary.
70 * This extends the invariant:
71 * write index >= read index >= hw_index >= sw_index
72 *
73 * For dest ring, this is currently unused.
74 */
75 unsigned int hw_index; /* cached copy */
76
77 /* Start of DMA-coherent area reserved for descriptors */
78 void *base_addr_owner_space_unaligned; /* Host address space */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053079 qdf_dma_addr_t base_addr_CE_space_unaligned; /* CE address space */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080080
81 /*
82 * Actual start of descriptors.
83 * Aligned to descriptor-size boundary.
84 * Points into reserved DMA-coherent area, above.
85 */
86 void *base_addr_owner_space; /* Host address space */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053087 qdf_dma_addr_t base_addr_CE_space; /* CE address space */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080088 /*
89 * Start of shadow copy of descriptors, within regular memory.
90 * Aligned to descriptor-size boundary.
91 */
92 char *shadow_base_unaligned;
93 struct CE_src_desc *shadow_base;
94
95 unsigned int low_water_mark_nentries;
96 unsigned int high_water_mark_nentries;
97 void **per_transfer_context;
98 OS_DMA_MEM_CONTEXT(ce_dmacontext) /* OS Specific DMA context */
99};
100
101/* Copy Engine internal state */
102struct CE_state {
Komal Seelam644263d2016-02-22 20:45:49 +0530103 struct hif_softc *scn;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800104 unsigned int id;
105 unsigned int attr_flags; /* CE_ATTR_* */
106 uint32_t ctrl_addr; /* relative to BAR */
107 enum CE_op_state state;
108
109#ifdef WLAN_FEATURE_FASTPATH
Manjunathappa Prakash7399f142016-04-13 23:38:16 -0700110 fastpath_msg_handler fastpath_handler;
111 void *context;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800112#endif /* WLAN_FEATURE_FASTPATH */
113
114 ce_send_cb send_cb;
115 void *send_context;
116
117 CE_recv_cb recv_cb;
118 void *recv_context;
119
120 /* misc_cbs - are any callbacks besides send and recv enabled? */
121 uint8_t misc_cbs;
122
123 CE_watermark_cb watermark_cb;
124 void *wm_context;
125
126 /*Record the state of the copy compl interrupt */
127 int disable_copy_compl_intr;
128
129 unsigned int src_sz_max;
130 struct CE_ring_state *src_ring;
131 struct CE_ring_state *dest_ring;
132 atomic_t rx_pending;
Houston Hoffman44b7e4a2015-09-03 17:01:22 -0700133
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530134 qdf_spinlock_t ce_index_lock;
Houston Hoffman18c7fc52015-09-02 11:44:42 -0700135 bool force_break; /* Flag to indicate whether to
136 * break out the DPC context */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800137
Houston Hoffman05652722016-04-29 16:58:59 -0700138 qdf_time_t ce_service_yield_time;
Houston Hoffman5bf441a2015-09-02 11:52:10 -0700139 unsigned int receive_count; /* count Num Of Receive Buffers
140 * handled for one interrupt
141 * DPC routine */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800142 /* epping */
143 bool timer_inited;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530144 qdf_timer_t poll_timer;
Houston Hoffmanc7d54292016-04-13 18:55:37 -0700145
146 /* datapath - for faster access, use bools instead of a bitmap */
147 bool htt_tx_data;
148 bool htt_rx_data;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800149 void (*lro_flush_cb)(void *);
150 void *lro_data;
151};
152
153/* Descriptor rings must be aligned to this boundary */
154#define CE_DESC_RING_ALIGN 8
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700155#define CLOCK_OVERRIDE 0x2
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800156
157#ifdef QCA_WIFI_3_0
158#define HIF_CE_DESC_ADDR_TO_DMA(desc) \
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530159 (qdf_dma_addr_t)(((uint64_t)(desc)->buffer_addr + \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800160 ((uint64_t)((desc)->buffer_addr_hi & 0x1F) << 32)))
161#else
162#define HIF_CE_DESC_ADDR_TO_DMA(desc) \
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530163 (qdf_dma_addr_t)((desc)->buffer_addr)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800164#endif
165
166#ifdef QCA_WIFI_3_0
167struct CE_src_desc {
168 uint32_t buffer_addr:32;
169#if _BYTE_ORDER == _BIG_ENDIAN
170 uint32_t gather:1,
171 enable_11h:1,
172 meta_data_low:2, /* fw_metadata_low */
173 packet_result_offset:12,
174 toeplitz_hash_enable:1,
175 addr_y_search_disable:1,
176 addr_x_search_disable:1,
177 misc_int_disable:1,
178 target_int_disable:1,
179 host_int_disable:1,
180 dest_byte_swap:1,
181 byte_swap:1,
182 type:2,
183 tx_classify:1,
184 buffer_addr_hi:5;
185 uint32_t meta_data:16, /* fw_metadata_high */
186 nbytes:16; /* length in register map */
187#else
188 uint32_t buffer_addr_hi:5,
189 tx_classify:1,
190 type:2,
191 byte_swap:1, /* src_byte_swap */
192 dest_byte_swap:1,
193 host_int_disable:1,
194 target_int_disable:1,
195 misc_int_disable:1,
196 addr_x_search_disable:1,
197 addr_y_search_disable:1,
198 toeplitz_hash_enable:1,
199 packet_result_offset:12,
200 meta_data_low:2, /* fw_metadata_low */
201 enable_11h:1,
202 gather:1;
203 uint32_t nbytes:16, /* length in register map */
204 meta_data:16; /* fw_metadata_high */
205#endif
206 uint32_t toeplitz_hash_result:32;
207};
208
209struct CE_dest_desc {
210 uint32_t buffer_addr:32;
211#if _BYTE_ORDER == _BIG_ENDIAN
212 uint32_t gather:1,
213 enable_11h:1,
214 meta_data_low:2, /* fw_metadata_low */
215 packet_result_offset:12,
216 toeplitz_hash_enable:1,
217 addr_y_search_disable:1,
218 addr_x_search_disable:1,
219 misc_int_disable:1,
220 target_int_disable:1,
221 host_int_disable:1,
222 byte_swap:1,
223 src_byte_swap:1,
224 type:2,
225 tx_classify:1,
226 buffer_addr_hi:5;
227 uint32_t meta_data:16, /* fw_metadata_high */
228 nbytes:16; /* length in register map */
229#else
230 uint32_t buffer_addr_hi:5,
231 tx_classify:1,
232 type:2,
233 src_byte_swap:1,
234 byte_swap:1, /* dest_byte_swap */
235 host_int_disable:1,
236 target_int_disable:1,
237 misc_int_disable:1,
238 addr_x_search_disable:1,
239 addr_y_search_disable:1,
240 toeplitz_hash_enable:1,
241 packet_result_offset:12,
242 meta_data_low:2, /* fw_metadata_low */
243 enable_11h:1,
244 gather:1;
245 uint32_t nbytes:16, /* length in register map */
246 meta_data:16; /* fw_metadata_high */
247#endif
248 uint32_t toeplitz_hash_result:32;
249};
250#else
251struct CE_src_desc {
252 uint32_t buffer_addr;
253#if _BYTE_ORDER == _BIG_ENDIAN
Houston Hoffman56e0d702016-05-05 17:48:06 -0700254 uint32_t meta_data:12,
255 target_int_disable:1,
256 host_int_disable:1,
257 byte_swap:1,
258 gather:1,
259 nbytes:16;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800260#else
261
Houston Hoffman56e0d702016-05-05 17:48:06 -0700262 uint32_t nbytes:16,
263 gather:1,
264 byte_swap:1,
265 host_int_disable:1,
266 target_int_disable:1,
267 meta_data:12;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800268#endif
269};
270
271struct CE_dest_desc {
272 uint32_t buffer_addr;
273#if _BYTE_ORDER == _BIG_ENDIAN
Houston Hoffman56e0d702016-05-05 17:48:06 -0700274 uint32_t meta_data:12,
275 target_int_disable:1,
276 host_int_disable:1,
277 byte_swap:1,
278 gather:1,
279 nbytes:16;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800280#else
281 uint32_t nbytes:16,
Houston Hoffman56e0d702016-05-05 17:48:06 -0700282 gather:1,
283 byte_swap:1,
284 host_int_disable:1,
285 target_int_disable:1,
286 meta_data:12;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800287#endif
288};
289#endif /* QCA_WIFI_3_0 */
290
291#define CE_SENDLIST_ITEMS_MAX 12
292
Houston Hoffman68e837e2015-12-04 12:57:24 -0800293/**
294 * union ce_desc - unified data type for ce descriptors
295 *
296 * Both src and destination descriptors follow the same format.
297 * They use different data structures for different access symantics.
298 * Here we provice a unifying data type.
299 */
300union ce_desc {
301 struct CE_src_desc src_desc;
302 struct CE_dest_desc dest_desc;
303};
304
305/**
306 * enum hif_ce_event_type - HIF copy engine event type
307 * @HIF_RX_DESC_POST: event recorded before updating write index of RX ring.
308 * @HIF_RX_DESC_COMPLETION: event recorded before updating sw index of RX ring.
309 * @HIF_TX_GATHER_DESC_POST: post gather desc. (no write index update)
310 * @HIF_TX_DESC_POST: event recorded before updating write index of TX ring.
311 * @HIF_TX_DESC_COMPLETION: event recorded before updating sw index of TX ring.
Houston Hoffmanfa260aa2016-04-26 16:14:13 -0700312 * @FAST_RX_WRITE_INDEX_UPDATE: event recorded before updating the write index
313 * of the RX ring in fastpath
314 * @FAST_RX_SOFTWARE_INDEX_UPDATE: event recorded before updating the software
315 * index of the RX ring in fastpath
316 * @FAST_TX_WRITE_INDEX_UPDATE: event recorded before updating the write index
317 * of the TX ring in fastpath
318 * @FAST_TX_SOFTWARE_INDEX_UPDATE: event recorded before updating the software
319 * index of the RX ring in fastpath
320 *
Houston Hoffman4275ba22015-12-06 21:02:11 -0800321 * @HIF_IRQ_EVENT: event recorded in the irq before scheduling the bh
322 * @HIF_CE_TASKLET_ENTRY: records the start of the ce_tasklet
323 * @HIF_CE_TASKLET_RESCHEDULE: records the rescheduling of the wlan_tasklet
324 * @HIF_CE_TASKLET_EXIT: records the exit of the wlan tasklet without reschedule
Houston Hoffmana575ec22015-12-14 16:35:15 -0800325 * @HIF_CE_REAP_ENTRY: records when we process completion outside of a bh
326 * @HIF_CE_REAP_EXIT: records when we process completion outside of a bh
Houston Hoffmanfa260aa2016-04-26 16:14:13 -0700327 * @NAPI_SCHEDULE: records when napi is scheduled from the irq context
328 * @NAPI_POLL_ENTER: records the start of the napi poll function
329 * @NAPI_COMPLETE: records when interrupts are reenabled
330 * @NAPI_POLL_EXIT: records when the napi poll function returns
Houston Hoffman68e837e2015-12-04 12:57:24 -0800331 */
332enum hif_ce_event_type {
333 HIF_RX_DESC_POST,
334 HIF_RX_DESC_COMPLETION,
335 HIF_TX_GATHER_DESC_POST,
336 HIF_TX_DESC_POST,
337 HIF_TX_DESC_COMPLETION,
Houston Hoffmanfa260aa2016-04-26 16:14:13 -0700338 FAST_RX_WRITE_INDEX_UPDATE,
339 FAST_RX_SOFTWARE_INDEX_UPDATE,
340 FAST_TX_WRITE_INDEX_UPDATE,
341 FAST_TX_SOFTWARE_INDEX_UPDATE,
342
343 HIF_IRQ_EVENT = 0x10,
Houston Hoffman4275ba22015-12-06 21:02:11 -0800344 HIF_CE_TASKLET_ENTRY,
345 HIF_CE_TASKLET_RESCHEDULE,
346 HIF_CE_TASKLET_EXIT,
Houston Hoffmana575ec22015-12-14 16:35:15 -0800347 HIF_CE_REAP_ENTRY,
348 HIF_CE_REAP_EXIT,
Houston Hoffmanfa260aa2016-04-26 16:14:13 -0700349 NAPI_SCHEDULE,
350 NAPI_POLL_ENTER,
351 NAPI_COMPLETE,
352 NAPI_POLL_EXIT,
Houston Hoffman68e837e2015-12-04 12:57:24 -0800353};
354
355void ce_init_ce_desc_event_log(int ce_id, int size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530356void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id,
357 enum hif_ce_event_type type,
358 union ce_desc *descriptor, void *memory,
359 int index);
Houston Hoffman68e837e2015-12-04 12:57:24 -0800360
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800361enum ce_sendlist_type_e {
362 CE_SIMPLE_BUFFER_TYPE,
363 /* TBDXXX: CE_RX_DESC_LIST, */
364};
365
366/*
367 * There's a public "ce_sendlist" and a private "ce_sendlist_s".
368 * The former is an opaque structure with sufficient space
369 * to hold the latter. The latter is the actual structure
370 * definition and it is only used internally. The opaque version
371 * of the structure allows callers to allocate an instance on the
372 * run-time stack without knowing any of the details of the
373 * structure layout.
374 */
375struct ce_sendlist_s {
376 unsigned int num_items;
377 struct ce_sendlist_item {
378 enum ce_sendlist_type_e send_type;
379 dma_addr_t data; /* e.g. buffer or desc list */
380 union {
381 unsigned int nbytes; /* simple buffer */
382 unsigned int ndesc; /* Rx descriptor list */
383 } u;
384 /* flags: externally-specified flags;
385 * OR-ed with internal flags */
386 uint32_t flags;
387 uint32_t user_flags;
388 } item[CE_SENDLIST_ITEMS_MAX];
389};
390
Houston Hoffman05652722016-04-29 16:58:59 -0700391bool hif_ce_service_should_yield(struct hif_softc *scn, struct CE_state
392 *ce_state);
393
Manjunathappa Prakash4a9c3a82016-04-14 01:12:14 -0700394#ifdef WLAN_FEATURE_FASTPATH
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800395void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl);
Manjunathappa Prakash7399f142016-04-13 23:38:16 -0700396void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl);
Manjunathappa Prakash4a9c3a82016-04-14 01:12:14 -0700397#else
398static inline void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl)
399{
400}
401
402static inline void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl)
403{
404}
405#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800406
407/* which ring of a CE? */
408#define CE_RING_SRC 0
409#define CE_RING_DEST 1
410
411#define CDC_WAR_MAGIC_STR 0xceef0000
412#define CDC_WAR_DATA_CE 4
413
414/* Additional internal-only ce_send flags */
415#define CE_SEND_FLAG_GATHER 0x00010000 /* Use Gather */
416#endif /* __COPY_ENGINE_INTERNAL_H__ */