O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fhi_lib / lib / src / xran_mem_mgr.c
diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c
new file mode 100644 (file)
index 0000000..3e401e6
--- /dev/null
@@ -0,0 +1,185 @@
+/******************************************************************************
+*
+*   Copyright (c) 2020 Intel.
+*
+*   Licensed under the Apache License, Version 2.0 (the "License");
+*   you may not use this file except in compliance with the License.
+*   You may obtain a copy of the License at
+*
+*       http://www.apache.org/licenses/LICENSE-2.0
+*
+*   Unless required by applicable law or agreed to in writing, software
+*   distributed under the License is distributed on an "AS IS" BASIS,
+*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*   See the License for the specific language governing permissions and
+*   limitations under the License.
+*
+*******************************************************************************/
+
+/**
+ * @brief XRAN memory management
+ * @file xran_mem_mgr.c
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#define _GNU_SOURCE
+#include <sched.h>
+#include <assert.h>
+#include <err.h>
+#include <libgen.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <malloc.h>
+#include <immintrin.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_mbuf.h>
+#include <rte_ring.h>
+
+#include "ethernet.h"
+#include "xran_mem_mgr.h"
+#include "xran_dev.h"
+#include "xran_printf.h"
+
+int32_t
+xran_mm_init (void * pHandle, uint64_t nMemorySize,
+            uint32_t nMemorySegmentSize)
+{
+    /* we use mbuf from dpdk memory */
+    return 0;
+}
+
+int32_t
+xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
+{
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    uint32_t nAllocBufferSize;
+
+    char pool_name[RTE_MEMPOOL_NAMESIZE];
+
+    snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
+        pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
+
+    nAllocBufferSize = nBufferSize + sizeof(struct rte_ether_hdr) +
+        sizeof (struct xran_ecpri_hdr) +
+        sizeof (struct radio_app_common_hdr) +
+        sizeof(struct data_section_hdr) + 256;
+
+    if(nAllocBufferSize >= UINT16_MAX) {
+        rte_panic("nAllocBufferSize is failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d nAllocBufferSize %d\n",
+                    pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, nAllocBufferSize);
+        return -1;
+    }
+
+    printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name,
+                        pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize);
+
+    pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
+                                                                               MBUF_CACHE, 0, nAllocBufferSize, rte_socket_id());
+
+    if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){
+        rte_panic("rte_pktmbuf_pool_create failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n",
+                    pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno));
+        return -1;
+    }
+
+    pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex]  = nBufferSize;
+    pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
+
+    printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n",
+                pXranCc, pXranCc->nXranPort, pXranCc->nIndex,
+                    pXranCc->nBufferPoolIndex,  pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]);
+
+    *pPoolIndex = pXranCc->nBufferPoolIndex++;
+
+    return 0;
+}
+
+int32_t
+xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData,  void **ppCtrl)
+{
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    *ppData = NULL;
+    *ppCtrl = NULL;
+
+    struct rte_mbuf * mb =  rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
+
+    if(mb){
+        char * start     = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
+        char * ethhdr    = rte_pktmbuf_prepend(mb, sizeof(struct rte_ether_hdr));
+
+        if(start && ethhdr){
+            char * iq_offset = rte_pktmbuf_mtod(mb, char * );
+            /* skip headers */
+            iq_offset = iq_offset + sizeof(struct rte_ether_hdr) +
+                                    sizeof (struct xran_ecpri_hdr) +
+                                    sizeof (struct radio_app_common_hdr) +
+                                    sizeof(struct data_section_hdr);
+
+            if (0) /* if compression */
+                iq_offset += sizeof (struct data_section_compression_hdr);
+
+            *ppData = (void *)iq_offset;
+            *ppCtrl  = (void *)mb;
+        } else {
+            print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex );
+            return -1;
+        }
+    } else {
+        print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
+        return -1;
+    }
+
+    if (*ppData ==  NULL){
+        print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]);
+        return -1;
+    }
+
+    return 0;
+}
+
+int32_t
+xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
+{
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+
+    if(pCtrl)
+        rte_pktmbuf_free(pCtrl);
+
+    return 0;
+}
+
+void*
+xran_malloc(size_t buf_len)
+{
+    return rte_malloc("External buffer", buf_len, RTE_CACHE_LINE_SIZE);
+}
+
+void
+xran_free(void *addr)
+{
+    return rte_free(addr);
+}
+
+int32_t
+xran_mm_destroy (void * pHandle)
+{
+    if(xran_get_if_state() == XRAN_RUNNING) {
+        print_err("Please STOP first !!");
+        return (-1);
+        }
+
+    /* functionality is not yet implemented */
+    return 0;
+}