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