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(dpivf->total_pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
285 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
286 : 0 : dpivf->total_pnum_words = 0;
287 : : } else {
288 : 0 : dpivf->total_pnum_words += CNXK_DPI_DW_PER_SINGLE_CMD;
289 : : }
290 : :
291 : 0 : dpi_conf->stats.submitted += 1;
292 : :
293 : 0 : return dpi_conf->desc_idx++;
294 : : }
295 : :
296 : : int
297 : 0 : cnxk_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
298 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst, uint64_t flags)
299 : : {
300 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
301 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
302 : : const struct rte_dma_sge *fptr, *lptr;
303 : : uint8_t *comp_ptr;
304 : : uint64_t hdr[4];
305 : : int rc;
306 : :
307 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
308 : : dpi_conf->c_desc.head))
309 : : return -ENOSPC;
310 : :
311 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
312 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
313 : :
314 : 0 : hdr[1] = dpi_conf->cmd.u | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 37);
315 : 0 : hdr[2] = (uint64_t)comp_ptr;
316 : :
317 : : /*
318 : : * For inbound case, src pointers are last pointers.
319 : : * For all other cases, src pointers are first pointers.
320 : : */
321 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
322 : : fptr = dst;
323 : : lptr = src;
324 : : RTE_SWAP(nb_src, nb_dst);
325 : : } else {
326 : : fptr = src;
327 : : lptr = dst;
328 : : }
329 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
330 : :
331 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
332 [ # # ]: 0 : if (unlikely(rc)) {
333 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
334 : 0 : return rc;
335 : : }
336 : :
337 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
338 : : rte_wmb();
339 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
340 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
341 : 0 : dpivf->total_pnum_words = 0;
342 : : } else {
343 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
344 : : }
345 : :
346 : 0 : dpi_conf->stats.submitted += 1;
347 : :
348 : 0 : return dpi_conf->desc_idx++;
349 : : }
350 : :
351 : : int
352 : 0 : cn10k_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t dst,
353 : : uint32_t length, uint64_t flags)
354 : : {
355 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
356 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
357 : : uint64_t cmd[CNXK_DPI_DW_PER_SINGLE_CMD];
358 : : uint8_t *comp_ptr;
359 : : int rc;
360 : :
361 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
362 : : dpi_conf->c_desc.head))
363 : : return -ENOSPC;
364 : :
365 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
366 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
367 : :
368 : 0 : cmd[0] = dpi_conf->cmd.u | (1U << 6) | 1U;
369 : 0 : cmd[1] = (uint64_t)comp_ptr;
370 : 0 : cmd[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
371 : 0 : cmd[4] = length;
372 : 0 : cmd[5] = src;
373 : 0 : cmd[6] = length;
374 [ # # ]: 0 : cmd[7] = dst;
375 : :
376 : : rc = __dpi_queue_write_single(dpivf, cmd);
377 [ # # ]: 0 : if (unlikely(rc)) {
378 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
379 : 0 : return rc;
380 : : }
381 : :
382 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
383 : : rte_wmb();
384 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_DW_PER_SINGLE_CMD,
385 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
386 : 0 : dpivf->total_pnum_words = 0;
387 : : } else {
388 : 0 : dpivf->total_pnum_words += CNXK_DPI_DW_PER_SINGLE_CMD;
389 : : }
390 : :
391 : 0 : dpi_conf->stats.submitted += 1;
392 : :
393 : 0 : return dpi_conf->desc_idx++;
394 : : }
395 : :
396 : : int
397 : 0 : cn10k_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *src,
398 : : const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst,
399 : : uint64_t flags)
400 : : {
401 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
402 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
403 : : uint8_t *comp_ptr;
404 : : uint64_t hdr[4];
405 : : int rc;
406 : :
407 [ # # ]: 0 : if (unlikely(((dpi_conf->c_desc.tail + 1) & dpi_conf->c_desc.max_cnt) ==
408 : : dpi_conf->c_desc.head))
409 : : return -ENOSPC;
410 : :
411 : 0 : comp_ptr = &dpi_conf->c_desc.compl_ptr[dpi_conf->c_desc.tail * CNXK_DPI_COMPL_OFFSET];
412 : 0 : CNXK_DPI_STRM_INC(dpi_conf->c_desc, tail);
413 : :
414 : 0 : hdr[0] = dpi_conf->cmd.u | (nb_dst << 6) | nb_src;
415 : 0 : hdr[1] = (uint64_t)comp_ptr;
416 : 0 : hdr[2] = (1UL << 47) | ((flags & RTE_DMA_OP_FLAG_AUTO_FREE) << 43);
417 : :
418 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
419 [ # # ]: 0 : if (unlikely(rc)) {
420 [ # # ]: 0 : CNXK_DPI_STRM_DEC(dpi_conf->c_desc, tail);
421 : 0 : return rc;
422 : : }
423 : :
424 [ # # ]: 0 : if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
425 : : rte_wmb();
426 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
427 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
428 : 0 : dpivf->total_pnum_words = 0;
429 : : } else {
430 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
431 : : }
432 : :
433 : 0 : dpi_conf->stats.submitted += 1;
434 : :
435 : 0 : return dpi_conf->desc_idx++;
436 : : }
437 : :
438 : : static inline uint64_t
439 : : cnxk_dma_adapter_format_event(uint64_t event)
440 : : {
441 : : uint64_t w0;
442 : 0 : w0 = (event & 0xFFC000000000) >> 6 |
443 : 0 : (event & 0xFFFFFFF) | RTE_EVENT_TYPE_DMADEV << 28;
444 : :
445 : : return w0;
446 : : }
447 : :
448 : : uint16_t
449 : 0 : cn10k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
450 : : {
451 : : const struct rte_dma_sge *src, *dst;
452 : : struct rte_event_dma_adapter_op *op;
453 : : struct cnxk_dpi_conf *dpi_conf;
454 : : struct cnxk_dpi_vf_s *dpivf;
455 : : struct cn10k_sso_hws *work;
456 : : uint16_t nb_src, nb_dst;
457 : : rte_mcslock_t mcs_lock_me;
458 : : uint64_t hdr[4];
459 : : uint16_t count;
460 : : int rc;
461 : :
462 : : work = (struct cn10k_sso_hws *)ws;
463 : :
464 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
465 : 0 : op = ev[count].event_ptr;
466 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
467 : 0 : dpi_conf = &dpivf->conf[op->vchan];
468 : :
469 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
470 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
471 : :
472 : 0 : hdr[0] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 54);
473 : 0 : hdr[0] |= (nb_dst << 6) | nb_src;
474 : 0 : hdr[1] = (uint64_t)op;
475 : 0 : hdr[2] = cnxk_dma_adapter_format_event(ev[count].event);
476 : :
477 : 0 : src = &op->src_dst_seg[0];
478 : 0 : dst = &op->src_dst_seg[op->nb_src];
479 : :
480 [ # # ]: 0 : if (CNXK_TAG_IS_HEAD(work->gw_rdata) ||
481 [ # # ]: 0 : ((CNXK_TT_FROM_TAG(work->gw_rdata) == SSO_TT_ORDERED) &&
482 [ # # ]: 0 : (ev[count].sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED))
483 : 0 : roc_sso_hws_head_wait(work->base);
484 : :
485 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
486 : : rc = __dpi_queue_write_sg(dpivf, hdr, src, dst, nb_src, nb_dst);
487 [ # # ]: 0 : if (unlikely(rc)) {
488 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
489 : 0 : return rc;
490 : : }
491 : :
492 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
493 : : rte_wmb();
494 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
495 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
496 : 0 : dpivf->total_pnum_words = 0;
497 : : } else {
498 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
499 : : }
500 : 0 : dpi_conf->stats.submitted += 1;
501 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
502 : : }
503 : :
504 : : return count;
505 : : }
506 : :
507 : : uint16_t
508 : 0 : cn9k_dma_adapter_dual_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
509 : : {
510 : : const struct rte_dma_sge *fptr, *lptr;
511 : : struct rte_event_dma_adapter_op *op;
512 : : struct cn9k_sso_hws_dual *work;
513 : : struct cnxk_dpi_conf *dpi_conf;
514 : : struct cnxk_dpi_vf_s *dpivf;
515 : : struct rte_event *rsp_info;
516 : : uint16_t nb_src, nb_dst;
517 : : rte_mcslock_t mcs_lock_me;
518 : : uint64_t hdr[4];
519 : : uint16_t count;
520 : : int rc;
521 : :
522 : : work = (struct cn9k_sso_hws_dual *)ws;
523 : :
524 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
525 : 0 : op = ev[count].event_ptr;
526 : : rsp_info = (struct rte_event *)((uint8_t *)op +
527 : : sizeof(struct rte_event_dma_adapter_op));
528 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
529 : 0 : dpi_conf = &dpivf->conf[op->vchan];
530 : :
531 : 0 : hdr[1] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 36);
532 : 0 : hdr[2] = (uint64_t)op;
533 : :
534 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
535 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
536 : : /*
537 : : * For inbound case, src pointers are last pointers.
538 : : * For all other cases, src pointers are first pointers.
539 : : */
540 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
541 : 0 : fptr = &op->src_dst_seg[nb_src];
542 : 0 : lptr = &op->src_dst_seg[0];
543 : : RTE_SWAP(nb_src, nb_dst);
544 : : } else {
545 : 0 : fptr = &op->src_dst_seg[0];
546 : 0 : lptr = &op->src_dst_seg[nb_src];
547 : : }
548 : :
549 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
550 : 0 : hdr[0] |= cnxk_dma_adapter_format_event(rsp_info->event);
551 : :
552 [ # # ]: 0 : if ((rsp_info->sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED)
553 : 0 : roc_sso_hws_head_wait(work->base[!work->vws]);
554 : :
555 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
556 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
557 [ # # ]: 0 : if (unlikely(rc)) {
558 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
559 : 0 : return rc;
560 : : }
561 : :
562 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
563 : : rte_wmb();
564 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
565 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
566 : 0 : dpivf->total_pnum_words = 0;
567 : : } else {
568 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
569 : : }
570 : 0 : dpi_conf->stats.submitted += 1;
571 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
572 : : }
573 : :
574 : : return count;
575 : : }
576 : :
577 : : uint16_t
578 : 0 : cn9k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
579 : : {
580 : : const struct rte_dma_sge *fptr, *lptr;
581 : : struct rte_event_dma_adapter_op *op;
582 : : struct cnxk_dpi_conf *dpi_conf;
583 : : struct cnxk_dpi_vf_s *dpivf;
584 : : struct cn9k_sso_hws *work;
585 : : uint16_t nb_src, nb_dst;
586 : : rte_mcslock_t mcs_lock_me;
587 : : uint64_t hdr[4];
588 : : uint16_t count;
589 : : int rc;
590 : :
591 : : work = (struct cn9k_sso_hws *)ws;
592 : :
593 [ # # ]: 0 : for (count = 0; count < nb_events; count++) {
594 : 0 : op = ev[count].event_ptr;
595 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
596 : 0 : dpi_conf = &dpivf->conf[op->vchan];
597 : :
598 : 0 : hdr[1] = dpi_conf->cmd.u | ((uint64_t)DPI_HDR_PT_WQP << 36);
599 : 0 : hdr[2] = (uint64_t)op;
600 : :
601 : 0 : nb_src = op->nb_src & CNXK_DPI_MAX_POINTER;
602 : 0 : nb_dst = op->nb_dst & CNXK_DPI_MAX_POINTER;
603 : : /*
604 : : * For inbound case, src pointers are last pointers.
605 : : * For all other cases, src pointers are first pointers.
606 : : */
607 [ # # ]: 0 : if (((dpi_conf->cmd.u >> 48) & DPI_HDR_XTYPE_MASK) == DPI_XTYPE_INBOUND) {
608 : 0 : fptr = &op->src_dst_seg[nb_src];
609 : 0 : lptr = &op->src_dst_seg[0];
610 : : RTE_SWAP(nb_src, nb_dst);
611 : : } else {
612 : 0 : fptr = &op->src_dst_seg[0];
613 : 0 : lptr = &op->src_dst_seg[nb_src];
614 : : }
615 : :
616 : 0 : hdr[0] = ((uint64_t)nb_dst << 54) | (uint64_t)nb_src << 48;
617 : 0 : hdr[0] |= cnxk_dma_adapter_format_event(ev[count].event);
618 : :
619 [ # # ]: 0 : if ((ev[count].sched_type & DPI_HDR_TT_MASK) == RTE_SCHED_TYPE_ORDERED)
620 : 0 : roc_sso_hws_head_wait(work->base);
621 : :
622 : 0 : rte_mcslock_lock(&dpivf->mcs_lock, &mcs_lock_me);
623 [ # # ]: 0 : rc = __dpi_queue_write_sg(dpivf, hdr, fptr, lptr, nb_src, nb_dst);
624 [ # # ]: 0 : if (unlikely(rc)) {
625 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
626 : 0 : return rc;
627 : : }
628 : :
629 [ # # ]: 0 : if (op->flags & RTE_DMA_OP_FLAG_SUBMIT) {
630 : : rte_wmb();
631 : 0 : plt_write64(dpivf->total_pnum_words + CNXK_DPI_CMD_LEN(nb_src, nb_dst),
632 : : dpivf->rdpi.rbase + DPI_VDMA_DBELL);
633 : 0 : dpivf->total_pnum_words = 0;
634 : : } else {
635 : 0 : dpivf->total_pnum_words += CNXK_DPI_CMD_LEN(nb_src, nb_dst);
636 : : }
637 : 0 : dpi_conf->stats.submitted += 1;
638 : 0 : rte_mcslock_unlock(&dpivf->mcs_lock, &mcs_lock_me);
639 : : }
640 : :
641 : : return count;
642 : : }
643 : :
644 : : uintptr_t
645 : 0 : cnxk_dma_adapter_dequeue(uintptr_t get_work1)
646 : : {
647 : : struct rte_event_dma_adapter_op *op;
648 : : struct cnxk_dpi_conf *dpi_conf;
649 : : struct cnxk_dpi_vf_s *dpivf;
650 : :
651 : 0 : op = (struct rte_event_dma_adapter_op *)get_work1;
652 : 0 : dpivf = rte_dma_fp_objs[op->dma_dev_id].dev_private;
653 : 0 : dpi_conf = &dpivf->conf[op->vchan];
654 : :
655 [ # # ]: 0 : if (rte_atomic_load_explicit((RTE_ATOMIC(uint64_t) *)&op->impl_opaque[0],
656 : : rte_memory_order_relaxed) != 0)
657 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.errors, 1,
658 : : rte_memory_order_relaxed);
659 : :
660 : : /* Take into account errors also. This is similar to
661 : : * cnxk_dmadev_completed_status().
662 : : */
663 : 0 : rte_atomic_fetch_add_explicit((RTE_ATOMIC(uint64_t) *)&dpi_conf->stats.completed, 1,
664 : : rte_memory_order_relaxed);
665 : :
666 : 0 : return (uintptr_t)op;
667 : : }
|