Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Marvell International Ltd.
3 : : */
4 : :
5 : : #include <rte_vect.h>
6 : :
7 : : #include "cnxk_dmadev.h"
8 : : #include <rte_event_dma_adapter.h>
9 : :
10 : : #include <cn10k_eventdev.h>
11 : : #include <cnxk_eventdev.h>
12 : :
13 : : static __plt_always_inline void
14 : : __dpi_cpy_scalar(uint64_t *src, uint64_t *dst, uint8_t n)
15 : : {
16 : : uint8_t i;
17 : :
18 [ # # # # : 0 : for (i = 0; i < n; i++)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
19 : 0 : dst[i] = src[i];
20 : : }
21 : :
22 : : #if defined(RTE_ARCH_ARM64)
23 : : static __plt_always_inline void
24 : : __dpi_cpy_vector(uint64_t *src, uint64_t *dst, uint8_t n)
25 : : {
26 : : uint64x2_t vec;
27 : : uint8_t i;
28 : :
29 : : for (i = 0; i < n; i += 2) {
30 : : vec = vld1q_u64((const uint64_t *)&src[i]);
31 : : vst1q_u64(&dst[i], vec);
32 : : }
33 : : }
34 : :
35 : : static __plt_always_inline void
36 : : __dpi_cpy_vector_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
37 : : {
38 : : uint64x2_t mask = {0xFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL};
39 : : uint64x2_t vec;
40 : : uint8_t i;
41 : :
42 : : for (i = 0; i < n; i++) {
43 : : vec = vld1q_u64((const uint64_t *)&src[i]);
44 : : vec = vextq_u64(vec, vec, 1);
45 : : vec = vandq_u64(vec, mask);
46 : : vst1q_u64(dst, vec);
47 : : dst += 2;
48 : : }
49 : : }
50 : :
51 : : static __plt_always_inline uint8_t
52 : : __dpi_cpy_vector_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
53 : : {
54 : : uint64x2_t mask = {0xFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL};
55 : : uint64x2_t vec;
56 : : uint8_t i;
57 : :
58 : : for (i = 0; i < n && lmt; i++) {
59 : : vec = vld1q_u64((const uint64_t *)&src[i]);
60 : : vec = vextq_u64(vec, vec, 1);
61 : : vec = vandq_u64(vec, mask);
62 : : vst1q_u64(dst, vec);
63 : : dst += 2;
64 : : lmt -= 2;
65 : : }
66 : :
67 : : return i;
68 : : }
69 : : #else
70 : : static __plt_always_inline void
71 : : __dpi_cpy_scalar_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
72 : : {
73 : : uint8_t i;
74 : :
75 [ # # # # : 0 : for (i = 0; i < n; i++) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
76 : 0 : *dst++ = src[i].length;
77 : 0 : *dst++ = src[i].addr;
78 : : }
79 : : }
80 : :
81 : : static __plt_always_inline uint8_t
82 : : __dpi_cpy_scalar_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
83 : : {
84 : : uint8_t i;
85 : :
86 [ # # # # : 0 : for (i = 0; i < n && lmt; i++) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
87 : 0 : *dst++ = src[i].length;
88 : 0 : *dst++ = src[i].addr;
89 : 0 : lmt -= 2;
90 : : }
91 : :
92 : : return i;
93 : : }
94 : : #endif
95 : :
96 : : static __plt_always_inline void
97 : : __dpi_cpy(uint64_t *src, uint64_t *dst, uint8_t n)
98 : : {
99 : : #if defined(RTE_ARCH_ARM64)
100 : : __dpi_cpy_vector(src, dst, n);
101 : : #else
102 : : __dpi_cpy_scalar(src, dst, n);
103 : : #endif
104 : : }
105 : :
106 : : static __plt_always_inline void
107 : : __dpi_cpy_sg(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n)
108 : : {
109 : : #if defined(RTE_ARCH_ARM64)
110 : : __dpi_cpy_vector_sg(src, dst, n);
111 : : #else
112 : : __dpi_cpy_scalar_sg(src, dst, n);
113 : : #endif
114 : : }
115 : :
116 : : static __plt_always_inline uint8_t
117 : : __dpi_cpy_sg_lmt(const struct rte_dma_sge *src, uint64_t *dst, uint16_t n, uint16_t lmt)
118 : : {
119 : : #if defined(RTE_ARCH_ARM64)
120 : : return __dpi_cpy_vector_sg_lmt(src, dst, n, lmt);
121 : : #else
122 : : return __dpi_cpy_scalar_sg_lmt(src, dst, n, lmt);
123 : : #endif
124 : : }
125 : :
126 : : static __plt_always_inline int
127 : : __dpi_queue_write_single(struct cnxk_dpi_vf_s *dpi, uint64_t *cmd)
128 : : {
129 : 0 : uint64_t *ptr = dpi->chunk_base;
130 : :
131 : : /* Check if command fits in the current chunk. */
132 [ # # ]: 0 : if (dpi->chunk_head + CNXK_DPI_DW_PER_SINGLE_CMD < dpi->chunk_size_m1) {
133 : 0 : ptr += dpi->chunk_head;
134 : :
135 : : __dpi_cpy_scalar(cmd, ptr, CNXK_DPI_DW_PER_SINGLE_CMD);
136 : 0 : dpi->chunk_head += CNXK_DPI_DW_PER_SINGLE_CMD;
137 : : } else {
138 : 0 : uint64_t *new_buff = NULL;
139 : : int count;
140 : :
141 [ # # # # : 0 : if (rte_mempool_get(dpi->chunk_pool, (void **)&new_buff) < 0) {
# # # # ]
142 : 0 : plt_dpi_dbg("Failed to alloc next buffer from NPA");
143 : 0 : return -ENOSPC;
144 : : }
145 : :
146 : : /*
147 : : * Figure out how many cmd words will fit in the current chunk
148 : : * and copy them.
149 : : */
150 : 0 : count = dpi->chunk_size_m1 - dpi->chunk_head;
151 : 0 : ptr += dpi->chunk_head;
152 : :
153 : 0 : __dpi_cpy_scalar(cmd, ptr, count);
154 : :
155 : 0 : ptr += count;
156 : 0 : *ptr = (uint64_t)new_buff;
157 : : ptr = new_buff;
158 : :
159 : : /* Copy the remaining cmd words to new chunk. */
160 : 0 : __dpi_cpy_scalar(cmd + count, ptr, CNXK_DPI_DW_PER_SINGLE_CMD - count);
161 : :
162 : 0 : dpi->chunk_base = new_buff;
163 : 0 : dpi->chunk_head = CNXK_DPI_DW_PER_SINGLE_CMD - count;
164 : : }
165 : :
166 : : return 0;
167 : : }
168 : :
169 : : static __plt_always_inline int
170 : : __dpi_queue_write_sg(struct cnxk_dpi_vf_s *dpi, uint64_t *hdr, const struct rte_dma_sge *src,
171 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst)
172 : : {
173 : 0 : uint8_t cmd_len = CNXK_DPI_CMD_LEN(nb_src, nb_dst);
174 : 0 : uint64_t *ptr = dpi->chunk_base;
175 : :
176 : : /* Check if command fits in the current chunk. */
177 [ # # ]: 0 : if (dpi->chunk_head + cmd_len < dpi->chunk_size_m1) {
178 : 0 : ptr += dpi->chunk_head;
179 : :
180 : : __dpi_cpy(hdr, ptr, CNXK_DPI_HDR_LEN);
181 : 0 : ptr += CNXK_DPI_HDR_LEN;
182 : : __dpi_cpy_sg(src, ptr, nb_src);
183 : 0 : ptr += (nb_src << 1);
184 : : __dpi_cpy_sg(dst, ptr, nb_dst);
185 : :
186 : 0 : dpi->chunk_head += cmd_len;
187 : : } else {
188 : 0 : uint64_t *new_buff = NULL, *buf;
189 : : uint16_t count;
190 : :
191 [ # # # # : 0 : if (rte_mempool_get(dpi->chunk_pool, (void **)&new_buff) < 0) {
# # # # #
# # # # #
# # # # #
# ]
192 : 0 : plt_dpi_dbg("Failed to alloc next buffer from NPA");
193 : 0 : return -ENOSPC;
194 : : }
195 : :
196 : : /*
197 : : * Figure out how many cmd words will fit in the current chunk
198 : : * and copy them, copy the rest to the new buffer.
199 : : */
200 : 0 : count = dpi->chunk_size_m1 - dpi->chunk_head;
201 : 0 : ptr += dpi->chunk_head;
202 : 0 : buf = new_buff;
203 [ # # # # : 0 : if (count <= 4) {
# # # # #
# ]
204 : 0 : __dpi_cpy(hdr, ptr, count);
205 : 0 : ptr += count;
206 : : __dpi_cpy(&hdr[count], buf, 4);
207 : 0 : buf += (4 - count);
208 : : } else {
209 : : uint8_t i;
210 : :
211 : : __dpi_cpy(hdr, ptr, 4);
212 : 0 : ptr += 4;
213 : 0 : count -= 4;
214 : :
215 : : i = __dpi_cpy_sg_lmt(src, ptr, nb_src, count);
216 : 0 : src += i;
217 : 0 : nb_src -= i;
218 : 0 : count -= (i << 1);
219 : 0 : ptr += (i << 1);
220 : :
221 : : i = __dpi_cpy_sg_lmt(dst, ptr, nb_dst, count);
222 : 0 : dst += i;
223 : 0 : nb_dst -= i;
224 : 0 : ptr += (i << 1);
225 : : }
226 : 0 : *ptr = (uint64_t)new_buff;
227 : :
228 : 0 : __dpi_cpy_sg(src, buf, nb_src);
229 : 0 : buf += (nb_src << 1);
230 : :
231 : 0 : __dpi_cpy_sg(dst, buf, nb_dst);
232 : 0 : buf += (nb_dst << 1);
233 : :
234 : 0 : dpi->chunk_base = new_buff;
235 : 0 : dpi->chunk_head = buf - new_buff;
236 : : }
237 : :
238 : : return 0;
239 : : }
240 : :
241 : : int
242 : 0 : cnxk_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t dst, uint32_t length,
243 : : uint64_t flags)
244 : : {
245 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
246 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
247 : : uint64_t cmd[CNXK_DPI_DW_PER_SINGLE_CMD];
248 : : uint8_t *comp_ptr;
249 : : int rc;
250 : :
251 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
252 : : dpi_conf->c_desc.head))
253 : : return -ENOSPC;
254 : :
255 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
256 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
257 : :
258 : 0 : cmd[0] = (1UL << 54) | (1UL << 48);
259 : 0 : cmd[1] = dpi_conf->cmd.u | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
260 : 0 : cmd[2] = (uint64_t)comp_ptr;
261 : 0 : cmd[4] = length;
262 : 0 : cmd[6] = length;
263 : :
264 : : /*
265 : : * For inbound case, src pointers are last pointers.
266 : : * For all other cases, src pointers are first pointers.
267 : : */
268 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
269 : 0 : cmd[5] = dst;
270 : 0 : cmd[7] = src;
271 : : } else {
272 : 0 : cmd[5] = src;
273 : 0 : cmd[7] = dst;
274 : : }
275 : :
276 : : rc = __dpi_queue_write_single(dpivf, cmd);
277 [ # # ]: 0 : if (unlikely(rc)) {
278 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
279 : 0 : return rc;
280 : : }
281 : :
282 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
283 : : rte_wmb();
284 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
285 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
286 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
287 : 0 : dpi_conf->pnum_words = 0;
288 : 0 : dpi_conf->pending = 0;
289 : : } else {
290 : 0 : dpi_conf->pnum_words += CNXK_DPI_DW_PER_SINGLE_CMD;
291 : 0 : dpi_conf->pending++;
292 : : }
293 : :
294 : 0 : return dpi_conf->desc_idx++;
295 : : }
296 : :
297 : : int
298 : 0 : cnxk_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
299 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst, uint64_t flags)
300 : : {
301 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
302 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
303 : : const struct rte_dma_sge *fptr, *lptr;
304 : : uint8_t *comp_ptr;
305 : : uint64_t hdr[4];
306 : : int rc;
307 : :
308 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
309 : : dpi_conf->c_desc.head))
310 : : return -ENOSPC;
311 : :
312 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
313 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
314 : :
315 : 0 : hdr[1] = dpi_conf->cmd.u | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
316 : 0 : hdr[2] = (uint64_t)comp_ptr;
317 : :
318 : : /*
319 : : * For inbound case, src pointers are last pointers.
320 : : * For all other cases, src pointers are first pointers.
321 : : */
322 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
323 : : fptr = dst;
324 : : lptr = src;
325 : : RTE_SWAP(nb_src, nb_dst);
326 : : } else {
327 : : fptr = src;
328 : : lptr = dst;
329 : : }
330 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
331 : :
332 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
333 [ # # ]: 0 : if (unlikely(rc)) {
334 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
335 : 0 : return rc;
336 : : }
337 : :
338 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
339 : : rte_wmb();
340 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
341 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
342 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
343 : 0 : dpi_conf->pnum_words = 0;
344 : 0 : dpi_conf->pending = 0;
345 : : } else {
346 : 0 : dpi_conf->pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
347 : 0 : dpi_conf->pending++;
348 : : }
349 : :
350 : 0 : return dpi_conf->desc_idx++;
351 : : }
352 : :
353 : : int
354 : 0 : cn10k_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t dst,
355 : : uint32_t length, uint64_t flags)
356 : : {
357 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
358 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
359 : : uint64_t cmd[CNXK_DPI_DW_PER_SINGLE_CMD];
360 : : uint8_t *comp_ptr;
361 : : int rc;
362 : :
363 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
364 : : dpi_conf->c_desc.head))
365 : : return -ENOSPC;
366 : :
367 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
368 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
369 : :
370 : 0 : cmd[0] = dpi_conf->cmd.u | (1U << 6) | 1U;
371 : 0 : cmd[1] = (uint64_t)comp_ptr;
372 : 0 : cmd[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
373 : 0 : cmd[4] = length;
374 : 0 : cmd[5] = src;
375 : 0 : cmd[6] = length;
376 [ # # ]: 0 : cmd[7] = dst;
377 : :
378 : : rc = __dpi_queue_write_single(dpivf, cmd);
379 [ # # ]: 0 : if (unlikely(rc)) {
380 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
381 : 0 : return rc;
382 : : }
383 : :
384 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
385 : : rte_wmb();
386 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
387 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
388 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
389 : 0 : dpi_conf->pnum_words = 0;
390 : 0 : dpi_conf->pending = 0;
391 : : } else {
392 : 0 : dpi_conf->pnum_words += 8;
393 : 0 : dpi_conf->pending++;
394 : : }
395 : :
396 : 0 : return dpi_conf->desc_idx++;
397 : : }
398 : :
399 : : int
400 : 0 : cn10k_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
401 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst,
402 : : uint64_t flags)
403 : : {
404 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
405 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
406 : : uint8_t *comp_ptr;
407 : : uint64_t hdr[4];
408 : : int rc;
409 : :
410 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
411 : : dpi_conf->c_desc.head))
412 : : return -ENOSPC;
413 : :
414 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
415 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
416 : :
417 : 0 : hdr[0] = dpi_conf->cmd.u | (nb_dst << 6) | nb_src;
418 : 0 : hdr[1] = (uint64_t)comp_ptr;
419 : 0 : hdr[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
420 : :
421 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
422 [ # # ]: 0 : if (unlikely(rc)) {
423 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
424 : 0 : return rc;
425 : : }
426 : :
427 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
428 : : rte_wmb();
429 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
430 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
431 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
432 : 0 : dpi_conf->pnum_words = 0;
433 : 0 : dpi_conf->pending = 0;
434 : : } else {
435 : 0 : dpi_conf->pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
436 : 0 : dpi_conf->pending++;
437 : : }
438 : :
439 : 0 : return dpi_conf->desc_idx++;
440 : : }
441 : :
442 : : static inline uint64_t
443 : : cnxk_dma_adapter_format_event(uint64_t event)
444 : : {
445 : : uint64_t w0;
446 : 0 : w0 = (event & 0xFFC000000000) >> 6 |
447 : 0 : (event & 0xFFFFFFF) | RTE_EVENT_TYPE_DMADEV << 28;
448 : :
449 : : return w0;
450 : : }
451 : :
452 : : uint16_t
453 : 0 : cn10k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
454 : : {
455 : : const struct rte_dma_sge *src, *dst;
456 : : struct rte_event_dma_adapter_op *op;
457 : : struct cnxk_dpi_conf *dpi_conf;
458 : : struct cnxk_dpi_vf_s *dpivf;
459 : : struct cn10k_sso_hws *work;
460 : : uint16_t nb_src, nb_dst;
461 : : rte_mcslock_t mcs_lock_me;
462 : : uint64_t hdr[4];
463 : : uint16_t count;
464 : : int rc;
465 : :
466 : : work = (struct cn10k_sso_hws *)ws;
467 : :
468 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
469 : 0 : op = ev[count].event_ptr;
470 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
471 : 0 : dpi_conf = &dpivf->conf[op->vchan];
472 : :
473 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
474 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
475 : :
476 : 0 : hdr[0] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 54);
477 : 0 : hdr[0] |= (nb_dst << 6) | nb_src;
478 : 0 : hdr[1] = (uint64_t)op;
479 : 0 : hdr[2] = cnxk_dma_adapter_format_event(ev[count].event);
480 : :
481 : 0 : src = &op->src_dst_seg[0];
482 : 0 : dst = &op->src_dst_seg[op->nb_src];
483 : :
484 [ # # ]: 0 : if (CNXK_TAG_IS_HEAD(work->gw_rdata) ||
485 [ # # ]: 0 : ((CNXK_TT_FROM_TAG(work->gw_rdata) == SSO_TT_ORDERED) &&
486 [ # # ]: 0 : (ev[count].sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED))
487 : 0 : roc_sso_hws_head_wait(work->base);
488 : :
489 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
490 : : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
491 [ # # ]: 0 : if (unlikely(rc)) {
492 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
493 : 0 : return rc;
494 : : }
495 : :
496 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
497 : : rte_wmb();
498 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
499 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
500 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
501 : 0 : dpi_conf->pnum_words = 0;
502 : 0 : dpi_conf->pending = 0;
503 : : } else {
504 : 0 : dpi_conf->pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
505 : 0 : dpi_conf->pending++;
506 : : }
507 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
508 : : }
509 : :
510 : : return count;
511 : : }
512 : :
513 : : uint16_t
514 : 0 : cn9k_dma_adapter_dual_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
515 : : {
516 : : const struct rte_dma_sge *fptr, *lptr;
517 : : struct rte_event_dma_adapter_op *op;
518 : : struct cn9k_sso_hws_dual *work;
519 : : struct cnxk_dpi_conf *dpi_conf;
520 : : struct cnxk_dpi_vf_s *dpivf;
521 : : struct rte_event *rsp_info;
522 : : uint16_t nb_src, nb_dst;
523 : : rte_mcslock_t mcs_lock_me;
524 : : uint64_t hdr[4];
525 : : uint16_t count;
526 : : int rc;
527 : :
528 : : work = (struct cn9k_sso_hws_dual *)ws;
529 : :
530 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
531 : 0 : op = ev[count].event_ptr;
532 : : rsp_info = (struct rte_event *)((uint8_t *)op +
533 : : sizeof(struct rte_event_dma_adapter_op));
534 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
535 : 0 : dpi_conf = &dpivf->conf[op->vchan];
536 : :
537 : 0 : hdr[1] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 36);
538 : 0 : hdr[2] = (uint64_t)op;
539 : :
540 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
541 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
542 : : /*
543 : : * For inbound case, src pointers are last pointers.
544 : : * For all other cases, src pointers are first pointers.
545 : : */
546 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
547 : 0 : fptr = &op->src_dst_seg[nb_src];
548 : 0 : lptr = &op->src_dst_seg[0];
549 : : RTE_SWAP(nb_src, nb_dst);
550 : : } else {
551 : 0 : fptr = &op->src_dst_seg[0];
552 : 0 : lptr = &op->src_dst_seg[nb_src];
553 : : }
554 : :
555 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
556 : 0 : hdr[0] |= cnxk_dma_adapter_format_event(rsp_info->event);
557 : :
558 [ # # ]: 0 : if ((rsp_info->sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED)
559 : 0 : roc_sso_hws_head_wait(work->base[!work->vws]);
560 : :
561 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
562 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
563 [ # # ]: 0 : if (unlikely(rc)) {
564 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
565 : 0 : return rc;
566 : : }
567 : :
568 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
569 : : rte_wmb();
570 : 0 : plt_write64(dpi_conf->pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
571 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
572 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
573 : 0 : dpi_conf->pnum_words = 0;
574 : 0 : dpi_conf->pending = 0;
575 : : } else {
576 : 0 : dpi_conf->pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
577 : 0 : dpi_conf->pending++;
578 : : }
579 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
580 : : }
581 : :
582 : : return count;
583 : : }
584 : :
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_event_dma_adapter_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(dpi_conf->pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
640 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
641 : 0 : dpi_conf->stats.submitted += dpi_conf->pending + 1;
642 : 0 : dpi_conf->pnum_words = 0;
643 : 0 : dpi_conf->pending = 0;
644 : : } else {
645 : 0 : dpi_conf->pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
646 : 0 : dpi_conf->pending++;
647 : : }
648 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
649 : : }
650 : :
651 : : return count;
652 : : }
653 : :
654 : : uintptr_t
655 : 0 : cnxk_dma_adapter_dequeue(uintptr_t get_work1)
656 : : {
657 : : struct rte_event_dma_adapter_op *op;
658 : : struct cnxk_dpi_conf *dpi_conf;
659 : : struct cnxk_dpi_vf_s *dpivf;
660 : :
661 : 0 : op = (struct rte_event_dma_adapter_op *)get_work1;
662 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
663 : 0 : dpi_conf = &dpivf->conf[op->vchan];
664 : :
665 [ # # ]: 0 : if (rte_atomic_load_explicit((RTE_ATOMIC(uint64_t) *)&op->impl_opaque[0],
666 : : rte_memory_order_relaxed) != 0)
667 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.errors, 1,
668 : : rte_memory_order_relaxed);
669 : :
670 : : /* Take into account errors also. This is similar to
671 : : * cnxk_dmadev_completed_status().
672 : : */
673 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.completed, 1,
674 : : rte_memory_order_relaxed);
675 : :
676 : 0 : return (uintptr_t)op;
677 : : }
|