Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
4 : : * Copyright 2016-2019,2022-2025 NXP
5 : : *
6 : : */
7 : :
8 : : #include <unistd.h>
9 : : #include <stdio.h>
10 : : #include <sys/types.h>
11 : : #include <string.h>
12 : : #include <stdlib.h>
13 : : #include <fcntl.h>
14 : : #include <errno.h>
15 : :
16 : : #include <eal_export.h>
17 : : #include <rte_mbuf.h>
18 : : #include <ethdev_driver.h>
19 : : #include <rte_malloc.h>
20 : : #include <rte_memcpy.h>
21 : : #include <rte_string_fns.h>
22 : : #include <rte_cycles.h>
23 : : #include <rte_kvargs.h>
24 : : #include <dev_driver.h>
25 : : #include "rte_dpaa2_mempool.h"
26 : :
27 : : #include <bus_fslmc_driver.h>
28 : : #include <fslmc_logs.h>
29 : : #include <mc/fsl_dpbp.h>
30 : : #include <portal/dpaa2_hw_pvt.h>
31 : : #include <portal/dpaa2_hw_dpio.h>
32 : : #include "dpaa2_hw_mempool.h"
33 : : #include "dpaa2_hw_mempool_logs.h"
34 : :
35 : : #include <dpaax_iova_table.h>
36 : :
37 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_bpid_info)
38 : : struct dpaa2_bp_info *rte_dpaa2_bpid_info;
39 : : static struct dpaa2_bp_list *h_bp_list;
40 : :
41 : : static int16_t s_dpaa2_pool_ops_idx = RTE_MEMPOOL_MAX_OPS_IDX;
42 : :
43 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mpool_get_ops_idx)
44 : 0 : int rte_dpaa2_mpool_get_ops_idx(void)
45 : : {
46 : 0 : return s_dpaa2_pool_ops_idx;
47 : : }
48 : :
49 : : static int
50 : 0 : rte_hw_mbuf_create_pool(struct rte_mempool *mp)
51 : : {
52 : : struct dpaa2_bp_list *bp_list;
53 : : struct dpaa2_dpbp_dev *avail_dpbp;
54 : : struct dpaa2_bp_info *bp_info;
55 : : struct dpbp_attr dpbp_attr;
56 : : uint32_t bpid;
57 : : unsigned int lcore_id;
58 : : struct rte_mempool_cache *cache;
59 : : int ret;
60 : :
61 : 0 : avail_dpbp = dpaa2_alloc_dpbp_dev();
62 : :
63 [ # # ]: 0 : if (rte_dpaa2_bpid_info == NULL) {
64 : 0 : rte_dpaa2_bpid_info = (struct dpaa2_bp_info *)rte_malloc(NULL,
65 : : sizeof(struct dpaa2_bp_info) * MAX_BPID,
66 : : RTE_CACHE_LINE_SIZE);
67 [ # # ]: 0 : if (rte_dpaa2_bpid_info == NULL)
68 : : return -ENOMEM;
69 : : memset(rte_dpaa2_bpid_info, 0,
70 : : sizeof(struct dpaa2_bp_info) * MAX_BPID);
71 : : }
72 : :
73 [ # # ]: 0 : if (!avail_dpbp) {
74 : 0 : DPAA2_MEMPOOL_ERR("DPAA2 pool not available!");
75 : 0 : return -ENOENT;
76 : : }
77 : :
78 [ # # ]: 0 : if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
79 : 0 : ret = dpaa2_affine_qbman_swp();
80 [ # # ]: 0 : if (ret) {
81 : 0 : DPAA2_MEMPOOL_ERR(
82 : : "Failed to allocate IO portal, tid: %d",
83 : : rte_gettid());
84 : 0 : goto err1;
85 : : }
86 : : }
87 : :
88 : 0 : ret = dpbp_enable(&avail_dpbp->dpbp, CMD_PRI_LOW, avail_dpbp->token);
89 [ # # ]: 0 : if (ret != 0) {
90 : 0 : DPAA2_MEMPOOL_ERR("Resource enable failure with err code: %d",
91 : : ret);
92 : 0 : goto err1;
93 : : }
94 : :
95 : 0 : ret = dpbp_get_attributes(&avail_dpbp->dpbp, CMD_PRI_LOW,
96 : 0 : avail_dpbp->token, &dpbp_attr);
97 [ # # ]: 0 : if (ret != 0) {
98 : 0 : DPAA2_MEMPOOL_ERR("Resource read failure with err code: %d",
99 : : ret);
100 : 0 : goto err2;
101 : : }
102 : :
103 : 0 : bp_info = rte_malloc(NULL,
104 : : sizeof(struct dpaa2_bp_info),
105 : : RTE_CACHE_LINE_SIZE);
106 [ # # ]: 0 : if (!bp_info) {
107 : 0 : DPAA2_MEMPOOL_ERR("Unable to allocate buffer pool memory");
108 : : ret = -ENOMEM;
109 : 0 : goto err2;
110 : : }
111 : :
112 : : /* Allocate the bp_list which will be added into global_bp_list */
113 : 0 : bp_list = rte_malloc(NULL, sizeof(struct dpaa2_bp_list),
114 : : RTE_CACHE_LINE_SIZE);
115 [ # # ]: 0 : if (!bp_list) {
116 : 0 : DPAA2_MEMPOOL_ERR("Unable to allocate buffer pool memory");
117 : : ret = -ENOMEM;
118 : 0 : goto err3;
119 : : }
120 : :
121 : : /* Set parameters of buffer pool list */
122 : 0 : bp_list->buf_pool.num_bufs = mp->size;
123 [ # # ]: 0 : bp_list->buf_pool.size = mp->elt_size
124 : 0 : - sizeof(struct rte_mbuf) - rte_pktmbuf_priv_size(mp);
125 : 0 : bp_list->buf_pool.bpid = dpbp_attr.bpid;
126 : 0 : bp_list->buf_pool.h_bpool_mem = NULL;
127 : 0 : bp_list->buf_pool.dpbp_node = avail_dpbp;
128 : : /* Identification for our offloaded pool_data structure */
129 : 0 : bp_list->dpaa2_ops_index = mp->ops_index;
130 [ # # ]: 0 : if (s_dpaa2_pool_ops_idx == RTE_MEMPOOL_MAX_OPS_IDX) {
131 : 0 : s_dpaa2_pool_ops_idx = mp->ops_index;
132 [ # # ]: 0 : } else if (s_dpaa2_pool_ops_idx != mp->ops_index) {
133 : 0 : DPAA2_MEMPOOL_ERR("Only single ops index only");
134 : : ret = -EINVAL;
135 : 0 : goto err4;
136 : : }
137 : :
138 : 0 : bp_list->next = h_bp_list;
139 : 0 : bp_list->mp = mp;
140 : :
141 : 0 : bpid = dpbp_attr.bpid;
142 : :
143 : 0 : rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
144 : 0 : + rte_pktmbuf_priv_size(mp);
145 : 0 : rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
146 [ # # ]: 0 : rte_dpaa2_bpid_info[bpid].bpid = bpid;
147 : :
148 : : rte_memcpy(bp_info, (void *)&rte_dpaa2_bpid_info[bpid],
149 : : sizeof(struct dpaa2_bp_info));
150 : 0 : mp->pool_data = (void *)bp_info;
151 : :
152 : 0 : DPAA2_MEMPOOL_DEBUG("BP List created for bpid =%d", dpbp_attr.bpid);
153 : :
154 : 0 : h_bp_list = bp_list;
155 : : /* Update per core mempool cache threshold to optimal value which is
156 : : * number of buffers that can be released to HW buffer pool in
157 : : * a single API call.
158 : : */
159 [ # # ]: 0 : for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
160 : 0 : cache = &mp->local_cache[lcore_id];
161 : 0 : DPAA2_MEMPOOL_DEBUG("lCore %d: cache->flushthresh %d -> %d",
162 : : lcore_id, cache->flushthresh,
163 : : (uint32_t)(cache->size + DPAA2_MBUF_MAX_ACQ_REL));
164 [ # # ]: 0 : if (cache->flushthresh)
165 : 0 : cache->flushthresh = cache->size + DPAA2_MBUF_MAX_ACQ_REL;
166 : : }
167 : :
168 : : return 0;
169 : : err4:
170 : 0 : rte_free(bp_list);
171 : 0 : err3:
172 : 0 : rte_free(bp_info);
173 : 0 : err2:
174 : 0 : dpbp_disable(&avail_dpbp->dpbp, CMD_PRI_LOW, avail_dpbp->token);
175 : 0 : err1:
176 : 0 : dpaa2_free_dpbp_dev(avail_dpbp);
177 : :
178 : 0 : return ret;
179 : : }
180 : :
181 : : static void
182 : 0 : rte_hw_mbuf_free_pool(struct rte_mempool *mp)
183 : : {
184 : : struct dpaa2_bp_info *bpinfo;
185 : : struct dpaa2_bp_list *bp;
186 : : struct dpaa2_dpbp_dev *dpbp_node;
187 : :
188 [ # # ]: 0 : if (!mp->pool_data) {
189 : 0 : DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool");
190 : 0 : return;
191 : : }
192 : :
193 : : bpinfo = (struct dpaa2_bp_info *)mp->pool_data;
194 : 0 : bp = bpinfo->bp_list;
195 : 0 : dpbp_node = bp->buf_pool.dpbp_node;
196 : :
197 : 0 : dpbp_disable(&(dpbp_node->dpbp), CMD_PRI_LOW, dpbp_node->token);
198 : :
199 [ # # ]: 0 : if (h_bp_list == bp) {
200 : 0 : h_bp_list = h_bp_list->next;
201 : : } else { /* if it is not the first node */
202 : : struct dpaa2_bp_list *prev = h_bp_list, *temp;
203 : 0 : temp = h_bp_list->next;
204 [ # # ]: 0 : while (temp) {
205 [ # # ]: 0 : if (temp == bp) {
206 : 0 : prev->next = temp->next;
207 : 0 : rte_free(bp);
208 : 0 : break;
209 : : }
210 : : prev = temp;
211 : 0 : temp = temp->next;
212 : : }
213 : : }
214 : :
215 : 0 : rte_free(mp->pool_data);
216 : 0 : dpaa2_free_dpbp_dev(dpbp_node);
217 : : }
218 : :
219 : : static inline int
220 : 0 : dpaa2_bman_multi_release(uint64_t *bufs, int num,
221 : : struct qbman_swp *swp,
222 : : const struct qbman_release_desc *releasedesc)
223 : : {
224 : : int retry_count = 0, ret;
225 : :
226 : 0 : release_again:
227 : 0 : ret = qbman_swp_release(swp, releasedesc, bufs, num);
228 [ # # ]: 0 : if (unlikely(ret == -EBUSY)) {
229 : 0 : retry_count++;
230 [ # # ]: 0 : if (retry_count <= DPAA2_MAX_TX_RETRY_COUNT)
231 : 0 : goto release_again;
232 : :
233 : 0 : DPAA2_MEMPOOL_ERR("bman release retry exceeded, low fbpr?");
234 : 0 : return ret;
235 : : }
236 [ # # ]: 0 : if (unlikely(ret)) {
237 : 0 : DPAA2_MEMPOOL_ERR("bman release failed(err=%d)", ret);
238 : 0 : return ret;
239 : : }
240 : :
241 : : return 0;
242 : : }
243 : :
244 : : static int
245 : 0 : dpaa2_mbuf_release(void * const *obj_table, uint32_t bpid,
246 : : uint32_t meta_data_size, int count)
247 : : {
248 : : struct qbman_release_desc releasedesc;
249 : : struct qbman_swp *swp;
250 : : int ret;
251 : : int i, n;
252 : : uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
253 : :
254 [ # # ]: 0 : if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
255 : 0 : ret = dpaa2_affine_qbman_swp();
256 [ # # ]: 0 : if (ret) {
257 : 0 : DPAA2_MEMPOOL_ERR("affine portal err: %d, tid: %d",
258 : : ret, rte_gettid());
259 : 0 : return -EIO;
260 : : }
261 : : }
262 : 0 : swp = DPAA2_PER_LCORE_PORTAL;
263 : :
264 : : /* Create a release descriptor required for releasing
265 : : * buffers into QBMAN
266 : : */
267 : 0 : qbman_release_desc_clear(&releasedesc);
268 : 0 : qbman_release_desc_set_bpid(&releasedesc, bpid);
269 : :
270 : 0 : n = count % DPAA2_MBUF_MAX_ACQ_REL;
271 [ # # ]: 0 : if (unlikely(!n))
272 : 0 : goto aligned;
273 : :
274 : : /* convert mbuf to buffers for the remainder */
275 [ # # ]: 0 : if (likely(rte_eal_iova_mode() == RTE_IOVA_VA)) {
276 [ # # ]: 0 : for (i = 0; i < n ; i++) {
277 : 0 : bufs[i] = DPAA2_VAMODE_VADDR_TO_IOVA(obj_table[i]) +
278 : : meta_data_size;
279 : : }
280 : : } else {
281 [ # # ]: 0 : for (i = 0; i < n ; i++) {
282 : 0 : bufs[i] = DPAA2_PAMODE_VADDR_TO_IOVA(obj_table[i]) +
283 : : meta_data_size;
284 : : }
285 : : }
286 : :
287 : : /* feed them to bman */
288 : 0 : ret = dpaa2_bman_multi_release(bufs, n, swp, &releasedesc);
289 [ # # ]: 0 : if (unlikely(ret))
290 : : return 0;
291 : :
292 : 0 : aligned:
293 : : /* if there are more buffers to free */
294 [ # # ]: 0 : if (unlikely(rte_eal_iova_mode() != RTE_IOVA_VA))
295 : 0 : goto iova_pa_release;
296 : :
297 [ # # ]: 0 : while (n < count) {
298 : : /* convert mbuf to buffers */
299 [ # # ]: 0 : for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++) {
300 : 0 : bufs[i] = DPAA2_VAMODE_VADDR_TO_IOVA(obj_table[n + i]) +
301 : : meta_data_size;
302 : : }
303 : :
304 : 0 : ret = dpaa2_bman_multi_release(bufs,
305 : : DPAA2_MBUF_MAX_ACQ_REL, swp, &releasedesc);
306 [ # # ]: 0 : if (unlikely(ret))
307 : 0 : return n;
308 : :
309 : 0 : n += DPAA2_MBUF_MAX_ACQ_REL;
310 : : }
311 : :
312 : : return count;
313 : :
314 : : iova_pa_release:
315 [ # # ]: 0 : while (n < count) {
316 : : /* convert mbuf to buffers */
317 [ # # ]: 0 : for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++) {
318 : 0 : bufs[i] = DPAA2_PAMODE_VADDR_TO_IOVA(obj_table[n + i]) +
319 : : meta_data_size;
320 : : }
321 : :
322 : 0 : ret = dpaa2_bman_multi_release(bufs,
323 : : DPAA2_MBUF_MAX_ACQ_REL, swp, &releasedesc);
324 [ # # ]: 0 : if (unlikely(ret))
325 : 0 : return n;
326 : :
327 : 0 : n += DPAA2_MBUF_MAX_ACQ_REL;
328 : : }
329 : :
330 : : return count;
331 : : }
332 : :
333 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_bpid_info_init)
334 : 0 : int rte_dpaa2_bpid_info_init(struct rte_mempool *mp)
335 : : {
336 : 0 : struct dpaa2_bp_info *bp_info = mempool_to_bpinfo(mp);
337 : 0 : uint32_t bpid = bp_info->bpid;
338 : :
339 [ # # ]: 0 : if (!rte_dpaa2_bpid_info) {
340 : 0 : rte_dpaa2_bpid_info = (struct dpaa2_bp_info *)rte_malloc(NULL,
341 : : sizeof(struct dpaa2_bp_info) * MAX_BPID,
342 : : RTE_CACHE_LINE_SIZE);
343 [ # # ]: 0 : if (rte_dpaa2_bpid_info == NULL)
344 : : return -ENOMEM;
345 : : memset(rte_dpaa2_bpid_info, 0,
346 : : sizeof(struct dpaa2_bp_info) * MAX_BPID);
347 : : }
348 : :
349 : 0 : rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
350 : 0 : + rte_pktmbuf_priv_size(mp);
351 : 0 : rte_dpaa2_bpid_info[bpid].bp_list = bp_info->bp_list;
352 : 0 : rte_dpaa2_bpid_info[bpid].bpid = bpid;
353 : :
354 : 0 : return 0;
355 : : }
356 : :
357 : : RTE_EXPORT_SYMBOL(rte_dpaa2_mbuf_pool_bpid)
358 : : uint16_t
359 : 0 : rte_dpaa2_mbuf_pool_bpid(struct rte_mempool *mp)
360 : : {
361 : : struct dpaa2_bp_info *bp_info;
362 : :
363 : 0 : bp_info = mempool_to_bpinfo(mp);
364 [ # # ]: 0 : if (!(bp_info->bp_list)) {
365 : 0 : DPAA2_MEMPOOL_ERR("DPAA2 buffer pool not configured");
366 : 0 : return -ENOMEM;
367 : : }
368 : :
369 : 0 : return bp_info->bpid;
370 : : }
371 : :
372 : : RTE_EXPORT_SYMBOL(rte_dpaa2_mbuf_from_buf_addr)
373 : : struct rte_mbuf *
374 : 0 : rte_dpaa2_mbuf_from_buf_addr(struct rte_mempool *mp, void *buf_addr)
375 : : {
376 : : struct dpaa2_bp_info *bp_info;
377 : :
378 : 0 : bp_info = mempool_to_bpinfo(mp);
379 [ # # ]: 0 : if (!(bp_info->bp_list)) {
380 : 0 : DPAA2_MEMPOOL_ERR("DPAA2 buffer pool not configured");
381 : 0 : return NULL;
382 : : }
383 : :
384 : 0 : return (struct rte_mbuf *)((uint8_t *)buf_addr -
385 : 0 : bp_info->meta_data_size);
386 : : }
387 : :
388 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mbuf_alloc_bulk)
389 : : int
390 : 0 : rte_dpaa2_mbuf_alloc_bulk(struct rte_mempool *pool,
391 : : void **obj_table, unsigned int count)
392 : : {
393 : : #ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
394 : : static int alloc;
395 : : #endif
396 : : struct qbman_swp *swp;
397 : : uint16_t bpid;
398 : : uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
399 : : int i, ret;
400 : : unsigned int n = 0;
401 : : struct dpaa2_bp_info *bp_info;
402 : :
403 : 0 : bp_info = mempool_to_bpinfo(pool);
404 : :
405 [ # # ]: 0 : if (!(bp_info->bp_list)) {
406 : 0 : DPAA2_MEMPOOL_ERR("DPAA2 buffer pool not configured");
407 : 0 : return -ENOENT;
408 : : }
409 : :
410 : 0 : bpid = bp_info->bpid;
411 : :
412 [ # # ]: 0 : if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
413 : 0 : ret = dpaa2_affine_qbman_swp();
414 [ # # ]: 0 : if (ret) {
415 : 0 : DPAA2_MEMPOOL_ERR("affine portal err: %d, tid: %d",
416 : : ret, rte_gettid());
417 : 0 : return ret;
418 : : }
419 : : }
420 : 0 : swp = DPAA2_PER_LCORE_PORTAL;
421 : :
422 [ # # ]: 0 : if (unlikely(rte_eal_iova_mode() != RTE_IOVA_VA))
423 : 0 : goto iova_pa_acquire;
424 : :
425 [ # # ]: 0 : while (n < count) {
426 : : /* Acquire is all-or-nothing, so we drain in 7s,
427 : : * then the remainder.
428 : : */
429 : 0 : ret = qbman_swp_acquire(swp, bpid, bufs,
430 : 0 : (count - n) > DPAA2_MBUF_MAX_ACQ_REL ?
431 : : DPAA2_MBUF_MAX_ACQ_REL : (count - n));
432 [ # # ]: 0 : if (unlikely(ret <= 0))
433 : 0 : goto acquire_failed;
434 : :
435 : : /* assigning mbuf from the acquired objects */
436 [ # # ]: 0 : for (i = 0; i < ret; i++) {
437 : 0 : DPAA2_VAMODE_MODIFY_IOVA_TO_VADDR(bufs[i],
438 : : size_t);
439 : 0 : obj_table[n] = (void *)(uintptr_t)(bufs[i] -
440 : 0 : bp_info->meta_data_size);
441 : 0 : n++;
442 : : }
443 : : }
444 : 0 : goto acquire_success;
445 : :
446 : : iova_pa_acquire:
447 : :
448 [ # # ]: 0 : while (n < count) {
449 : : /* Acquire is all-or-nothing, so we drain in 7s,
450 : : * then the remainder.
451 : : */
452 : 0 : ret = qbman_swp_acquire(swp, bpid, bufs,
453 : 0 : (count - n) > DPAA2_MBUF_MAX_ACQ_REL ?
454 : : DPAA2_MBUF_MAX_ACQ_REL : (count - n));
455 [ # # ]: 0 : if (unlikely(ret <= 0))
456 : 0 : goto acquire_failed;
457 : :
458 : : /* assigning mbuf from the acquired objects */
459 [ # # ]: 0 : for (i = 0; i < ret; i++) {
460 : 0 : DPAA2_PAMODE_MODIFY_IOVA_TO_VADDR(bufs[i],
461 : : size_t);
462 : 0 : obj_table[n] = (void *)(uintptr_t)(bufs[i] -
463 : 0 : bp_info->meta_data_size);
464 : 0 : n++;
465 : : }
466 : : }
467 : :
468 : 0 : acquire_success:
469 : : #ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
470 : : alloc += n;
471 : : DPAA2_MEMPOOL_DP_DEBUG("Total = %d , req = %d done = %d",
472 : : alloc, count, n);
473 : : #endif
474 : : return 0;
475 : :
476 : 0 : acquire_failed:
477 : : DPAA2_MEMPOOL_DP_DEBUG("Buffer acquire err: %d", ret);
478 : : /* The API expect the exact number of requested bufs */
479 : : /* Releasing all buffers allocated */
480 : 0 : ret = dpaa2_mbuf_release(obj_table, bpid,
481 : : bp_info->meta_data_size, n);
482 [ # # ]: 0 : if (ret != (int)n) {
483 : 0 : DPAA2_MEMPOOL_ERR("%s: expect to free %d!= %d",
484 : : __func__, n, ret);
485 : : }
486 : : return -ENOBUFS;
487 : : }
488 : :
489 : : static int
490 : 0 : rte_hw_mbuf_free_bulk(struct rte_mempool *pool,
491 : : void * const *obj_table, unsigned int n)
492 : : {
493 : : struct dpaa2_bp_info *bp_info;
494 : : int ret;
495 : :
496 : 0 : bp_info = mempool_to_bpinfo(pool);
497 [ # # ]: 0 : if (!(bp_info->bp_list)) {
498 : 0 : DPAA2_MEMPOOL_ERR("DPAA2 buffer pool not configured");
499 : 0 : return -ENOENT;
500 : : }
501 : 0 : ret = dpaa2_mbuf_release(obj_table, bp_info->bpid,
502 : : bp_info->meta_data_size, n);
503 [ # # ]: 0 : if (unlikely(ret != (int)n)) {
504 : 0 : DPAA2_MEMPOOL_ERR("%s: expect to free %d!= %d",
505 : : __func__, n, ret);
506 : :
507 : 0 : return -EIO;
508 : : }
509 : :
510 : : return 0;
511 : : }
512 : :
513 : : static unsigned int
514 : 0 : rte_hw_mbuf_get_count(const struct rte_mempool *mp)
515 : : {
516 : : int ret;
517 : 0 : unsigned int num_of_bufs = 0;
518 : : struct dpaa2_bp_info *bp_info;
519 : : struct dpaa2_dpbp_dev *dpbp_node;
520 : : struct fsl_mc_io mc_io;
521 : :
522 [ # # # # ]: 0 : if (!mp || !mp->pool_data) {
523 : 0 : DPAA2_MEMPOOL_ERR("Invalid mempool provided");
524 : 0 : return 0;
525 : : }
526 : :
527 : : bp_info = (struct dpaa2_bp_info *)mp->pool_data;
528 : 0 : dpbp_node = bp_info->bp_list->buf_pool.dpbp_node;
529 : :
530 : : /* In case as secondary process access stats, MCP portal in priv-hw may
531 : : * have primary process address. Need the secondary process based MCP
532 : : * portal address for this object.
533 : : */
534 : 0 : mc_io.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
535 : 0 : ret = dpbp_get_num_free_bufs(&mc_io, CMD_PRI_LOW,
536 : 0 : dpbp_node->token, &num_of_bufs);
537 [ # # ]: 0 : if (ret) {
538 : 0 : DPAA2_MEMPOOL_ERR("Unable to obtain free buf count (err=%d)",
539 : : ret);
540 : 0 : return 0;
541 : : }
542 : :
543 : : DPAA2_MEMPOOL_DP_DEBUG("Free bufs = %u\n", num_of_bufs);
544 : :
545 : 0 : return num_of_bufs;
546 : : }
547 : :
548 : : static int
549 : 0 : dpaa2_populate(struct rte_mempool *mp, unsigned int max_objs,
550 : : void *vaddr, rte_iova_t paddr, size_t len,
551 : : rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg)
552 : : {
553 : : struct rte_memseg_list *msl;
554 : : int ret;
555 : : /* The memsegment list exists incase the memory is not external.
556 : : * So, DMA-Map is required only when memory is provided by user,
557 : : * i.e. External.
558 : : */
559 : 0 : msl = rte_mem_virt2memseg_list(vaddr);
560 : :
561 [ # # ]: 0 : if (!msl) {
562 : 0 : DPAA2_MEMPOOL_DEBUG("Memsegment is External.");
563 : 0 : ret = rte_fslmc_vfio_mem_dmamap((size_t)vaddr, paddr, len);
564 [ # # ]: 0 : if (ret)
565 : : return ret;
566 : : }
567 : :
568 : 0 : return rte_mempool_op_populate_helper(mp, 0, max_objs, vaddr, paddr,
569 : : len, obj_cb, obj_cb_arg);
570 : : }
571 : :
572 : : static const struct rte_mempool_ops dpaa2_mpool_ops = {
573 : : .name = DPAA2_MEMPOOL_OPS_NAME,
574 : : .alloc = rte_hw_mbuf_create_pool,
575 : : .free = rte_hw_mbuf_free_pool,
576 : : .enqueue = rte_hw_mbuf_free_bulk,
577 : : .dequeue = rte_dpaa2_mbuf_alloc_bulk,
578 : : .get_count = rte_hw_mbuf_get_count,
579 : : .populate = dpaa2_populate,
580 : : };
581 : :
582 : 253 : RTE_MEMPOOL_REGISTER_OPS(dpaa2_mpool_ops);
583 : :
584 [ - + ]: 253 : RTE_LOG_REGISTER_DEFAULT(dpaa2_logtype_mempool, NOTICE);
|