Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Marvell International Ltd.
3 : : */
4 : :
5 : : #include <eal_export.h>
6 : : #include <rte_vect.h>
7 : :
8 : : #include "cnxk_dmadev.h"
9 : : #include <rte_event_dma_adapter.h>
10 : :
11 : : #include <cn10k_eventdev.h>
12 : : #include <cnxk_eventdev.h>
13 : :
14 : : static __plt_always_inline void
15 : : __dpi_cpy_scalar(uint64_t *src, uint64_t *dst, uint8_t n)
16 : : {
17 : : uint8_t i;
18 : :
19 [ # # # # : 0 : for (i = 0; i < n; i++)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
20 : 0 : dst[i] = src[i];
21 : : }
22 : :
23 : : #if defined(RTE_ARCH_ARM64)
24 : : static __plt_always_inline void
25 : : __dpi_cpy_vector(uint64_t *src, uint64_t *dst, uint8_t n)
26 : : {
27 : : uint64x2_t vec;
28 : : uint8_t i;
29 : :
30 : : for (i = 0; i < n; i += 2) {
31 : : vec = vld1q_u64((const uint64_t *)&src[i]);
32 : : vst1q_u64(&dst[i], vec);
33 : : }
34 : : }
35 : :
36 : : static __plt_always_inline void
37 : : __dpi_cpy_vector_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
38 : : {
39 : : uint64x2_t mask = {0xFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL};
40 : : uint64x2_t vec;
41 : : uint8_t i;
42 : :
43 : : for (i = 0; i < n; i++) {
44 : : vec = vld1q_u64((const uint64_t *)&src[i]);
45 : : vec = vextq_u64(vec, vec, 1);
46 : : vec = vandq_u64(vec, mask);
47 : : vst1q_u64(dst, vec);
48 : : dst += 2;
49 : : }
50 : : }
51 : :
52 : : static __plt_always_inline uint8_t
53 : : __dpi_cpy_vector_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
54 : : {
55 : : uint64x2_t mask = {0xFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL};
56 : : uint64x2_t vec;
57 : : uint8_t i;
58 : :
59 : : for (i = 0; i < n && lmt; i++) {
60 : : vec = vld1q_u64((const uint64_t *)&src[i]);
61 : : vec = vextq_u64(vec, vec, 1);
62 : : vec = vandq_u64(vec, mask);
63 : : vst1q_u64(dst, vec);
64 : : dst += 2;
65 : : lmt -= 2;
66 : : }
67 : :
68 : : return i;
69 : : }
70 : : #else
71 : : static __plt_always_inline void
72 : : __dpi_cpy_scalar_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
73 : : {
74 : : uint8_t i;
75 : :
76 [ # # # # : 0 : for (i = 0; i < n; i++) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
77 : 0 : *dst++ = src[i].length;
78 : 0 : *dst++ = src[i].addr;
79 : : }
80 : : }
81 : :
82 : : static __plt_always_inline uint8_t
83 : : __dpi_cpy_scalar_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
84 : : {
85 : : uint8_t i;
86 : :
87 [ # # # # : 0 : for (i = 0; i < n && lmt; i++) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
88 : 0 : *dst++ = src[i].length;
89 : 0 : *dst++ = src[i].addr;
90 : 0 : lmt -= 2;
91 : : }
92 : :
93 : : return i;
94 : : }
95 : : #endif
96 : :
97 : : static __plt_always_inline void
98 : : __dpi_cpy(uint64_t *src, uint64_t *dst, uint8_t n)
99 : : {
100 : : #if defined(RTE_ARCH_ARM64)
101 : : __dpi_cpy_vector(src, dst, n);
102 : : #else
103 : : __dpi_cpy_scalar(src, dst, n);
104 : : #endif
105 : : }
106 : :
107 : : static __plt_always_inline void
108 : : __dpi_cpy_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
109 : : {
110 : : #if defined(RTE_ARCH_ARM64)
111 : : __dpi_cpy_vector_sg(src, dst, n);
112 : : #else
113 : : __dpi_cpy_scalar_sg(src, dst, n);
114 : : #endif
115 : : }
116 : :
117 : : static __plt_always_inline uint8_t
118 : : __dpi_cpy_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
119 : : {
120 : : #if defined(RTE_ARCH_ARM64)
121 : : return __dpi_cpy_vector_sg_lmt(src, dst, n, lmt);
122 : : #else
123 : : return __dpi_cpy_scalar_sg_lmt(src, dst, n, lmt);
124 : : #endif
125 : : }
126 : :
127 : : static __plt_always_inline int
128 : : __dpi_queue_write_single(struct cnxk_dpi_vf_s *dpi, uint64_t *cmd)
129 : : {
130 : 0 : uint64_t *ptr = dpi->chunk_base;
131 : :
132 : : /* Check if command fits in the current chunk. */
133 [ # # ]: 0 : if (dpi->chunk_head + CNXK_DPI_DW_PER_SINGLE_CMD < dpi->chunk_size_m1) {
134 : 0 : ptr += dpi->chunk_head;
135 : :
136 : : __dpi_cpy_scalar(cmd, ptr, CNXK_DPI_DW_PER_SINGLE_CMD);
137 : 0 : dpi->chunk_head += CNXK_DPI_DW_PER_SINGLE_CMD;
138 : : } else {
139 : 0 : uint64_t *new_buff = NULL;
140 : : int count;
141 : :
142 [ # # # # : 0 : if (rte_mempool_get(dpi->chunk_pool, (void **)&new_buff) < 0) {
# # # # ]
143 : 0 : plt_dpi_dbg("Failed to alloc next buffer from NPA");
144 : 0 : return -ENOSPC;
145 : : }
146 : :
147 : : /*
148 : : * Figure out how many cmd words will fit in the current chunk
149 : : * and copy them.
150 : : */
151 : 0 : count = dpi->chunk_size_m1 - dpi->chunk_head;
152 : 0 : ptr += dpi->chunk_head;
153 : :
154 : 0 : __dpi_cpy_scalar(cmd, ptr, count);
155 : :
156 : 0 : ptr += count;
157 : 0 : *ptr = (uint64_t)new_buff;
158 : : ptr = new_buff;
159 : :
160 : : /* Copy the remaining cmd words to new chunk. */
161 : 0 : __dpi_cpy_scalar(cmd + count, ptr, CNXK_DPI_DW_PER_SINGLE_CMD - count);
162 : :
163 : 0 : dpi->chunk_base = new_buff;
164 : 0 : dpi->chunk_head = CNXK_DPI_DW_PER_SINGLE_CMD - count;
165 : : }
166 : :
167 : : return 0;
168 : : }
169 : :
170 : : static __plt_always_inline int
171 : : __dpi_queue_write_sg(struct cnxk_dpi_vf_s *dpi, uint64_t *hdr, const struct rte_dma_sge *src,
172 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst)
173 : : {
174 : 0 : uint8_t cmd_len = CNXK_DPI_CMD_LEN(nb_src, nb_dst);
175 : 0 : uint64_t *ptr = dpi->chunk_base;
176 : :
177 : : /* Check if command fits in the current chunk. */
178 [ # # ]: 0 : if (dpi->chunk_head + cmd_len < dpi->chunk_size_m1) {
179 : 0 : ptr += dpi->chunk_head;
180 : :
181 : : __dpi_cpy(hdr, ptr, CNXK_DPI_HDR_LEN);
182 : 0 : ptr += CNXK_DPI_HDR_LEN;
183 : : __dpi_cpy_sg(src, ptr, nb_src);
184 : 0 : ptr += (nb_src << 1);
185 : : __dpi_cpy_sg(dst, ptr, nb_dst);
186 : :
187 : 0 : dpi->chunk_head += cmd_len;
188 : : } else {
189 : 0 : uint64_t *new_buff = NULL, *buf;
190 : : uint16_t count;
191 : :
192 [ # # # # : 0 : if (rte_mempool_get(dpi->chunk_pool, (void **)&new_buff) < 0) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
193 : 0 : plt_dpi_dbg("Failed to alloc next buffer from NPA");
194 : 0 : return -ENOSPC;
195 : : }
196 : :
197 : : /*
198 : : * Figure out how many cmd words will fit in the current chunk
199 : : * and copy them, copy the rest to the new buffer.
200 : : */
201 : 0 : count = dpi->chunk_size_m1 - dpi->chunk_head;
202 : 0 : ptr += dpi->chunk_head;
203 : 0 : buf = new_buff;
204 [ # # # # : 0 : if (count <= 4) {
# # # # #
# # # #
# ]
205 : 0 : __dpi_cpy(hdr, ptr, count);
206 : 0 : ptr += count;
207 : : __dpi_cpy(&hdr[count], buf, 4);
208 : 0 : buf += (4 - count);
209 : : } else {
210 : : uint8_t i;
211 : :
212 : : __dpi_cpy(hdr, ptr, 4);
213 : 0 : ptr += 4;
214 : 0 : count -= 4;
215 : :
216 : : i = __dpi_cpy_sg_lmt(src, ptr, nb_src, count);
217 : 0 : src += i;
218 : 0 : nb_src -= i;
219 : 0 : count -= (i << 1);
220 : 0 : ptr += (i << 1);
221 : :
222 : : i = __dpi_cpy_sg_lmt(dst, ptr, nb_dst, count);
223 : 0 : dst += i;
224 : 0 : nb_dst -= i;
225 : 0 : ptr += (i << 1);
226 : : }
227 : 0 : *ptr = (uint64_t)new_buff;
228 : :
229 : 0 : __dpi_cpy_sg(src, buf, nb_src);
230 : 0 : buf += (nb_src << 1);
231 : :
232 : 0 : __dpi_cpy_sg(dst, buf, nb_dst);
233 : 0 : buf += (nb_dst << 1);
234 : :
235 : 0 : dpi->chunk_base = new_buff;
236 : 0 : dpi->chunk_head = buf - new_buff;
237 : : }
238 : :
239 : : return 0;
240 : : }
241 : :
242 : : int
243 : 0 : cnxk_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t dst, uint32_t length,
244 : : uint64_t flags)
245 : : {
246 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
247 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
248 : : uint64_t cmd[CNXK_DPI_DW_PER_SINGLE_CMD];
249 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
250 : : uint8_t *comp_ptr;
251 : : int rc;
252 : :
253 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == (dpi_conf->c_desc.head & max_cnt)))
254 : : return -ENOSPC;
255 : :
256 : 0 : comp_ptr = &dpi_conf->c_desc
257 : 0 : .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * CNXK_DPI_COMPL_OFFSET];
258 : 0 : dpi_conf->c_desc.tail++;
259 : :
260 : 0 : cmd[0] = (1UL << 54) | (1UL << 48);
261 : 0 : cmd[1] = dpi_conf->cmd.u | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
262 : 0 : cmd[2] = (uint64_t)comp_ptr;
263 : 0 : cmd[4] = length;
264 : 0 : cmd[6] = length;
265 : :
266 : : /*
267 : : * For inbound case, src pointers are last pointers.
268 : : * For all other cases, src pointers are first pointers.
269 : : */
270 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
271 : 0 : cmd[5] = dst;
272 : 0 : cmd[7] = src;
273 : : } else {
274 : 0 : cmd[5] = src;
275 : 0 : cmd[7] = dst;
276 : : }
277 : :
278 : : rc = __dpi_queue_write_single(dpivf, cmd);
279 [ # # ]: 0 : if (unlikely(rc)) {
280 : 0 : dpi_conf->c_desc.tail--;
281 : 0 : return rc;
282 : : }
283 : :
284 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
285 : : rte_wmb();
286 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
287 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
288 : 0 : dpivf->total_pnum_words = 0;
289 : : } else {
290 : 0 : dpivf->total_pnum_words += CNXK_DPI_DW_PER_SINGLE_CMD;
291 : : }
292 : :
293 : 0 : dpi_conf->stats.submitted += 1;
294 : :
295 : 0 : return dpi_conf->desc_idx++;
296 : : }
297 : :
298 : : int
299 : 0 : cnxk_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
300 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst, uint64_t flags)
301 : : {
302 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
303 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
304 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
305 : : const struct rte_dma_sge *fptr, *lptr;
306 : : uint8_t *comp_ptr;
307 : : uint64_t hdr[4];
308 : : int rc;
309 : :
310 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == (dpi_conf->c_desc.head & max_cnt)))
311 : : return -ENOSPC;
312 : :
313 : 0 : comp_ptr = &dpi_conf->c_desc
314 : 0 : .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * CNXK_DPI_COMPL_OFFSET];
315 : 0 : dpi_conf->c_desc.tail++;
316 : :
317 : 0 : hdr[1] = dpi_conf->cmd.u | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
318 : 0 : hdr[2] = (uint64_t)comp_ptr;
319 : :
320 : : /*
321 : : * For inbound case, src pointers are last pointers.
322 : : * For all other cases, src pointers are first pointers.
323 : : */
324 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
325 : : fptr = dst;
326 : : lptr = src;
327 : : RTE_SWAP(nb_src, nb_dst);
328 : : } else {
329 : : fptr = src;
330 : : lptr = dst;
331 : : }
332 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
333 : :
334 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
335 [ # # ]: 0 : if (unlikely(rc)) {
336 : 0 : dpi_conf->c_desc.tail--;
337 : 0 : return rc;
338 : : }
339 : :
340 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
341 : : rte_wmb();
342 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
343 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
344 : 0 : dpivf->total_pnum_words = 0;
345 : : } else {
346 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
347 : : }
348 : :
349 : 0 : dpi_conf->stats.submitted += 1;
350 : :
351 : 0 : return dpi_conf->desc_idx++;
352 : : }
353 : :
354 : : int
355 : 0 : cn10k_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t dst,
356 : : uint32_t length, uint64_t flags)
357 : : {
358 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
359 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
360 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
361 : : uint64_t cmd[CNXK_DPI_DW_PER_SINGLE_CMD];
362 : : uint8_t *comp_ptr;
363 : : int rc;
364 : :
365 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == (dpi_conf->c_desc.head & max_cnt)))
366 : : return -ENOSPC;
367 : :
368 : 0 : comp_ptr = &dpi_conf->c_desc
369 : 0 : .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * CNXK_DPI_COMPL_OFFSET];
370 : 0 : dpi_conf->c_desc.tail++;
371 : :
372 : 0 : cmd[0] = dpi_conf->cmd.u | (1U << 6) | 1U;
373 : 0 : cmd[1] = (uint64_t)comp_ptr;
374 : 0 : cmd[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
375 : 0 : cmd[4] = length;
376 : 0 : cmd[5] = src;
377 : 0 : cmd[6] = length;
378 [ # # ]: 0 : cmd[7] = dst;
379 : :
380 : : rc = __dpi_queue_write_single(dpivf, cmd);
381 [ # # ]: 0 : if (unlikely(rc)) {
382 : 0 : dpi_conf->c_desc.tail--;
383 : 0 : return rc;
384 : : }
385 : :
386 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
387 : : rte_wmb();
388 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
389 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
390 : 0 : dpivf->total_pnum_words = 0;
391 : : } else {
392 : 0 : dpivf->total_pnum_words += CNXK_DPI_DW_PER_SINGLE_CMD;
393 : : }
394 : :
395 : 0 : dpi_conf->stats.submitted += 1;
396 : :
397 : 0 : return dpi_conf->desc_idx++;
398 : : }
399 : :
400 : : int
401 : 0 : cn10k_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
402 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst,
403 : : uint64_t flags)
404 : : {
405 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
406 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
407 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
408 : : uint8_t *comp_ptr;
409 : : uint64_t hdr[4];
410 : : int rc;
411 : :
412 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == (dpi_conf->c_desc.head & max_cnt)))
413 : : return -ENOSPC;
414 : :
415 : 0 : comp_ptr = &dpi_conf->c_desc
416 : 0 : .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * CNXK_DPI_COMPL_OFFSET];
417 : 0 : dpi_conf->c_desc.tail++;
418 : :
419 : 0 : hdr[0] = dpi_conf->cmd.u | (nb_dst << 6) | nb_src;
420 : 0 : hdr[1] = (uint64_t)comp_ptr;
421 : 0 : hdr[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
422 : :
423 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
424 [ # # ]: 0 : if (unlikely(rc)) {
425 : 0 : dpi_conf->c_desc.tail--;
426 : 0 : return rc;
427 : : }
428 : :
429 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
430 : : rte_wmb();
431 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
432 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
433 : 0 : dpivf->total_pnum_words = 0;
434 : : } else {
435 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
436 : : }
437 : :
438 : 0 : dpi_conf->stats.submitted += 1;
439 : :
440 : 0 : return dpi_conf->desc_idx++;
441 : : }
442 : :
443 : : static inline uint64_t
444 : : cnxk_dma_adapter_format_event(uint64_t event)
445 : : {
446 : : uint64_t w0;
447 : 0 : w0 = (event & 0xFFC000000000) >> 6 |
448 : 0 : (event & 0xFFFFFFF) | RTE_EVENT_TYPE_DMADEV << 28;
449 : :
450 : : return w0;
451 : : }
452 : :
453 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_dma_adapter_enqueue)
454 : : uint16_t
455 : 0 : cn10k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
456 : : {
457 : : const struct rte_dma_sge *src, *dst;
458 : : struct rte_dma_op *op;
459 : : struct cnxk_dpi_conf *dpi_conf;
460 : : struct cnxk_dpi_vf_s *dpivf;
461 : : struct cn10k_sso_hws *work;
462 : : uint16_t nb_src, nb_dst;
463 : : rte_mcslock_t mcs_lock_me;
464 : : uint64_t hdr[4];
465 : : uint16_t count;
466 : : int rc;
467 : :
468 : : work = (struct cn10k_sso_hws *)ws;
469 : :
470 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
471 : 0 : op = ev[count].event_ptr;
472 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
473 : 0 : dpi_conf = &dpivf->conf[op->vchan];
474 : :
475 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
476 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
477 : :
478 : 0 : hdr[0] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 54);
479 : 0 : hdr[0] |= (nb_dst << 6) | nb_src;
480 : 0 : hdr[1] = (uint64_t)op;
481 : 0 : hdr[2] = cnxk_dma_adapter_format_event(ev[count].event);
482 : :
483 : 0 : src = &op->src_dst_seg[0];
484 : 0 : dst = &op->src_dst_seg[op->nb_src];
485 : :
486 [ # # ]: 0 : if (CNXK_TAG_IS_HEAD(work->gw_rdata) ||
487 [ # # ]: 0 : ((CNXK_TT_FROM_TAG(work->gw_rdata) == SSO_TT_ORDERED) &&
488 [ # # ]: 0 : (ev[count].sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED))
489 : 0 : roc_sso_hws_head_wait(work->base);
490 : :
491 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
492 : : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
493 [ # # ]: 0 : if (unlikely(rc)) {
494 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
495 : 0 : return rc;
496 : : }
497 : :
498 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
499 : : rte_wmb();
500 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
501 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
502 : 0 : dpivf->total_pnum_words = 0;
503 : : } else {
504 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
505 : : }
506 : 0 : dpi_conf->stats.submitted += 1;
507 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
508 : : }
509 : :
510 : : return count;
511 : : }
512 : :
513 : : RTE_EXPORT_INTERNAL_SYMBOL(cn9k_dma_adapter_dual_enqueue)
514 : : uint16_t
515 : 0 : cn9k_dma_adapter_dual_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
516 : : {
517 : : const struct rte_dma_sge *fptr, *lptr;
518 : : struct rte_dma_op *op;
519 : : struct cn9k_sso_hws_dual *work;
520 : : struct cnxk_dpi_conf *dpi_conf;
521 : : struct cnxk_dpi_vf_s *dpivf;
522 : : struct rte_event *rsp_info;
523 : : uint16_t nb_src, nb_dst;
524 : : rte_mcslock_t mcs_lock_me;
525 : : uint64_t hdr[4];
526 : : uint16_t count;
527 : : int rc;
528 : :
529 : : work = (struct cn9k_sso_hws_dual *)ws;
530 : :
531 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
532 : 0 : op = ev[count].event_ptr;
533 : : rsp_info = (struct rte_event *)((uint8_t *)op +
534 : : sizeof(struct rte_dma_op));
535 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
536 : 0 : dpi_conf = &dpivf->conf[op->vchan];
537 : :
538 : 0 : hdr[1] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 36);
539 : 0 : hdr[2] = (uint64_t)op;
540 : :
541 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
542 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
543 : : /*
544 : : * For inbound case, src pointers are last pointers.
545 : : * For all other cases, src pointers are first pointers.
546 : : */
547 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
548 : 0 : fptr = &op->src_dst_seg[nb_src];
549 : 0 : lptr = &op->src_dst_seg[0];
550 : : RTE_SWAP(nb_src, nb_dst);
551 : : } else {
552 : 0 : fptr = &op->src_dst_seg[0];
553 : 0 : lptr = &op->src_dst_seg[nb_src];
554 : : }
555 : :
556 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
557 : 0 : hdr[0] |= cnxk_dma_adapter_format_event(rsp_info->event);
558 : :
559 [ # # ]: 0 : if ((rsp_info->sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED)
560 : 0 : roc_sso_hws_head_wait(work->base[!work->vws]);
561 : :
562 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
563 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
564 [ # # ]: 0 : if (unlikely(rc)) {
565 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
566 : 0 : return rc;
567 : : }
568 : :
569 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
570 : : rte_wmb();
571 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
572 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
573 : 0 : dpivf->total_pnum_words = 0;
574 : : } else {
575 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
576 : : }
577 : 0 : dpi_conf->stats.submitted += 1;
578 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
579 : : }
580 : :
581 : : return count;
582 : : }
583 : :
584 : : RTE_EXPORT_INTERNAL_SYMBOL(cn9k_dma_adapter_enqueue)
585 : : uint16_t
586 : 0 : cn9k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
587 : : {
588 : : const struct rte_dma_sge *fptr, *lptr;
589 : : struct rte_dma_op *op;
590 : : struct cnxk_dpi_conf *dpi_conf;
591 : : struct cnxk_dpi_vf_s *dpivf;
592 : : struct cn9k_sso_hws *work;
593 : : uint16_t nb_src, nb_dst;
594 : : rte_mcslock_t mcs_lock_me;
595 : : uint64_t hdr[4];
596 : : uint16_t count;
597 : : int rc;
598 : :
599 : : work = (struct cn9k_sso_hws *)ws;
600 : :
601 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
602 : 0 : op = ev[count].event_ptr;
603 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
604 : 0 : dpi_conf = &dpivf->conf[op->vchan];
605 : :
606 : 0 : hdr[1] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 36);
607 : 0 : hdr[2] = (uint64_t)op;
608 : :
609 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
610 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
611 : : /*
612 : : * For inbound case, src pointers are last pointers.
613 : : * For all other cases, src pointers are first pointers.
614 : : */
615 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
616 : 0 : fptr = &op->src_dst_seg[nb_src];
617 : 0 : lptr = &op->src_dst_seg[0];
618 : : RTE_SWAP(nb_src, nb_dst);
619 : : } else {
620 : 0 : fptr = &op->src_dst_seg[0];
621 : 0 : lptr = &op->src_dst_seg[nb_src];
622 : : }
623 : :
624 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
625 : 0 : hdr[0] |= cnxk_dma_adapter_format_event(ev[count].event);
626 : :
627 [ # # ]: 0 : if ((ev[count].sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED)
628 : 0 : roc_sso_hws_head_wait(work->base);
629 : :
630 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
631 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
632 [ # # ]: 0 : if (unlikely(rc)) {
633 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
634 : 0 : return rc;
635 : : }
636 : :
637 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
638 : : rte_wmb();
639 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
640 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
641 : 0 : dpivf->total_pnum_words = 0;
642 : : } else {
643 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
644 : : }
645 : 0 : dpi_conf->stats.submitted += 1;
646 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
647 : : }
648 : :
649 : : return count;
650 : : }
651 : :
652 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_dma_adapter_dequeue)
653 : : uintptr_t
654 : 0 : cnxk_dma_adapter_dequeue(uintptr_t get_work1)
655 : : {
656 : : struct rte_dma_op *op;
657 : : struct cnxk_dpi_conf *dpi_conf;
658 : : struct cnxk_dpi_vf_s *dpivf;
659 : :
660 : 0 : op = (struct rte_dma_op *)get_work1;
661 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
662 : 0 : dpi_conf = &dpivf->conf[op->vchan];
663 : :
664 [ # # ]: 0 : if (rte_atomic_load_explicit((RTE_ATOMIC(uint64_t) *)&op->impl_opaque[0],
665 : : rte_memory_order_relaxed) != 0)
666 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.errors, 1,
667 : : rte_memory_order_relaxed);
668 : :
669 : : /* Take into account errors also. This is similar to
670 : : * cnxk_dmadev_completed_status().
671 : : */
672 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.completed, 1,
673 : : rte_memory_order_relaxed);
674 : :
675 : 0 : return (uintptr_t)op;
676 : : }
677 : :
678 : : uint16_t
679 : 0 : cnxk_dma_ops_enqueue(void *dev_private, uint16_t vchan, struct rte_dma_op **ops, uint16_t nb_ops)
680 : : {
681 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
682 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
683 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
684 : : const struct rte_dma_sge *fptr, *lptr;
685 : : uint16_t src, dst, nwords = 0;
686 : : struct rte_dma_op *op;
687 : : uint16_t space, i;
688 : : uint8_t *comp_ptr;
689 : : uint64_t hdr[4];
690 : : int rc;
691 : :
692 : 0 : space = ((dpi_conf->c_desc.max_cnt + dpi_conf->c_desc.head - dpi_conf->c_desc.tail) &
693 : : max_cnt);
694 : 0 : space = RTE_MIN(space, nb_ops);
695 : :
696 [ # # ]: 0 : for (i = 0; i < space; i++) {
697 : 0 : op = ops[i];
698 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[(dpi_conf->c_desc.tail & max_cnt) *
699 : : CNXK_DPI_COMPL_OFFSET];
700 : 0 : dpi_conf->c_desc.ops[dpi_conf->c_desc.tail & max_cnt] = op;
701 : 0 : dpi_conf->c_desc.tail++;
702 : :
703 : 0 : hdr[1] = dpi_conf->cmd.u | ((op->flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
704 : 0 : hdr[2] = (uint64_t)comp_ptr;
705 : :
706 : 0 : src = op->nb_src;
707 : 0 : dst = op->nb_dst;
708 : : /*
709 : : * For inbound case, src pointers are last pointers.
710 : : * For all other cases, src pointers are first pointers.
711 : : */
712 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
713 : 0 : fptr = &op->src_dst_seg[src];
714 : 0 : lptr = &op->src_dst_seg[0];
715 : : RTE_SWAP(src, dst);
716 : : } else {
717 : 0 : fptr = &op->src_dst_seg[0];
718 : 0 : lptr = &op->src_dst_seg[src];
719 : : }
720 : 0 : hdr[0] = ((uint64_t)dst << 54) | (uint64_t)src << 48;
721 : :
722 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, src, dst);
723 : : if (rc) {
724 : 0 : dpi_conf->c_desc.tail--;
725 : 0 : goto done;
726 : : }
727 : 0 : nwords += CNXK_DPI_CMD_LEN(src, dst);
728 : : }
729 : :
730 : 0 : done:
731 [ # # ]: 0 : if (nwords) {
732 : : rte_wmb();
733 : 0 : plt_write64(nwords, dpivf->rdpi.rbase + DPI_VDMA_DBELL);
734 : 0 : dpi_conf->stats.submitted += i;
735 : : }
736 : :
737 : 0 : return i;
738 : : }
739 : :
740 : : uint16_t
741 : 0 : cn10k_dma_ops_enqueue(void *dev_private, uint16_t vchan, struct rte_dma_op **ops, uint16_t nb_ops)
742 : : {
743 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
744 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
745 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
746 : : uint16_t space, i, nwords = 0;
747 : : struct rte_dma_op *op;
748 : : uint16_t src, dst;
749 : : uint8_t *comp_ptr;
750 : : uint64_t hdr[4];
751 : : int rc;
752 : :
753 : 0 : space = (max_cnt + dpi_conf->c_desc.head - dpi_conf->c_desc.tail) & max_cnt;
754 : 0 : space = RTE_MIN(space, nb_ops);
755 : :
756 [ # # ]: 0 : for (i = 0; i < space; i++) {
757 : 0 : op = ops[i];
758 : 0 : src = op->nb_src;
759 : 0 : dst = op->nb_dst;
760 : :
761 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[(dpi_conf->c_desc.tail & max_cnt) *
762 : : CNXK_DPI_COMPL_OFFSET];
763 : 0 : dpi_conf->c_desc.ops[dpi_conf->c_desc.tail & max_cnt] = op;
764 : 0 : dpi_conf->c_desc.tail++;
765 : :
766 : 0 : hdr[0] = dpi_conf->cmd.u | (dst << 6) | src;
767 : 0 : hdr[1] = (uint64_t)comp_ptr;
768 : 0 : hdr[2] = (1UL << 47) | ((op->flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
769 : :
770 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, &op->src_dst_seg[0], &op->src_dst_seg[src],
771 : : src, dst);
772 : : if (rc) {
773 : 0 : dpi_conf->c_desc.tail--;
774 : 0 : goto done;
775 : : }
776 : 0 : nwords += CNXK_DPI_CMD_LEN(src, dst);
777 : : }
778 : :
779 : 0 : done:
780 [ # # ]: 0 : if (nwords) {
781 : : rte_wmb();
782 : 0 : plt_write64(nwords, dpivf->rdpi.rbase + DPI_VDMA_DBELL);
783 : 0 : dpi_conf->stats.submitted += i;
784 : : }
785 : :
786 : 0 : return i;
787 : : }
788 : :
789 : : uint16_t
790 : 0 : cnxk_dma_ops_dequeue(void *dev_private, uint16_t vchan, struct rte_dma_op **ops, uint16_t nb_ops)
791 : : {
792 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
793 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
794 : : struct cnxk_dpi_cdesc_data_s *c_desc = &dpi_conf->c_desc;
795 : 0 : const uint16_t max_cnt = c_desc->max_cnt;
796 : : struct rte_dma_op *op;
797 : : uint16_t space, cnt;
798 : : uint8_t status;
799 : :
800 : 0 : space = (c_desc->tail - c_desc->head) & max_cnt;
801 : 0 : space = RTE_MIN(nb_ops, space);
802 : :
803 [ # # ]: 0 : for (cnt = 0; cnt < space; cnt++) {
804 : 0 : status = c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET];
805 : 0 : op = c_desc->ops[c_desc->head & max_cnt];
806 [ # # ]: 0 : if (status) {
807 [ # # ]: 0 : if (status == CNXK_DPI_REQ_CDATA)
808 : : break;
809 : 0 : dpi_conf->stats.errors++;
810 : : }
811 : 0 : op->status = status;
812 : 0 : ops[cnt] = op;
813 : 0 : c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
814 : : CNXK_DPI_REQ_CDATA;
815 : 0 : c_desc->head++;
816 : : }
817 : :
818 : 0 : dpi_conf->stats.completed += cnt;
819 : :
820 : 0 : return cnt;
821 : : }
|