* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / lib / src / xran_mem_mgr.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19 /**
20  * @brief XRAN memory management
21  * @file xran_mem_mgr.c
22  * @ingroup group_source_xran
23  * @author Intel Corporation
24  **/
25
26 #define _GNU_SOURCE
27 #include <sched.h>
28 #include <assert.h>
29 #include <err.h>
30 #include <libgen.h>
31 #include <sys/time.h>
32 #include <sys/queue.h>
33 #include <time.h>
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <pthread.h>
37 #include <malloc.h>
38 #include <immintrin.h>
39
40 #include <rte_common.h>
41 #include <rte_eal.h>
42 #include <rte_errno.h>
43 #include <rte_lcore.h>
44 #include <rte_cycles.h>
45 #include <rte_memory.h>
46 #include <rte_memzone.h>
47 #include <rte_mbuf.h>
48 #include <rte_ring.h>
49
50 #include "ethernet.h"
51 #include "xran_mem_mgr.h"
52 #include "xran_dev.h"
53 #include "xran_printf.h"
54
55 int32_t
56 xran_mm_init (void * pHandle, uint64_t nMemorySize,
57             uint32_t nMemorySegmentSize)
58 {
59     /* we use mbuf from dpdk memory */
60     return 0;
61 }
62
63 int32_t
64 xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
65 {
66     //printf("nNumberOfBuffers=%u\n", nNumberOfBuffers);
67     if(nNumberOfBuffers == 280)
68         nNumberOfBuffers = 560;
69
70     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
71     uint32_t nAllocBufferSize;
72
73     char pool_name[RTE_MEMPOOL_NAMESIZE];
74
75     snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
76         pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
77
78     nAllocBufferSize = nBufferSize + sizeof(struct rte_ether_hdr) +
79         sizeof (struct xran_ecpri_hdr) +
80         sizeof (struct radio_app_common_hdr) +
81         sizeof(struct data_section_hdr) + 256;
82
83     if(nAllocBufferSize >= UINT16_MAX) {
84         rte_panic("nAllocBufferSize is failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d nAllocBufferSize %d\n",
85                     pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, nAllocBufferSize);
86         return -1;
87     }
88
89     printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d socket_id %d\n", pool_name,
90                         pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_socket_id());
91
92     pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
93                                                                                /*MBUF_CACHE*/0, 0, nAllocBufferSize, rte_socket_id());
94
95
96     if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){
97         rte_panic("rte_pktmbuf_pool_create failed [poolName=%s, handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n",
98                     pool_name, pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno));
99         return -1;
100     }
101     //printf("press enter (RTE_MEMPOOL_NAMESIZE=%u)\n", RTE_MEMPOOL_NAMESIZE);
102     //getchar();
103     pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex]  = nBufferSize;
104     pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
105
106     printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n",
107                 pXranCc, pXranCc->nXranPort, pXranCc->nIndex,
108                     pXranCc->nBufferPoolIndex,  pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]);
109
110     *pPoolIndex = pXranCc->nBufferPoolIndex++;
111
112     return 0;
113 }
114
115 int32_t
116 xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData,  void **ppCtrl)
117 {
118     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
119     *ppData = NULL;
120     *ppCtrl = NULL;
121
122     struct rte_mbuf * mb =  rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
123
124     if(mb){
125         char * start     = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
126         char * ethhdr    = rte_pktmbuf_prepend(mb, sizeof(struct rte_ether_hdr));
127
128         if(start && ethhdr){
129             char * iq_offset = rte_pktmbuf_mtod(mb, char * );
130             /* skip headers */
131             iq_offset = iq_offset + sizeof(struct rte_ether_hdr) +
132                                     sizeof (struct xran_ecpri_hdr) +
133                                     sizeof (struct radio_app_common_hdr) +
134                                     sizeof(struct data_section_hdr);
135
136             if (0) /* if compression */
137                 iq_offset += sizeof (struct data_section_compression_hdr);
138
139             *ppData = (void *)iq_offset;
140             *ppCtrl  = (void *)mb;
141         } else {
142             print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex );
143             return -1;
144         }
145     } else {
146         print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
147         return -1;
148     }
149
150     if (*ppData ==  NULL){
151         print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]);
152         return -1;
153     }
154
155     return 0;
156 }
157
158 int32_t
159 xran_bm_allocate_ring(void * pHandle, const char *rng_name_prefix, uint16_t cc_id, uint16_t buff_id, uint16_t ant_id, uint16_t symb_id, void **ppRing)
160 {
161     int32_t ret = 0;
162     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
163     uint32_t xran_port_id;
164     char ring_name[32]    = "";
165     struct rte_ring *ring =  NULL;
166     ssize_t r_size;
167
168     if(pHandle){
169         xran_port_id = pXranCc->nXranPort;
170         *ppRing = NULL;
171         snprintf(ring_name, RTE_DIM(ring_name), "%srb%dp%dcc%dant%dsym%d", rng_name_prefix, buff_id, xran_port_id, cc_id, ant_id, symb_id);
172         print_dbg("%s\n", ring_name);
173         r_size = rte_ring_get_memsize(XRAN_MAX_MEM_IF_RING_SIZE);
174         ring = (struct rte_ring *)xran_malloc(r_size);
175         if(ring ==  NULL) {
176             print_err("[%srb%dp%dcc%dant%dsym%d] ring alloc failed \n", rng_name_prefix, buff_id, xran_port_id, cc_id, ant_id, symb_id);
177             return -1;
178         }
179         ret = rte_ring_init(ring, ring_name, XRAN_MAX_MEM_IF_RING_SIZE, /*RING_F_SC_DEQ*/0);
180         if(ret != 0){
181             print_err("[%srb%dp%dcc%dant%dsym%d] rte_ring_init failed \n", rng_name_prefix, buff_id, xran_port_id, cc_id, ant_id, symb_id);
182             return -1;
183         }
184
185         if(ring) {
186             *ppRing  = (void *)ring;
187         }else {
188             print_err("[%srb%dp%dcc%dant%dsym%d] ring alloc failed \n", rng_name_prefix, buff_id, xran_port_id, cc_id, ant_id, symb_id);
189             return -1;
190         }
191     } else {
192         print_err("pHandle failed \n");
193         return -1;
194     }
195
196     return 0;
197 }
198
199 int32_t
200 xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
201 {
202     //XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
203
204     if(pCtrl)
205         rte_pktmbuf_free(pCtrl);
206
207     return 0;
208 }
209
210 void*
211 xran_malloc(size_t buf_len)
212 {
213     return rte_malloc("External buffer", buf_len, RTE_CACHE_LINE_SIZE);
214 }
215
216 void
217 xran_free(void *addr)
218 {
219     return rte_free(addr);
220 }
221
222 int32_t
223 xran_mm_destroy (void * pHandle)
224 {
225     if(xran_get_if_state() == XRAN_RUNNING) {
226         print_err("Please STOP first !!");
227         return (-1);
228         }
229
230     /* functionality is not yet implemented */
231     return 0;
232 }