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_event_dma_adapter.h>
6 : :
7 : : #include <cnxk_dmadev.h>
8 : :
9 : : static int cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan);
10 : : static void cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t enable_enq_deq);
11 : :
12 : : static int
13 : 0 : cnxk_dmadev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info *dev_info, uint32_t size)
14 : : {
15 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
16 : : RTE_SET_USED(size);
17 : :
18 : 0 : dev_info->max_vchans = CNXK_DPI_MAX_VCHANS_PER_QUEUE;
19 : 0 : dev_info->nb_vchans = dpivf->num_vchans;
20 [ # # ]: 0 : dev_info->dev_capa = RTE_DMA_CAPA_MEM_TO_MEM | RTE_DMA_CAPA_MEM_TO_DEV |
21 : : RTE_DMA_CAPA_DEV_TO_MEM | RTE_DMA_CAPA_DEV_TO_DEV |
22 : : RTE_DMA_CAPA_OPS_COPY | RTE_DMA_CAPA_OPS_COPY_SG |
23 : : RTE_DMA_CAPA_M2D_AUTO_FREE | RTE_DMA_CAPA_OPS_ENQ_DEQ;
24 [ # # ]: 0 : if (roc_feature_dpi_has_priority()) {
25 : 0 : dev_info->dev_capa |= RTE_DMA_CAPA_PRI_POLICY_SP;
26 : 0 : dev_info->nb_priorities = CN10K_DPI_MAX_PRI;
27 : : }
28 : 0 : dev_info->max_desc = CNXK_DPI_MAX_DESC;
29 : 0 : dev_info->min_desc = CNXK_DPI_MIN_DESC;
30 : 0 : dev_info->max_sges = CNXK_DPI_MAX_POINTER;
31 : :
32 : 0 : return 0;
33 : : }
34 : :
35 : : static int
36 : 0 : cnxk_dmadev_vchan_free(struct cnxk_dpi_vf_s *dpivf, uint16_t vchan)
37 : : {
38 : : struct cnxk_dpi_conf *dpi_conf;
39 : : uint16_t num_vchans;
40 : : int i;
41 : :
42 [ # # ]: 0 : if (vchan == RTE_DMA_ALL_VCHAN) {
43 : 0 : num_vchans = dpivf->num_vchans;
44 : : i = 0;
45 : : } else {
46 [ # # ]: 0 : if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
47 : : return -EINVAL;
48 : :
49 : 0 : num_vchans = vchan + 1;
50 : 0 : i = vchan;
51 : : }
52 : :
53 [ # # # # : 0 : for (; i < num_vchans; i++) {
# # ]
54 : : dpi_conf = &dpivf->conf[i];
55 : 0 : rte_free(dpi_conf->c_desc.compl_ptr);
56 : 0 : dpi_conf->c_desc.compl_ptr = NULL;
57 : : }
58 : :
59 : : return 0;
60 : : }
61 : :
62 : : static int
63 : 0 : cnxk_dmadev_chunk_pool_create(struct rte_dma_dev *dev, uint32_t nb_chunks, uint32_t chunk_sz)
64 : : {
65 : : char pool_name[RTE_MEMPOOL_NAMESIZE];
66 : : struct cnxk_dpi_vf_s *dpivf = NULL;
67 : : int rc;
68 : :
69 : 0 : dpivf = dev->fp_obj->dev_private;
70 : : /* Create chunk pool. */
71 : 0 : snprintf(pool_name, sizeof(pool_name), "cnxk_dma_chunk_pool%d", dev->data->dev_id);
72 : :
73 : 0 : nb_chunks += (CNXK_DPI_POOL_MAX_CACHE_SZ * rte_lcore_count());
74 : 0 : dpivf->chunk_pool = rte_mempool_create_empty(
75 : 0 : pool_name, nb_chunks, chunk_sz, CNXK_DPI_POOL_MAX_CACHE_SZ, 0, rte_socket_id(), 0);
76 : :
77 [ # # ]: 0 : if (dpivf->chunk_pool == NULL) {
78 : 0 : plt_err("Unable to create chunkpool.");
79 : 0 : return -ENOMEM;
80 : : }
81 : :
82 : 0 : rc = rte_mempool_set_ops_byname(dpivf->chunk_pool, rte_mbuf_platform_mempool_ops(), NULL);
83 [ # # ]: 0 : if (rc < 0) {
84 : 0 : plt_err("Unable to set chunkpool ops");
85 : 0 : goto free;
86 : : }
87 : :
88 : 0 : rc = rte_mempool_populate_default(dpivf->chunk_pool);
89 [ # # ]: 0 : if (rc < 0) {
90 : 0 : plt_err("Unable to set populate chunkpool.");
91 : 0 : goto free;
92 : : }
93 : 0 : dpivf->aura = roc_npa_aura_handle_to_aura(dpivf->chunk_pool->pool_id);
94 : :
95 : 0 : return 0;
96 : :
97 : 0 : free:
98 : 0 : rte_mempool_free(dpivf->chunk_pool);
99 : 0 : return rc;
100 : : }
101 : :
102 : : static int
103 : 0 : cnxk_dmadev_configure(struct rte_dma_dev *dev, const struct rte_dma_conf *conf, uint32_t conf_sz)
104 : : {
105 : : struct cnxk_dpi_vf_s *dpivf = NULL;
106 : :
107 : : RTE_SET_USED(conf_sz);
108 : 0 : dpivf = dev->fp_obj->dev_private;
109 : :
110 : : /* After config function, vchan setup function has to be called.
111 : : * Free up vchan memory if any, before configuring num_vchans.
112 : : */
113 : : cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
114 [ # # ]: 0 : dpivf->num_vchans = conf->nb_vchans;
115 [ # # ]: 0 : if (roc_feature_dpi_has_priority())
116 : 0 : dpivf->rdpi.priority = conf->priority;
117 : :
118 : 0 : cnxk_set_fp_ops(dev, conf->flags & RTE_DMA_CFG_FLAG_ENQ_DEQ);
119 : :
120 : 0 : return 0;
121 : : }
122 : :
123 : : static int
124 : : dmadev_src_buf_aura_get(struct rte_mempool *sb_mp, const char *mp_ops_name)
125 : : {
126 : : struct rte_mempool_ops *ops;
127 : :
128 : 0 : if (sb_mp == NULL)
129 : : return 0;
130 : :
131 : 0 : ops = rte_mempool_get_ops(sb_mp->ops_index);
132 [ # # # # ]: 0 : if (strcmp(ops->name, mp_ops_name) != 0)
133 : : return -EINVAL;
134 : :
135 : 0 : return roc_npa_aura_handle_to_aura(sb_mp->pool_id);
136 : : }
137 : :
138 : : static int
139 : 0 : cn9k_dmadev_setup_hdr(union cnxk_dpi_instr_cmd *header, const struct rte_dma_vchan_conf *conf)
140 : : {
141 : : int aura;
142 : :
143 : 0 : header->cn9k.pt = DPI_HDR_PT_ZBW_CA;
144 : :
145 [ # # # # : 0 : switch (conf->direction) {
# ]
146 : 0 : case RTE_DMA_DIR_DEV_TO_MEM:
147 : 0 : header->cn9k.xtype = DPI_XTYPE_INBOUND;
148 : 0 : header->cn9k.lport = conf->src_port.pcie.coreid;
149 : 0 : header->cn9k.fport = 0;
150 : 0 : header->cn9k.pvfe = conf->src_port.pcie.vfen;
151 [ # # ]: 0 : if (header->cn9k.pvfe) {
152 : 0 : header->cn9k.func = conf->src_port.pcie.pfid << 12;
153 : 0 : header->cn9k.func |= conf->src_port.pcie.vfid;
154 : : }
155 : : break;
156 : 0 : case RTE_DMA_DIR_MEM_TO_DEV:
157 : 0 : header->cn9k.xtype = DPI_XTYPE_OUTBOUND;
158 : 0 : header->cn9k.lport = 0;
159 : 0 : header->cn9k.fport = conf->dst_port.pcie.coreid;
160 : 0 : header->cn9k.pvfe = conf->dst_port.pcie.vfen;
161 [ # # ]: 0 : if (header->cn9k.pvfe) {
162 : 0 : header->cn9k.func = conf->dst_port.pcie.pfid << 12;
163 : 0 : header->cn9k.func |= conf->dst_port.pcie.vfid;
164 : : }
165 [ # # ]: 0 : aura = dmadev_src_buf_aura_get(conf->auto_free.m2d.pool, "cn9k_mempool_ops");
166 : : if (aura < 0)
167 : 0 : return aura;
168 : 0 : header->cn9k.aura = aura;
169 : 0 : header->cn9k.ii = 1;
170 : 0 : break;
171 : 0 : case RTE_DMA_DIR_MEM_TO_MEM:
172 : 0 : header->cn9k.xtype = DPI_XTYPE_INTERNAL_ONLY;
173 : 0 : header->cn9k.lport = 0;
174 : 0 : header->cn9k.fport = 0;
175 : 0 : header->cn9k.pvfe = 0;
176 : 0 : break;
177 : 0 : case RTE_DMA_DIR_DEV_TO_DEV:
178 : 0 : header->cn9k.xtype = DPI_XTYPE_EXTERNAL_ONLY;
179 : 0 : header->cn9k.lport = conf->src_port.pcie.coreid;
180 : 0 : header->cn9k.fport = conf->dst_port.pcie.coreid;
181 : 0 : header->cn9k.pvfe = 0;
182 : : };
183 : :
184 : : return 0;
185 : : }
186 : :
187 : : static int
188 : 0 : cn10k_dmadev_setup_hdr(union cnxk_dpi_instr_cmd *header, const struct rte_dma_vchan_conf *conf)
189 : : {
190 : : int aura;
191 : :
192 : 0 : header->cn10k.pt = DPI_HDR_PT_ZBW_CA;
193 : :
194 [ # # # # : 0 : switch (conf->direction) {
# ]
195 : 0 : case RTE_DMA_DIR_DEV_TO_MEM:
196 : 0 : header->cn10k.xtype = DPI_XTYPE_INBOUND;
197 : 0 : header->cn10k.lport = conf->src_port.pcie.coreid;
198 : 0 : header->cn10k.fport = 0;
199 : 0 : header->cn10k.pvfe = conf->src_port.pcie.vfen;
200 [ # # ]: 0 : if (header->cn10k.pvfe) {
201 : 0 : header->cn10k.func = conf->src_port.pcie.pfid << 12;
202 : 0 : header->cn10k.func |= conf->src_port.pcie.vfid;
203 : : }
204 : : break;
205 : 0 : case RTE_DMA_DIR_MEM_TO_DEV:
206 : 0 : header->cn10k.xtype = DPI_XTYPE_OUTBOUND;
207 : 0 : header->cn10k.lport = 0;
208 : 0 : header->cn10k.fport = conf->dst_port.pcie.coreid;
209 : 0 : header->cn10k.pvfe = conf->dst_port.pcie.vfen;
210 [ # # ]: 0 : if (header->cn10k.pvfe) {
211 : 0 : header->cn10k.func = conf->dst_port.pcie.pfid << 12;
212 : 0 : header->cn10k.func |= conf->dst_port.pcie.vfid;
213 : : }
214 [ # # ]: 0 : aura = dmadev_src_buf_aura_get(conf->auto_free.m2d.pool, "cn10k_mempool_ops");
215 : : if (aura < 0)
216 : 0 : return aura;
217 : 0 : header->cn10k.aura = aura;
218 : 0 : break;
219 : 0 : case RTE_DMA_DIR_MEM_TO_MEM:
220 : 0 : header->cn10k.xtype = DPI_XTYPE_INTERNAL_ONLY;
221 : 0 : header->cn10k.lport = 0;
222 : 0 : header->cn10k.fport = 0;
223 : 0 : header->cn10k.pvfe = 0;
224 : 0 : break;
225 : 0 : case RTE_DMA_DIR_DEV_TO_DEV:
226 : 0 : header->cn10k.xtype = DPI_XTYPE_EXTERNAL_ONLY;
227 : 0 : header->cn10k.lport = conf->src_port.pcie.coreid;
228 : 0 : header->cn10k.fport = conf->dst_port.pcie.coreid;
229 : 0 : header->cn10k.pvfe = 0;
230 : : };
231 : :
232 : : return 0;
233 : : }
234 : :
235 : : static int
236 : 0 : cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
237 : : const struct rte_dma_vchan_conf *conf, uint32_t conf_sz)
238 : : {
239 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
240 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
241 : : union cnxk_dpi_instr_cmd *header;
242 : : uint16_t max_desc;
243 : : uint32_t size;
244 : : int i, ret;
245 : :
246 : : RTE_SET_USED(conf_sz);
247 : :
248 : 0 : header = (union cnxk_dpi_instr_cmd *)&dpi_conf->cmd.u;
249 : :
250 [ # # ]: 0 : if (dpivf->is_cn10k)
251 : 0 : ret = cn10k_dmadev_setup_hdr(header, conf);
252 : : else
253 : 0 : ret = cn9k_dmadev_setup_hdr(header, conf);
254 : :
255 [ # # ]: 0 : if (ret)
256 : : return ret;
257 : :
258 : : /* Free up descriptor memory before allocating. */
259 : 0 : cnxk_dmadev_vchan_free(dpivf, vchan);
260 : :
261 : 0 : max_desc = conf->nb_desc;
262 [ # # ]: 0 : if (!rte_is_power_of_2(max_desc))
263 : 0 : max_desc = rte_align32pow2(max_desc);
264 : :
265 : : if (max_desc > CNXK_DPI_MAX_DESC)
266 : : max_desc = CNXK_DPI_MAX_DESC;
267 : :
268 : 0 : size = (max_desc * sizeof(uint8_t) * CNXK_DPI_COMPL_OFFSET);
269 : 0 : dpi_conf->c_desc.compl_ptr = rte_zmalloc(NULL, size, 0);
270 : :
271 [ # # ]: 0 : if (dpi_conf->c_desc.compl_ptr == NULL) {
272 : 0 : plt_err("Failed to allocate for comp_data");
273 : 0 : return -ENOMEM;
274 : : }
275 : :
276 : 0 : size = (max_desc * sizeof(struct rte_dma_op *));
277 : 0 : dpi_conf->c_desc.ops = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
278 [ # # ]: 0 : if (dpi_conf->c_desc.ops == NULL) {
279 : 0 : plt_err("Failed to allocate for ops array");
280 : 0 : rte_free(dpi_conf->c_desc.compl_ptr);
281 : 0 : return -ENOMEM;
282 : : }
283 : :
284 [ # # ]: 0 : for (i = 0; i < max_desc; i++)
285 : 0 : dpi_conf->c_desc.compl_ptr[i * CNXK_DPI_COMPL_OFFSET] = CNXK_DPI_REQ_CDATA;
286 : :
287 : 0 : dpi_conf->c_desc.max_cnt = (max_desc - 1);
288 : :
289 : 0 : return 0;
290 : : }
291 : :
292 : : static int
293 : 0 : cnxk_dmadev_start(struct rte_dma_dev *dev)
294 : : {
295 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
296 : : struct cnxk_dpi_conf *dpi_conf;
297 : : uint32_t chunks, nb_desc = 0;
298 : : uint32_t queue_buf_sz;
299 : : int i, j, rc = 0;
300 : : void *chunk;
301 : :
302 : 0 : dpivf->total_pnum_words = 0;
303 : :
304 [ # # ]: 0 : for (i = 0; i < dpivf->num_vchans; i++) {
305 : : dpi_conf = &dpivf->conf[i];
306 : 0 : dpi_conf->c_desc.head = 0;
307 : 0 : dpi_conf->c_desc.tail = 0;
308 : 0 : dpi_conf->desc_idx = 0;
309 [ # # ]: 0 : for (j = 0; j < dpi_conf->c_desc.max_cnt + 1; j++)
310 : 0 : dpi_conf->c_desc.compl_ptr[j * CNXK_DPI_COMPL_OFFSET] = CNXK_DPI_REQ_CDATA;
311 : 0 : nb_desc += dpi_conf->c_desc.max_cnt + 1;
312 : 0 : cnxk_stats_reset(dev, i);
313 : 0 : dpi_conf->completed_offset = 0;
314 : : }
315 : :
316 : : queue_buf_sz = CNXK_DPI_QUEUE_BUF_SIZE_V2;
317 : : /* Max block size allowed by cnxk mempool driver is (128 * 1024).
318 : : * Block size = elt_size + mp->header + mp->trailer.
319 : : *
320 : : * Note from cn9k mempool driver:
321 : : * In cn9k additional padding of 128 bytes is added to mempool->trailer to
322 : : * ensure that the element size always occupies odd number of cachelines
323 : : * to ensure even distribution of elements among L1D cache sets.
324 : : */
325 [ # # ]: 0 : if (!roc_model_is_cn10k())
326 : : queue_buf_sz = CNXK_DPI_QUEUE_BUF_SIZE_V2 - 128;
327 : :
328 : 0 : chunks = CNXK_DPI_CHUNKS_FROM_DESC(queue_buf_sz, nb_desc);
329 : 0 : rc = cnxk_dmadev_chunk_pool_create(dev, chunks, queue_buf_sz);
330 [ # # ]: 0 : if (rc < 0) {
331 : 0 : plt_err("DMA pool configure failed err = %d", rc);
332 : 0 : goto error;
333 : : }
334 : :
335 [ # # ]: 0 : rc = rte_mempool_get(dpivf->chunk_pool, &chunk);
336 [ # # ]: 0 : if (rc < 0) {
337 : 0 : plt_err("DMA failed to get chunk pointer err = %d", rc);
338 : 0 : rte_mempool_free(dpivf->chunk_pool);
339 : 0 : goto error;
340 : : }
341 : :
342 : 0 : rc = roc_dpi_configure_v2(&dpivf->rdpi, queue_buf_sz, dpivf->aura, (uint64_t)chunk);
343 [ # # ]: 0 : if (rc < 0) {
344 : 0 : plt_err("DMA configure failed err = %d", rc);
345 : 0 : rte_mempool_free(dpivf->chunk_pool);
346 : 0 : goto error;
347 : : }
348 : 0 : dpivf->chunk_base = chunk;
349 : 0 : dpivf->chunk_head = 0;
350 : 0 : dpivf->chunk_size_m1 = (queue_buf_sz >> 3) - 2;
351 : :
352 : 0 : roc_dpi_enable(&dpivf->rdpi);
353 : 0 : error:
354 : 0 : return rc;
355 : : }
356 : :
357 : : static int
358 : 0 : cnxk_dmadev_stop(struct rte_dma_dev *dev)
359 : : {
360 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
361 : :
362 [ # # ]: 0 : if (roc_dpi_wait_queue_idle(&dpivf->rdpi))
363 : : return -EAGAIN;
364 : :
365 : 0 : roc_dpi_disable(&dpivf->rdpi);
366 : 0 : rte_mempool_free(dpivf->chunk_pool);
367 : 0 : dpivf->chunk_pool = NULL;
368 : 0 : dpivf->chunk_base = NULL;
369 : 0 : dpivf->chunk_size_m1 = 0;
370 : :
371 : 0 : return 0;
372 : : }
373 : :
374 : : static int
375 : 0 : cnxk_dmadev_close(struct rte_dma_dev *dev)
376 : : {
377 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
378 : :
379 : 0 : roc_dpi_disable(&dpivf->rdpi);
380 : : cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
381 : 0 : roc_dpi_dev_fini(&dpivf->rdpi);
382 : :
383 : : /* Clear all flags as we close the device. */
384 : 0 : dpivf->flag = 0;
385 : :
386 : 0 : return 0;
387 : : }
388 : :
389 : : static uint16_t
390 : 0 : cnxk_dmadev_completed(void *dev_private, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx,
391 : : bool *has_error)
392 : : {
393 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
394 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
395 : : struct cnxk_dpi_cdesc_data_s *c_desc = &dpi_conf->c_desc;
396 : 0 : const uint16_t max_cnt = c_desc->max_cnt;
397 : : uint8_t status;
398 : : int cnt;
399 : :
400 [ # # ]: 0 : for (cnt = 0; cnt < nb_cpls; cnt++) {
401 : 0 : status = c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET];
402 [ # # ]: 0 : if (status) {
403 [ # # ]: 0 : if (status == CNXK_DPI_REQ_CDATA)
404 : : break;
405 : 0 : *has_error = 1;
406 : 0 : dpi_conf->stats.errors++;
407 : 0 : c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
408 : : CNXK_DPI_REQ_CDATA;
409 : 0 : c_desc->head++;
410 : 0 : break;
411 : : }
412 : 0 : c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
413 : : CNXK_DPI_REQ_CDATA;
414 : 0 : c_desc->head++;
415 : : }
416 : :
417 : 0 : dpi_conf->stats.completed += cnt;
418 : 0 : *last_idx = (dpi_conf->completed_offset + dpi_conf->stats.completed - 1) & 0xffff;
419 : :
420 : 0 : return cnt;
421 : : }
422 : :
423 : : static uint16_t
424 : 0 : cnxk_dmadev_completed_status(void *dev_private, uint16_t vchan, const uint16_t nb_cpls,
425 : : uint16_t *last_idx, enum rte_dma_status_code *status)
426 : : {
427 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
428 : 0 : struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
429 : : struct cnxk_dpi_cdesc_data_s *c_desc = &dpi_conf->c_desc;
430 : 0 : const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
431 : : int cnt;
432 : :
433 [ # # ]: 0 : for (cnt = 0; cnt < nb_cpls; cnt++) {
434 : 0 : status[cnt] = c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET];
435 [ # # ]: 0 : if (status[cnt]) {
436 [ # # ]: 0 : if (status[cnt] == CNXK_DPI_REQ_CDATA)
437 : : break;
438 : :
439 : 0 : dpi_conf->stats.errors++;
440 : : }
441 : 0 : c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
442 : : CNXK_DPI_REQ_CDATA;
443 : 0 : c_desc->head++;
444 : : }
445 : :
446 : 0 : dpi_conf->stats.completed += cnt;
447 : 0 : *last_idx = (dpi_conf->completed_offset + dpi_conf->stats.completed - 1) & 0xffff;
448 : :
449 : 0 : return cnt;
450 : : }
451 : :
452 : : static uint16_t
453 : 0 : cnxk_damdev_burst_capacity(const void *dev_private, uint16_t vchan)
454 : : {
455 : : const struct cnxk_dpi_vf_s *dpivf = (const struct cnxk_dpi_vf_s *)dev_private;
456 : 0 : const struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
457 : : uint16_t burst_cap;
458 : :
459 : 0 : burst_cap = dpi_conf->c_desc.max_cnt -
460 : 0 : (dpi_conf->stats.submitted - dpi_conf->stats.completed) + 1;
461 : :
462 : 0 : return burst_cap;
463 : : }
464 : :
465 : : static int
466 : 0 : cnxk_dmadev_submit(void *dev_private, uint16_t vchan)
467 : : {
468 : : struct cnxk_dpi_vf_s *dpivf = dev_private;
469 : 0 : uint32_t num_words = dpivf->total_pnum_words;
470 : : RTE_SET_USED(vchan);
471 : :
472 [ # # ]: 0 : if (!num_words)
473 : : return 0;
474 : :
475 : : rte_wmb();
476 : 0 : plt_write64(num_words, dpivf->rdpi.rbase + DPI_VDMA_DBELL);
477 : :
478 : 0 : dpivf->total_pnum_words = 0;
479 : :
480 : 0 : return 0;
481 : : }
482 : :
483 : : static int
484 : 0 : cnxk_stats_get(const struct rte_dma_dev *dev, uint16_t vchan, struct rte_dma_stats *rte_stats,
485 : : uint32_t size)
486 : : {
487 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
488 : : struct cnxk_dpi_conf *dpi_conf;
489 : : int i;
490 : :
491 [ # # ]: 0 : if (size < sizeof(rte_stats))
492 : : return -EINVAL;
493 [ # # ]: 0 : if (rte_stats == NULL)
494 : : return -EINVAL;
495 : :
496 : : /* Stats of all vchans requested. */
497 [ # # ]: 0 : if (vchan == RTE_DMA_ALL_VCHAN) {
498 [ # # ]: 0 : for (i = 0; i < dpivf->num_vchans; i++) {
499 : : dpi_conf = &dpivf->conf[i];
500 : 0 : rte_stats->submitted += dpi_conf->stats.submitted;
501 : 0 : rte_stats->completed += dpi_conf->stats.completed;
502 : 0 : rte_stats->errors += dpi_conf->stats.errors;
503 : : }
504 : :
505 : 0 : goto done;
506 : : }
507 : :
508 [ # # ]: 0 : if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
509 : : return -EINVAL;
510 : :
511 : 0 : dpi_conf = &dpivf->conf[vchan];
512 : 0 : *rte_stats = dpi_conf->stats;
513 : :
514 : : done:
515 : : return 0;
516 : : }
517 : :
518 : : static int
519 : 0 : cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan)
520 : : {
521 : 0 : struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
522 : : struct cnxk_dpi_conf *dpi_conf;
523 : : int i;
524 : :
525 : : /* clear stats of all vchans. */
526 [ # # ]: 0 : if (vchan == RTE_DMA_ALL_VCHAN) {
527 [ # # ]: 0 : for (i = 0; i < dpivf->num_vchans; i++) {
528 : : dpi_conf = &dpivf->conf[i];
529 : 0 : dpi_conf->completed_offset += dpi_conf->stats.completed;
530 : 0 : dpi_conf->stats = (struct rte_dma_stats){0};
531 : : }
532 : :
533 : : return 0;
534 : : }
535 : :
536 [ # # ]: 0 : if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
537 : : return -EINVAL;
538 : :
539 : 0 : dpi_conf = &dpivf->conf[vchan];
540 : 0 : dpi_conf->completed_offset += dpi_conf->stats.completed;
541 : 0 : dpi_conf->stats = (struct rte_dma_stats){0};
542 : :
543 : 0 : return 0;
544 : : }
545 : :
546 : : static void
547 : 0 : cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t ena_enq_deq)
548 : : {
549 : :
550 : 0 : dev->fp_obj->copy = cnxk_dmadev_copy;
551 : 0 : dev->fp_obj->copy_sg = cnxk_dmadev_copy_sg;
552 : 0 : dev->fp_obj->submit = cnxk_dmadev_submit;
553 : 0 : dev->fp_obj->completed = cnxk_dmadev_completed;
554 : 0 : dev->fp_obj->completed_status = cnxk_dmadev_completed_status;
555 [ # # ]: 0 : dev->fp_obj->burst_capacity = cnxk_damdev_burst_capacity;
556 : :
557 [ # # ]: 0 : if (roc_model_is_cn10k()) {
558 : 0 : dev->fp_obj->copy = cn10k_dmadev_copy;
559 : 0 : dev->fp_obj->copy_sg = cn10k_dmadev_copy_sg;
560 : : }
561 : :
562 [ # # ]: 0 : if (ena_enq_deq) {
563 : 0 : dev->fp_obj->copy = NULL;
564 : 0 : dev->fp_obj->copy_sg = NULL;
565 : 0 : dev->fp_obj->submit = NULL;
566 : 0 : dev->fp_obj->completed = NULL;
567 : 0 : dev->fp_obj->completed_status = NULL;
568 : :
569 : 0 : dev->fp_obj->enqueue = cnxk_dma_ops_enqueue;
570 : 0 : dev->fp_obj->dequeue = cnxk_dma_ops_dequeue;
571 : :
572 [ # # ]: 0 : if (roc_model_is_cn10k())
573 : 0 : dev->fp_obj->enqueue = cn10k_dma_ops_enqueue;
574 : : }
575 : 0 : }
576 : :
577 : : static const struct rte_dma_dev_ops cnxk_dmadev_ops = {
578 : : .dev_close = cnxk_dmadev_close,
579 : : .dev_configure = cnxk_dmadev_configure,
580 : : .dev_info_get = cnxk_dmadev_info_get,
581 : : .dev_start = cnxk_dmadev_start,
582 : : .dev_stop = cnxk_dmadev_stop,
583 : : .stats_get = cnxk_stats_get,
584 : : .stats_reset = cnxk_stats_reset,
585 : : .vchan_setup = cnxk_dmadev_vchan_setup,
586 : : };
587 : :
588 : : static int
589 : 0 : cnxk_dmadev_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev)
590 : : {
591 : : struct cnxk_dpi_vf_s *dpivf = NULL;
592 : : char name[RTE_DEV_NAME_MAX_LEN];
593 : : struct rte_dma_dev *dmadev;
594 : : struct roc_dpi *rdpi = NULL;
595 : : int rc;
596 : :
597 [ # # ]: 0 : if (!pci_dev->mem_resource[0].addr)
598 : : return -ENODEV;
599 : :
600 : 0 : rc = roc_plt_init();
601 [ # # ]: 0 : if (rc) {
602 : 0 : plt_err("Failed to initialize platform model, rc=%d", rc);
603 : 0 : return rc;
604 : : }
605 : : memset(name, 0, sizeof(name));
606 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
607 : :
608 : 0 : dmadev = rte_dma_pmd_allocate(name, pci_dev->device.numa_node, sizeof(*dpivf));
609 [ # # ]: 0 : if (dmadev == NULL) {
610 : 0 : plt_err("dma device allocation failed for %s", name);
611 : 0 : return -ENOMEM;
612 : : }
613 : :
614 : 0 : dpivf = dmadev->data->dev_private;
615 : :
616 : 0 : dmadev->device = &pci_dev->device;
617 : 0 : dmadev->fp_obj->dev_private = dpivf;
618 : 0 : dmadev->dev_ops = &cnxk_dmadev_ops;
619 : :
620 : 0 : dpivf->is_cn10k = roc_model_is_cn10k();
621 : 0 : dpivf->mcs_lock = NULL;
622 : 0 : rdpi = &dpivf->rdpi;
623 : :
624 : 0 : rdpi->pci_dev = pci_dev;
625 : 0 : rc = roc_dpi_dev_init(rdpi, offsetof(struct rte_dma_op, impl_opaque));
626 [ # # ]: 0 : if (rc < 0)
627 : 0 : goto err_out_free;
628 : :
629 : 0 : dmadev->state = RTE_DMA_DEV_READY;
630 : :
631 : 0 : return 0;
632 : :
633 : : err_out_free:
634 : : if (dmadev)
635 : 0 : rte_dma_pmd_release(name);
636 : :
637 : 0 : return rc;
638 : : }
639 : :
640 : : static int
641 : 0 : cnxk_dmadev_remove(struct rte_pci_device *pci_dev)
642 : : {
643 : : char name[RTE_DEV_NAME_MAX_LEN];
644 : :
645 : : memset(name, 0, sizeof(name));
646 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
647 : :
648 : 0 : return rte_dma_pmd_release(name);
649 : : }
650 : :
651 : : static const struct rte_pci_id cnxk_dma_pci_map[] = {
652 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_DPI_VF)},
653 : : {
654 : : .vendor_id = 0,
655 : : },
656 : : };
657 : :
658 : : static struct rte_pci_driver cnxk_dmadev = {
659 : : .id_table = cnxk_dma_pci_map,
660 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
661 : : .probe = cnxk_dmadev_probe,
662 : : .remove = cnxk_dmadev_remove,
663 : : };
664 : :
665 : 253 : RTE_PMD_REGISTER_PCI(cnxk_dmadev_pci_driver, cnxk_dmadev);
666 : : RTE_PMD_REGISTER_PCI_TABLE(cnxk_dmadev_pci_driver, cnxk_dma_pci_map);
667 : : RTE_PMD_REGISTER_KMOD_DEP(cnxk_dmadev_pci_driver, "vfio-pci");
|