1aaf4363eSJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause 2aaf4363eSJerin Jacob * Copyright(c) 2017 Cavium, Inc 302fd6c74SSantosh Shukla */ 4aaf4363eSJerin Jacob 502fd6c74SSantosh Shukla #include <stdio.h> 602fd6c74SSantosh Shukla #include <rte_mempool.h> 702fd6c74SSantosh Shukla #include <rte_malloc.h> 802fd6c74SSantosh Shukla #include <rte_mbuf.h> 902fd6c74SSantosh Shukla 1002fd6c74SSantosh Shukla #include "octeontx_fpavf.h" 1102fd6c74SSantosh Shukla 1202fd6c74SSantosh Shukla static int 1302fd6c74SSantosh Shukla octeontx_fpavf_alloc(struct rte_mempool *mp) 1402fd6c74SSantosh Shukla { 1502fd6c74SSantosh Shukla uintptr_t pool; 1602fd6c74SSantosh Shukla uint32_t memseg_count = mp->size; 1702fd6c74SSantosh Shukla uint32_t object_size; 1802fd6c74SSantosh Shukla int rc = 0; 1902fd6c74SSantosh Shukla 2002fd6c74SSantosh Shukla object_size = mp->elt_size + mp->header_size + mp->trailer_size; 2102fd6c74SSantosh Shukla 2202fd6c74SSantosh Shukla pool = octeontx_fpa_bufpool_create(object_size, memseg_count, 2302fd6c74SSantosh Shukla OCTEONTX_FPAVF_BUF_OFFSET, 2402fd6c74SSantosh Shukla mp->socket_id); 2502fd6c74SSantosh Shukla rc = octeontx_fpa_bufpool_block_size(pool); 2602fd6c74SSantosh Shukla if (rc < 0) 2702fd6c74SSantosh Shukla goto _end; 2802fd6c74SSantosh Shukla 2902fd6c74SSantosh Shukla if ((uint32_t)rc != object_size) 30*f665790aSDavid Marchand fpavf_log_err("buffer size mismatch: %d instead of %u", 3102fd6c74SSantosh Shukla rc, object_size); 3202fd6c74SSantosh Shukla 33*f665790aSDavid Marchand fpavf_log_info("Pool created %p with .. obj_sz %d, cnt %d", 34*f665790aSDavid Marchand (void *)pool, object_size, memseg_count); 3502fd6c74SSantosh Shukla 3602fd6c74SSantosh Shukla /* assign pool handle to mempool */ 3702fd6c74SSantosh Shukla mp->pool_id = (uint64_t)pool; 3802fd6c74SSantosh Shukla 3902fd6c74SSantosh Shukla return 0; 4002fd6c74SSantosh Shukla 4102fd6c74SSantosh Shukla _end: 4202fd6c74SSantosh Shukla return rc; 4302fd6c74SSantosh Shukla } 4402fd6c74SSantosh Shukla 45806714f1SSantosh Shukla static void 46806714f1SSantosh Shukla octeontx_fpavf_free(struct rte_mempool *mp) 47806714f1SSantosh Shukla { 48806714f1SSantosh Shukla uintptr_t pool; 49806714f1SSantosh Shukla pool = (uintptr_t)mp->pool_id; 50806714f1SSantosh Shukla 51806714f1SSantosh Shukla octeontx_fpa_bufpool_destroy(pool, mp->socket_id); 52806714f1SSantosh Shukla } 53806714f1SSantosh Shukla 54e4f67314SSantosh Shukla static __rte_always_inline void * 55e4f67314SSantosh Shukla octeontx_fpa_bufpool_alloc(uintptr_t handle) 56e4f67314SSantosh Shukla { 57e4f67314SSantosh Shukla return (void *)(uintptr_t)fpavf_read64((void *)(handle + 58e4f67314SSantosh Shukla FPA_VF_VHAURA_OP_ALLOC(0))); 59e4f67314SSantosh Shukla } 60e4f67314SSantosh Shukla 61e4f67314SSantosh Shukla static __rte_always_inline void 62e4f67314SSantosh Shukla octeontx_fpa_bufpool_free(uintptr_t handle, void *buf) 63e4f67314SSantosh Shukla { 64e4f67314SSantosh Shukla uint64_t free_addr = FPA_VF_FREE_ADDRS_S(FPA_VF_VHAURA_OP_FREE(0), 65e4f67314SSantosh Shukla 0 /* DWB */, 1 /* FABS */); 66e4f67314SSantosh Shukla 67e4f67314SSantosh Shukla fpavf_write64((uintptr_t)buf, (void *)(uintptr_t)(handle + free_addr)); 68e4f67314SSantosh Shukla } 69e4f67314SSantosh Shukla 70e4f67314SSantosh Shukla static int 71e4f67314SSantosh Shukla octeontx_fpavf_enqueue(struct rte_mempool *mp, void * const *obj_table, 72e4f67314SSantosh Shukla unsigned int n) 73e4f67314SSantosh Shukla { 74e4f67314SSantosh Shukla uintptr_t pool; 75e4f67314SSantosh Shukla unsigned int index; 76e4f67314SSantosh Shukla 77e4f67314SSantosh Shukla pool = (uintptr_t)mp->pool_id; 78e4f67314SSantosh Shukla /* Get pool bar address from handle */ 79e4f67314SSantosh Shukla pool &= ~(uint64_t)FPA_GPOOL_MASK; 80e4f67314SSantosh Shukla for (index = 0; index < n; index++, obj_table++) 81e4f67314SSantosh Shukla octeontx_fpa_bufpool_free(pool, *obj_table); 82e4f67314SSantosh Shukla 83e4f67314SSantosh Shukla return 0; 84e4f67314SSantosh Shukla } 85e4f67314SSantosh Shukla 86e4f67314SSantosh Shukla static int 87e4f67314SSantosh Shukla octeontx_fpavf_dequeue(struct rte_mempool *mp, void **obj_table, 88e4f67314SSantosh Shukla unsigned int n) 89e4f67314SSantosh Shukla { 90e4f67314SSantosh Shukla unsigned int index; 91e4f67314SSantosh Shukla uintptr_t pool; 92e4f67314SSantosh Shukla void *obj; 93e4f67314SSantosh Shukla 94e4f67314SSantosh Shukla pool = (uintptr_t)mp->pool_id; 95e4f67314SSantosh Shukla /* Get pool bar address from handle */ 96e4f67314SSantosh Shukla pool &= ~(uint64_t)FPA_GPOOL_MASK; 97e4f67314SSantosh Shukla for (index = 0; index < n; index++, obj_table++) { 98e4f67314SSantosh Shukla obj = octeontx_fpa_bufpool_alloc(pool); 99e4f67314SSantosh Shukla if (obj == NULL) { 100e4f67314SSantosh Shukla /* 101e4f67314SSantosh Shukla * Failed to allocate the requested number of objects 102e4f67314SSantosh Shukla * from the pool. Current pool implementation requires 103e4f67314SSantosh Shukla * completing the entire request or returning error 104e4f67314SSantosh Shukla * otherwise. 105e4f67314SSantosh Shukla * Free already allocated buffers to the pool. 106e4f67314SSantosh Shukla */ 107e4f67314SSantosh Shukla for (; index > 0; index--) { 108e4f67314SSantosh Shukla obj_table--; 109e4f67314SSantosh Shukla octeontx_fpa_bufpool_free(pool, *obj_table); 110e4f67314SSantosh Shukla } 111e4f67314SSantosh Shukla return -ENOMEM; 112e4f67314SSantosh Shukla } 113e4f67314SSantosh Shukla *obj_table = obj; 114e4f67314SSantosh Shukla } 115e4f67314SSantosh Shukla 116e4f67314SSantosh Shukla return 0; 117e4f67314SSantosh Shukla } 118e4f67314SSantosh Shukla 119e48de68dSSantosh Shukla static unsigned int 120e48de68dSSantosh Shukla octeontx_fpavf_get_count(const struct rte_mempool *mp) 121e48de68dSSantosh Shukla { 122e48de68dSSantosh Shukla uintptr_t pool; 123e48de68dSSantosh Shukla 124e48de68dSSantosh Shukla pool = (uintptr_t)mp->pool_id; 125e48de68dSSantosh Shukla 126e48de68dSSantosh Shukla return octeontx_fpa_bufpool_free_count(pool); 127e48de68dSSantosh Shukla } 128e48de68dSSantosh Shukla 129ce1f2c61SAndrew Rybchenko static ssize_t 130ce1f2c61SAndrew Rybchenko octeontx_fpavf_calc_mem_size(const struct rte_mempool *mp, 131ce1f2c61SAndrew Rybchenko uint32_t obj_num, uint32_t pg_shift, 132ce1f2c61SAndrew Rybchenko size_t *min_chunk_size, size_t *align) 13306935a4fSSantosh Shukla { 134ce1f2c61SAndrew Rybchenko ssize_t mem_size; 13584626a0dSOlivier Matz size_t total_elt_sz; 136ce1f2c61SAndrew Rybchenko 13784626a0dSOlivier Matz /* Need space for one more obj on each chunk to fulfill 13884626a0dSOlivier Matz * alignment requirements. 139ce1f2c61SAndrew Rybchenko */ 14084626a0dSOlivier Matz total_elt_sz = mp->header_size + mp->elt_size + mp->trailer_size; 14184626a0dSOlivier Matz mem_size = rte_mempool_op_calc_mem_size_helper(mp, obj_num, pg_shift, 14284626a0dSOlivier Matz total_elt_sz, min_chunk_size, 14384626a0dSOlivier Matz align); 144ce1f2c61SAndrew Rybchenko if (mem_size >= 0) { 145ce1f2c61SAndrew Rybchenko /* 146ce1f2c61SAndrew Rybchenko * Memory area which contains objects must be physically 147ce1f2c61SAndrew Rybchenko * contiguous. 148ce1f2c61SAndrew Rybchenko */ 149ce1f2c61SAndrew Rybchenko *min_chunk_size = mem_size; 150ce1f2c61SAndrew Rybchenko } 151ce1f2c61SAndrew Rybchenko 152ce1f2c61SAndrew Rybchenko return mem_size; 15306935a4fSSantosh Shukla } 15406935a4fSSantosh Shukla 1552baa3f0bSSantosh Shukla static int 156ce1f2c61SAndrew Rybchenko octeontx_fpavf_populate(struct rte_mempool *mp, unsigned int max_objs, 157ce1f2c61SAndrew Rybchenko void *vaddr, rte_iova_t iova, size_t len, 158ce1f2c61SAndrew Rybchenko rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg) 159ce1f2c61SAndrew Rybchenko { 160ce1f2c61SAndrew Rybchenko size_t total_elt_sz; 161ce1f2c61SAndrew Rybchenko size_t off; 162a1c55702SAndrew Rybchenko uint8_t gpool; 163a1c55702SAndrew Rybchenko uintptr_t pool_bar; 164a1c55702SAndrew Rybchenko int ret; 165ce1f2c61SAndrew Rybchenko 166ce1f2c61SAndrew Rybchenko if (iova == RTE_BAD_IOVA) 167ce1f2c61SAndrew Rybchenko return -EINVAL; 168ce1f2c61SAndrew Rybchenko 169ce1f2c61SAndrew Rybchenko total_elt_sz = mp->header_size + mp->elt_size + mp->trailer_size; 170ce1f2c61SAndrew Rybchenko 171ce1f2c61SAndrew Rybchenko /* align object start address to a multiple of total_elt_sz */ 17284626a0dSOlivier Matz off = total_elt_sz - ((((uintptr_t)vaddr - 1) % total_elt_sz) + 1); 173ce1f2c61SAndrew Rybchenko 174ce1f2c61SAndrew Rybchenko if (len < off) 175ce1f2c61SAndrew Rybchenko return -EINVAL; 176ce1f2c61SAndrew Rybchenko 177ce1f2c61SAndrew Rybchenko vaddr = (char *)vaddr + off; 178ce1f2c61SAndrew Rybchenko iova += off; 179ce1f2c61SAndrew Rybchenko len -= off; 180ce1f2c61SAndrew Rybchenko 181a1c55702SAndrew Rybchenko gpool = octeontx_fpa_bufpool_gpool(mp->pool_id); 182a1c55702SAndrew Rybchenko pool_bar = mp->pool_id & ~(uint64_t)FPA_GPOOL_MASK; 183a1c55702SAndrew Rybchenko 184a1c55702SAndrew Rybchenko ret = octeontx_fpavf_pool_set_range(pool_bar, len, vaddr, gpool); 185a1c55702SAndrew Rybchenko if (ret < 0) 186a1c55702SAndrew Rybchenko return ret; 187a1c55702SAndrew Rybchenko 18884626a0dSOlivier Matz return rte_mempool_op_populate_helper(mp, 18984626a0dSOlivier Matz RTE_MEMPOOL_POPULATE_F_ALIGN_OBJ, 19084626a0dSOlivier Matz max_objs, vaddr, iova, len, 191ce1f2c61SAndrew Rybchenko obj_cb, obj_cb_arg); 192ce1f2c61SAndrew Rybchenko } 193ce1f2c61SAndrew Rybchenko 19402fd6c74SSantosh Shukla static struct rte_mempool_ops octeontx_fpavf_ops = { 19502fd6c74SSantosh Shukla .name = "octeontx_fpavf", 19602fd6c74SSantosh Shukla .alloc = octeontx_fpavf_alloc, 197806714f1SSantosh Shukla .free = octeontx_fpavf_free, 198e4f67314SSantosh Shukla .enqueue = octeontx_fpavf_enqueue, 199e4f67314SSantosh Shukla .dequeue = octeontx_fpavf_dequeue, 200e48de68dSSantosh Shukla .get_count = octeontx_fpavf_get_count, 201ce1f2c61SAndrew Rybchenko .calc_mem_size = octeontx_fpavf_calc_mem_size, 202ce1f2c61SAndrew Rybchenko .populate = octeontx_fpavf_populate, 20302fd6c74SSantosh Shukla }; 20402fd6c74SSantosh Shukla 205cb77b060SAndrew Rybchenko RTE_MEMPOOL_REGISTER_OPS(octeontx_fpavf_ops); 206