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