Front Haul Interface Library update to first seed code contribution 31/1331/1 ORAN-seedcode_v1.2
authorLuis Farias <luis.farias@intel.com>
Fri, 1 Nov 2019 21:21:18 +0000 (14:21 -0700)
committerLuis Farias <luis.farias@intel.com>
Fri, 1 Nov 2019 21:21:18 +0000 (14:21 -0700)
The following mandatory features of the ORAN FH interface are not yet
supported in this initial release:
1) RU Category:  Support of CAT-B RU (i.e. precoding in RU)
2) Beamforming: Beam Index Based and Real Time BF weights
3) Transport Features: QoS over FrontHaul
Additional Information available in the readme.txt file
xran root refers to the o-du/phy/fhi_lib folder

Issue-Id: ODUPHY-1

Change-Id: I3c370c1dc794e73e8488a011148d367f7f3525eb
Signed-off-by: Luis Farias <luis.farias@intel.com>
69 files changed:
fhi_lib/app/Makefile
fhi_lib/app/ant_0.bin [deleted file]
fhi_lib/app/ant_1.bin [deleted file]
fhi_lib/app/ant_2.bin [deleted file]
fhi_lib/app/ant_3.bin [deleted file]
fhi_lib/app/common/common.c [deleted file]
fhi_lib/app/config_file_lls_cu.dat [deleted file]
fhi_lib/app/config_file_ru.dat [deleted file]
fhi_lib/app/dpdk.sh
fhi_lib/app/gen_test.m
fhi_lib/app/ifft_in.txt [new file with mode: 0644]
fhi_lib/app/lls-cu/Makefile [deleted file]
fhi_lib/app/ru/Makefile [deleted file]
fhi_lib/app/run_o_du.sh [moved from fhi_lib/app/run_lls-cu.sh with 85% similarity]
fhi_lib/app/run_o_ru.sh [moved from fhi_lib/app/run_ru.sh with 92% similarity]
fhi_lib/app/src/common.c [new file with mode: 0644]
fhi_lib/app/src/common.h [moved from fhi_lib/app/common/common.h with 61% similarity]
fhi_lib/app/src/config.c
fhi_lib/app/src/config.h
fhi_lib/app/src/debug.h [new file with mode: 0644]
fhi_lib/app/src/sample-app.c [moved from fhi_lib/app/lls-cu/sample-lls-cu.c with 52% similarity]
fhi_lib/app/src/xran_mlog_task_id.h
fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_10mhz/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_10mhz/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_20mhz/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_20mhz/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_5mhz/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu0_5mhz/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu1_100mhz/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu1_100mhz/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu3_100mhz/config_file_o_du.dat [new file with mode: 0644]
fhi_lib/app/usecase/mu3_100mhz/config_file_o_ru.dat [new file with mode: 0644]
fhi_lib/build.sh
fhi_lib/lib/Makefile
fhi_lib/lib/api/xran_compression.hpp [new file with mode: 0644]
fhi_lib/lib/api/xran_cp_api.h
fhi_lib/lib/api/xran_fh_o_du.h [moved from fhi_lib/lib/api/xran_fh_lls_cu.h with 57% similarity]
fhi_lib/lib/api/xran_mlog_lnx.h [moved from fhi_lib/lib/src/mlog_lnx_xRAN.h with 89% similarity]
fhi_lib/lib/api/xran_pkt.h
fhi_lib/lib/api/xran_pkt_cp.h
fhi_lib/lib/api/xran_pkt_up.h
fhi_lib/lib/api/xran_sync_api.h
fhi_lib/lib/api/xran_timer.h
fhi_lib/lib/api/xran_transport.h
fhi_lib/lib/api/xran_up_api.h
fhi_lib/lib/ethernet/ethdi.c
fhi_lib/lib/ethernet/ethdi.h
fhi_lib/lib/ethernet/ethernet.c
fhi_lib/lib/ethernet/ethernet.h
fhi_lib/lib/src/xran_app_frag.c [new file with mode: 0644]
fhi_lib/lib/src/xran_app_frag.h [new file with mode: 0644]
fhi_lib/lib/src/xran_common.c
fhi_lib/lib/src/xran_common.h
fhi_lib/lib/src/xran_compression.cpp [new file with mode: 0644]
fhi_lib/lib/src/xran_cp_api.c
fhi_lib/lib/src/xran_frame_struct.c [new file with mode: 0644]
fhi_lib/lib/src/xran_frame_struct.h [new file with mode: 0644]
fhi_lib/lib/src/xran_hash.h [deleted file]
fhi_lib/lib/src/xran_lib_mlog_tasks_id.h
fhi_lib/lib/src/xran_main.c
fhi_lib/lib/src/xran_printf.h
fhi_lib/lib/src/xran_sync_api.c
fhi_lib/lib/src/xran_timer.c
fhi_lib/lib/src/xran_transport.c
fhi_lib/lib/src/xran_ul_tables.c
fhi_lib/lib/src/xran_up_api.c
fhi_lib/readme.txt

index ebad9b9..1c2437d 100644 (file)
 #*
 #*******************************************************************************/
 
-PHONY: all
 
-all: 
-       cd lls-cu && make #DEBUG=1
-       cd ru     && make #DEBUG=1
+MYCUSTOMTAB='     '
+MYCUSTOMSPACE='============================================================================================'
+MYCUSTOMSPACE1='------------------------------------------------------------'
 
-clean: 
-       cd lls-cu && make clean #DEBUG=1
-       cd ru     && make clean #DEBUG=1
+##############################################################
+#  Tools configuration
+##############################################################
+CC  := icc
+CPP := icpc
+AS := as
+AR := ar
+LD := icc
+OBJDUMP := objdump
 
+ifeq ($(SHELL),cmd.exe)
+MD := mkdir.exe -p
+CP := cp.exe -f
+RM := rm.exe -rf
+else
+MD := mkdir -p
+CP := cp -f
+RM := rm -rf
+endif
+
+PROJECT_NAME := sample-app
+PROJECT_TYPE := elf
+PROJECT_DIR  := $(XRAN_DIR)/app
+BUILDDIR := ./build
+PROJECT_BINARY := $(BUILDDIR)/$(PROJECT_NAME)
+
+ifeq ($(RTE_SDK),)
+    $(error "Please define RTE_SDK environment variable")
+endif
+
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
+
+API_DIR := $(XRAN_DIR)/lib/api
+SRC_DIR := $(PROJECT_DIR)/src
+
+ifeq ($(MLOG),1)
+ifeq ($(MLOG_DIR),)
+    MLOG_DIR=$(XRAN_DIR)/../mlog
+endif
+endif
+
+CC_SRC = $(SRC_DIR)/common.c \
+       $(SRC_DIR)/sample-app.c \
+       $(SRC_DIR)/config.c
+
+CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations  \
+       -fdata-sections \
+       -ffunction-sections \
+       -g \
+       -Wall \
+       -Wimplicit-function-declaration \
+       -g -O3
+
+CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+                -no-prec-div -fp-model fast=2\
+                -no-prec-sqrt  -falign-functions=16 -fast-transcendentals \
+        -Werror -Wno-unused-variable -std=c++11 -mcmodel=large
+
+INC :=  -I$(API_DIR) -I$(RTE_INC)
+DEF :=
+
+ifeq ($(MLOG),1)
+       INC  += -I$(MLOG_DIR)/source
+       DEF += -DMLOG_ENABLED
+else
+       DEF += -UMLOG_ENABLED
+endif
+
+XRAN_LIB_DIR=$(XRAN_DIR)/lib/build
+LD_FLAGS += -L$(XRAN_LIB_DIR) -lxran
+
+RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
+LD_FLAGS += $(RTE_LIBS)
+
+ifeq ($(MLOG),1)
+       LD_FLAGS +=  -L$(MLOG_DIR)/bin -lmlog
+endif
+
+AS_FLAGS :=
+AR_FLAGS := rc
+
+PROJECT_OBJ_DIR := build/obj
+
+CC_OBJS := $(patsubst %.c,%.o,$(CC_SRC))
+CPP_OBJS := $(patsubst %.cpp,%.o,$(CPP_SRC))
+AS_OBJS := $(patsubst %.s,%.o,$(AS_SRC))
+OBJS    := $(CC_OBJS) $(CPP_OBJS) $(AS_OBJS) $(LIBS)
+DIRLIST := $(addprefix $(PROJECT_OBJ_DIR)/,$(sort $(dir $(OBJS))))
+
+CC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CC_OBJS))
+CPP_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS))
+
+AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
+
+CC_FLAGS_FULL  := $(CC_FLAGS)  $(INC) $(DEF)
+CPP_FLAGS_FULL := $(CPP_FLAGS) $(INC) $(DEF)
+
+AS_FLAGS := $(AS_FLAGS) $(INC)
+
+PROJECT_DEP_FILE := $(PROJECT_OBJ_DIR)/$(PROJECT_NAME).dep
+
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+GENERATE_DEPS :=
+else
+
+CC_DEPS  := $(addprefix __dep__,$(subst ../,__up__,$(CC_SRC)))
+CPP_DEPS  := $(addprefix __dep__,$(subst ../,__up__,$(CPP_SRC)))
+GENERATE_DEPS := generate_deps
+endif
+
+all : welcome_line     $(PROJECT_BINARY)
+       @echo $(PROJECT_BINARY)
+
+.PHONY : clear_dep
+clear_dep:
+       @$(RM) $(PROJECT_DEP_FILE)
+       @echo [DEP]   $(subst $(PROJECT_OBJ_DIR)/,,$(PROJECT_DEP_FILE))
+
+$(CC_DEPS) :
+       @$(CC) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.c,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CC_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+$(CPP_DEPS) :
+       @$(CPP) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.cpp,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CPP_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+.PHONY : generate_deps
+generate_deps : clear_dep $(CC_DEPS) $(CPP_DEPS)
+
+
+.PHONY : echo_start_build
+echo_start_build :
+       @echo [BUILD] $(PROJECT_TYPE) : $(PROJECT_NAME)
+
+$(DIRLIST) :
+       -@$(MD) $@
+
+$(CC_OBJTARGETS) :
+       @echo [CC]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(CC) -c $(CC_FLAGS_FULL) -o"$@" $(patsubst %.o,%.c,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(CPP_OBJTARGETS) :
+       @echo [CPP]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(CPP) -c $(CPP_FLAGS_FULL) -o"$@" $(patsubst %.o,%.cpp,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(AS_OBJTARGETS) :
+       @echo [AS]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(AS) $(AS_FLAGS) -o"$@" $(patsubst %.o,%.s,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+
+include $(PROJECT_DEP_FILE)
+
+endif
+
+.PHONY: clean xclean
+clean:
+       @echo [CLEAN]  : $(PROJECT_NAME)
+       @$(RM) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+
+xclean: clean
+ifneq ($(wildcard $(PROJECT_DIR)/$(PROJECT_MAKE)),)
+       @echo [XCLEAN] : $(PROJECT_NAME)
+       @$(RM) $(PROJECT_BINARY) $(PROJECT_BINARY_LIB) $(PROJECT_DEP_FILE)
+endif
+
+.PHONY : welcome_line
+welcome_line :
+       @echo $(MYCUSTOMSPACE)
+       @echo Building  $(PROJECT_BINARY)
+       @echo $(MYCUSTOMTAB)RTE_TARGET           = $(RTE_TARGET)
+       @echo $(MYCUSTOMSPACE)
+
+
+.PHONY : debug release
+
+debug :  all
+release :  all
+
+$(PROJECT_BINARY): $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+       @echo "[LD] $@ "
+       @$(LD) -o $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS) $(LD_FLAGS) -Wl,-L $(BUILDDIR) -lrt -lpthread
+
+#@echo [APP]   $@
+#@$(OBJDUMP) -d $(PROJECT_BINARY) > $(PROJECT_BINARY).asm
diff --git a/fhi_lib/app/ant_0.bin b/fhi_lib/app/ant_0.bin
deleted file mode 100644 (file)
index 4d9fb4b..0000000
Binary files a/fhi_lib/app/ant_0.bin and /dev/null differ
diff --git a/fhi_lib/app/ant_1.bin b/fhi_lib/app/ant_1.bin
deleted file mode 100644 (file)
index 6cb4fe7..0000000
Binary files a/fhi_lib/app/ant_1.bin and /dev/null differ
diff --git a/fhi_lib/app/ant_2.bin b/fhi_lib/app/ant_2.bin
deleted file mode 100644 (file)
index d761f95..0000000
Binary files a/fhi_lib/app/ant_2.bin and /dev/null differ
diff --git a/fhi_lib/app/ant_3.bin b/fhi_lib/app/ant_3.bin
deleted file mode 100644 (file)
index 6962e60..0000000
Binary files a/fhi_lib/app/ant_3.bin and /dev/null differ
diff --git a/fhi_lib/app/common/common.c b/fhi_lib/app/common/common.c
deleted file mode 100644 (file)
index 818914e..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/******************************************************************************
-*
-*   Copyright (c) 2019 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.
-*
-*******************************************************************************/
-
-#ifndef _XRAN_APP_COMMON_
-#define _XRAN_APP_COMMON_
-
-#include <assert.h>
-#include <err.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "../common/common.h"
-#include "xran_pkt.h"
-#include "xran_pkt_up.h"
-#include "xran_cp_api.h"
-#include "xran_up_api.h"
-#include "../src/xran_printf.h"
-
-
-#define MBUFS_CNT 256
-
-extern enum app_state state;
-
-uint8_t numCCPorts = 1;
-/* Number of antennas supported by front-end */
-
-uint8_t num_eAxc = 4;
-/* Number of CPRI ports supported by front-end */
-
-int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_prach_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t prach_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t prach_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_tx_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_rx_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-
-void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
-    if (size)
-    {
-        if (filename && bufname)
-        {
-            FILE           *file;
-            printf("Storing %s to file %s: ", bufname, filename);
-            file = fopen(filename, "wb");
-            if (file == NULL)
-            {
-                print_err("can't open file %s!!!", filename);
-            }
-            else
-            {
-                uint32_t             num;
-                num = fwrite(pBuffer, buffers_num, size, file);
-                fflush(file);
-                fclose(file);
-                printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
-            }
-            printf(" \n");
-        }
-        else
-        {
-            print_err(" the file name, buffer name are not set!!!");
-        }
-    }
-    else
-    {
-        print_err(" the %s is free: size = %d bytes!!!", bufname, size);
-    }
-}
-
-int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
-    unsigned int  file_size = 0;
-    int  num= 0;
-
-    if (size)
-    {
-        if (filename && bufname)
-        {
-            FILE           *file;
-            printf("Loading file %s to  %s: ", filename, bufname);
-            file = fopen(filename, "rb");
-
-
-            if (file == NULL)
-            {
-                print_err("can't open file %s!!!", filename);
-                exit(-1);
-            }
-            else
-            {
-                fseek(file, 0, SEEK_END);
-                file_size = ftell(file);
-                fseek(file, 0, SEEK_SET);
-
-                if ((file_size > size) || (file_size == 0))
-                    file_size = size;
-
-                printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
-
-                num = fread(pBuffer, buffers_num, size, file);
-                fflush(file);
-                fclose(file);
-                printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
-            }
-            printf(" \n");
-
-        }
-        else
-        {
-            print_err(" the file name, buffer name are not set!!!");
-        }
-    }
-    else
-    {
-        print_err(" the %s is free: size = %d bytes!!!", bufname, size);
-    }
-    return num;
-}
-
-
-void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
-    unsigned int i;
-    int ret = 0;
-    if (pBuffer == NULL)
-        return;
-
-    if (size)
-    {
-        if (filename && bufname)
-        {
-            FILE           *file;
-            printf("Storing %s to file %s: ", bufname, filename);
-            file = fopen(filename, "w");
-            if (file == NULL)
-            {
-                print_err("can't open file %s!!!", filename);
-                exit(-1);
-            }
-            else
-            {
-                uint32_t num = 0;
-
-                signed short *ptr = (signed short*)pBuffer;
-                for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
-                {
-                    ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
-                    if (ret < 0)
-                    {
-                        printf("fprintf %d\n", ret);
-                        fclose(file);
-                        break;
-                    }
-                    num++;
-                }
-                fflush(file);
-                fclose(file);
-                printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
-            }
-            printf(" \n");
-        }
-        else
-        {
-            print_err(" the file name, buffer name are not set!!!");
-        }
-    }
-    else
-    {
-        print_err(" the %s is free: size = %d bytes!!!", bufname, size);
-    }
-}
-
-
-#endif /* _XRAN_APP_COMMON_ */
diff --git a/fhi_lib/app/config_file_lls_cu.dat b/fhi_lib/app/config_file_lls_cu.dat
deleted file mode 100644 (file)
index 7a17943..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#######################################################################
-#
-# <COPYRIGHT_TAG>
-#
-#######################################################################
-
-# This is simple configuration file. Use '#' sign for comments
-appMode=0 # lls-CU(0) | RU(1)
-xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
-ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
-##Numerology
-mu=3 #mmWave 120Khz Sub Carrier Spacing
-antNum=4 # Number of Antennas per CC (default: 4)
-ttiPeriod=125 # in us TTI period (mmWave default 125us)
-llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
-ruMac=00:11:22:33:44:55  #RU VF for RU app
-#ruMac=3c:fd:fe:b1:d8:98 #RU PF for tcpdump
-#56:1e:4b:0c:f5:9b # RU MAC
-antC0=./ant_0.bin   #CC0
-antC1=./ant_1.bin   #CC0
-antC2=./ant_2.bin   #CC0
-antC3=./ant_3.bin   #CC0
-antC4=./ant_4.bin   #CC1
-antC5=./ant_5.bin   #CC1
-antC6=./ant_6.bin   #CC1
-antC7=./ant_7.bin   #CC1
-antC8=./ant_8.bin   #CC2
-antC9=./ant_9.bin   #CC2
-antC10=./ant_10.bin #CC2
-antC11=./ant_11.bin #CC2
-antC12=./ant_12.bin #CC3
-antC13=./ant_13.bin #CC3
-antC14=./ant_14.bin #CC3
-antC15=./ant_15.bin #CC3
-
-## RACH TODO: update for PRACH
-#rachEanble=1 # Enable (1)| disable (0) PRACH configuration
-#rachOffset=43 # RB offset for prach detection (see RIU spec)
-#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
-
-## control of IQ byte order
-iqswap=0 #do swap of IQ before send buffer to eth
-nebyteorderswap=0 #do swap of byte order for each I and Q from CPU byte order to network byte order
-
-##Debug
-debugStop=0 #stop app on 1pps boundary (gps_second % 30)
-
-CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
-c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
-u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
-
-##RU Settings
-Tadv_cp_dl=25 #in us  TODO: update per RU implementation
-              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
-
-#Reception Window C-plane DL
-T2a_min_cp_dl=50 #in us  TODO: update per RU implementation
-T2a_max_cp_dl=140 #in us  TODO: update per RU implementation
-
-#Reception Window C-plane UL
-T2a_min_cp_ul=50 #in us  TODO: update per RU implementation
-T2a_max_cp_ul=140 #in us  TODO: update per RU implementation
-
-#Reception Window U-plane
-T2a_min_up=25 #in us
-T2a_max_up=140 #in us
-
-#Transmission Window
-Ta3_min=20 #in us
-Ta3_max=32 #in us
-
-###########################################################
-##lls-CU Settings
-#C-plane
-#Transmission Window Fast C-plane DL
-T1a_min_cp_dl=70
-T1a_max_cp_dl=100
-
-##Transmission Window Fast C-plane UL
-T1a_min_cp_ul=70
-T1a_max_cp_ul=80
-
-#U-plane
-##Transmission Window
-T1a_min_up=35
-T1a_max_up=50
-
-#Reception Window
-Ta4_min=0
-Ta4_max=45
-###########################################################
-
diff --git a/fhi_lib/app/config_file_ru.dat b/fhi_lib/app/config_file_ru.dat
deleted file mode 100644 (file)
index d1edf90..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#######################################################################
-#
-# <COPYRIGHT_TAG>
-#
-#######################################################################
-
-# This is simple configuration file. Use '#' sign for comments
-appMode=1 # lls-CU(0) | RU(1)
-xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
-ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
-##Numerology
-mu=3 #mmWave 120Khz Sub Carrier Spacing
-antNum=4 # Number of Antennas per CC (default: 4)
-ttiPeriod=125 # in us TTI period (mmWave default 125us)
-llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
-#llsCUMac=3c:fd:fe:9e:93:68 # PF for tcpdump
-ruMac=00:11:22:33:44:55
-#56:1e:4b:0c:f5:9b # RU MAC
-antC0=./ant_0.bin   #CC0
-antC1=./ant_1.bin   #CC0
-antC2=./ant_2.bin   #CC0
-antC3=./ant_3.bin   #CC0
-antC4=./ant_4.bin   #CC1
-antC5=./ant_5.bin   #CC1
-antC6=./ant_6.bin   #CC1
-antC7=./ant_7.bin   #CC1
-antC8=./ant_8.bin   #CC2
-antC9=./ant_9.bin   #CC2
-antC10=./ant_10.bin #CC2
-antC11=./ant_11.bin #CC2
-antC12=./ant_12.bin #CC3
-antC13=./ant_13.bin #CC3
-antC14=./ant_14.bin #CC3
-antC15=./ant_15.bin #CC3
-
-## RACH TODO: update for PRACH
-#rachEanble=1 # Enable (1)| disable (0) PRACH configuration
-#rachOffset=43 # RB offset for prach detection (see RIU spec)
-#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
-
-## control of IQ byte order
-iqswap=0 #do swap of IQ before send buffer to eth
-nebyteorderswap=0 #do swap of byte order for each I and Q from CPU byte order to network byte order
-
-##Debug
-debugStop=0 #stop app on 1pps boundary (gps_second % 30)
-
-CPenable=0 #(1) C-Plane is enabled| 0 C-Plane is disabled
-c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
-u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
-
-##RU Settings
-Tadv_cp_dl=25 #in us  TODO: update per RU implementation
-              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
-
-#Reception Window C-plane DL
-T2a_min_cp_dl=50 #in us  TODO: update per RU implementation
-T2a_max_cp_dl=140 #in us  TODO: update per RU implementation
-
-#Reception Window C-plane UL
-T2a_min_cp_ul=50 #in us  TODO: update per RU implementation
-T2a_max_cp_ul=140 #in us  TODO: update per RU implementation
-
-#Reception Window U-plane
-T2a_min_up=25 #in us
-T2a_max_up=140 #in us
-
-#Transmission Window
-Ta3_min=20 #in us
-Ta3_max=32 #in us
-
-###########################################################
-##lls-CU Settings
-#C-plane
-#Transmission Window Fast C-plane DL
-T1a_min_cp_dl=70
-T1a_max_cp_dl=100
-
-##Transmission Window Fast C-plane UL
-T1a_min_cp_ul=70
-T1a_max_cp_ul=80
-
-#U-plane
-##Transmission Window
-T1a_min_up=35
-T1a_max_up=50
-
-#Reception Window
-Ta4_min=10
-Ta4_max=100
-###########################################################
-
index 96bb84f..5b267bd 100644 (file)
@@ -18,6 +18,7 @@
 #*
 #*******************************************************************************/
 
+
 export RTE_SDK=/home/turner/dpdk
 export RTE_TARGET=x86_64-native-linuxapp-icc
 
@@ -65,7 +66,57 @@ load_igb_uio_module()
     fi
 }
 
+#
+# Unloads VFIO modules.
+#
+remove_vfio_module()
+{
+       echo "Unloading any existing VFIO module"
+       /sbin/lsmod | grep -s vfio > /dev/null
+       if [ $? -eq 0 ] ; then
+               sudo /sbin/rmmod vfio-pci
+               sudo /sbin/rmmod vfio_iommu_type1
+               sudo /sbin/rmmod vfio
+       fi
+}
+
+#
+# Loads new vfio-pci (and vfio module if needed).
+#
+load_vfio_module()
+{
+       remove_vfio_module
+
+       VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
+
+       echo "Loading VFIO module"
+       /sbin/lsmod | grep -s vfio_pci > /dev/null
+       if [ $? -ne 0 ] ; then
+               if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
+                       sudo /sbin/modprobe vfio-pci
+               fi
+       fi
+
+       # make sure regular users can read /dev/vfio
+       echo "chmod /dev/vfio"
+       sudo chmod a+x /dev/vfio
+       if [ $? -ne 0 ] ; then
+               echo "FAIL"
+               quit
+       fi
+       echo "OK"
+
+       # check if /dev/vfio/vfio exists - that way we
+       # know we either loaded the module, or it was
+       # compiled into the kernel
+       if [ ! -e /dev/vfio/vfio ] ; then
+               echo "## ERROR: VFIO not found!"
+       fi
+}
+
+
 load_igb_uio_module
+load_vfio_module
 
 CPU_FEATURES_DETECT=`cat /proc/cpuinfo |grep hypervisor | wc -l`
 
@@ -81,10 +132,13 @@ fi
 $RTE_SDK/usertools/dpdk-devbind.py --status
 if [ ${VM_DETECT} == 'HOST' ]; then
     #HOST
-    $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:d8:02.0
-    $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:d8:02.1
-    $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:07:02.0
-    $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:07:02.1
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:86:02.0
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:86:02.1
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:d8:02.0 
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:d8:02.1 
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.0 
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.1
+
 else
     #VM
     $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:00:04.0
index b93736c..d8bd859 100644 (file)
 %*
 %*******************************************************************************/
 
-%Matlab: read bin
-%fileID_c = fopen('ant_7.bin','r');
-%ant7_c= fread(fileID_c, [2, 792*14*80], 'integer*2');
-%ant7_c;
-%ant7_c=ant7_c.';
-
 close all;
 clear all;
 
-ifft_in = load('ifft_in.txt')
+%select mu and bw to generate test files
+sub6=false;  %false
+mu=3; % 0,1, or 3
+bw=100; %5,10,20,100 MHz
+
+nSlots=160; % any 40 and 160
+
+     %  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
+nNumRbsPerSymF1 = ...
+[
+     %  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
+        [25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0]         % Numerology 0 (15KHz)
+        [11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273]         % Numerology 1 (30KHz)
+        [0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135]         % Numerology 2 (60KHz)
+];
+
+nNumRbsPerSymF2 = ...
+[
+    %  50Mhz  100MHz  200MHz   400MHz
+        [66,    132,    264,     0]        % Numerology 2 (60KHz)
+        [32,    66,     132,     264]      % Numerology 3 (120KHz)
+];
+
+if sub6
+    disp('Sub6')
+    if mu < 3
+        nNumerology = mu+1;
+        switch (bw)
+            case {5}
+                numRBs = nNumRbsPerSymF1(nNumerology,0+1);
+            case {10}
+                numRBs = nNumRbsPerSymF1(nNumerology,1+1);
+            case {15}
+                numRBs = nNumRbsPerSymF1(nNumerology,2+1);
+            case {20}
+                numRBs = nNumRbsPerSymF1(nNumerology,3+1);
+            case {25}
+                numRBs = nNumRbsPerSymF1(nNumerology,4+1);
+            case {30}
+                numRBs = nNumRbsPerSymF1(nNumerology,5+1);
+            case {40}
+                numRBs = nNumRbsPerSymF1(nNumerology,6+1);
+            case {50}
+                numRBs = nNumRbsPerSymF1(nNumerology,7+1);
+            case {60}
+                numRBs = nNumRbsPerSymF1(nNumerology,8+1);
+            case {70}
+                numRBs = nNumRbsPerSymF1(nNumerology,9+1);
+            case {80}
+                numRBs = nNumRbsPerSymF1(nNumerology,10+1);
+            case {90}
+                numRBs = nNumRbsPerSymF1(nNumerology,11+1);
+            case {100}
+                numRBs = nNumRbsPerSymF1(nNumerology,12+1);
+            otherwise
+                disp('Unknown BW && mu')
+        end
+    end
+else
+    disp('mmWave')
+    if  (mu >=2) && (mu <= 3)
+        nNumerology = mu;
+        switch (bw)
+            case {50}
+                numRBs = nNumRbsPerSymF2(nNumerology-1,0+1);
+            case {100}
+                numRBs = nNumRbsPerSymF2(nNumerology-1,1+1);
+            case {200}
+                numRBs = nNumRbsPerSymF2(nNumerology-1,2+1);
+            case {400}
+                numRBs = nNumRbsPerSymF2(nNumerology-1,3+1);
+            otherwise
+                disp('Unknown BW && mu')
+        end
+    end
+end
+
+if numRBs ==0
+    disp('Incorrect Numerology and BW combination.')
+    return
+end
+
+bw
+numRBs
+nSlots
+
+%use file as input
+%ifft_in = load('ifft_in.txt')
+
+%gen IQs
+ifft_in = [[1:1:(numRBs*12)]', [1:1:(numRBs*12)]'];
+
 ant_c = ifft_in;
-for (i=1:1:80*14-1)
-    ant_c = [ant_c; ifft_in];
+for (i=1:1:nSlots*14-1)
+    ifft_in_1 = ifft_in + i;
+    ant_c = [ant_c; ifft_in_1];
 end
 
 ant0=ant_c;
diff --git a/fhi_lib/app/ifft_in.txt b/fhi_lib/app/ifft_in.txt
new file mode 100644 (file)
index 0000000..bca8a2f
--- /dev/null
@@ -0,0 +1,792 @@
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,0
+19,-1
+19,-1
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,2
+20,1
+20,1
+20,1
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,4
+21,4
+22,4
+21,3
+21,3
+21,4
+21,4
+21,4
+21,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+23,5
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+24,7
+24,7
+24,7
+24,7
+24,7
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,11
+25,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+27,12
+27,12
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+28,14
+28,14
+28,14
+28,14
+28,14
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,16
+28,16
+28,16
+28,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,17
+29,17
+28,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,19
+30,18
+30,19
+30,19
+30,19
+30,19
+30,19
+31,19
+31,19
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,21
+31,21
+31,21
+31,21
+32,21
+31,21
+32,21
+32,21
+32,21
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,23
+32,23
+32,23
+33,23
+33,23
+33,23
+33,23
+33,23
+33,24
+34,24
+33,24
+33,24
+33,24
+33,24
+33,24
+33,24
+34,25
+34,25
+34,25
+34,25
+34,25
+34,25
+34,25
+34,26
+34,26
+34,26
+34,26
+34,26
+35,26
+35,26
+35,26
+35,27
+35,27
+35,27
+35,27
+35,27
+35,28
+35,28
+35,28
+36,28
+36,28
+36,28
+36,29
+36,29
+36,29
+36,29
+36,29
+36,29
+36,30
+36,30
+37,30
+37,30
+37,30
+37,30
+37,31
+37,31
+37,31
+37,31
+37,31
+38,32
+38,32
+38,32
+38,32
+38,32
+38,33
+38,33
+38,33
+38,33
+39,33
+39,34
+39,34
+39,34
+39,34
+39,34
+39,35
+39,35
+40,35
+40,35
+40,35
+40,36
+40,36
+40,36
+40,36
+41,37
+41,37
+41,37
+41,37
+41,38
+41,38
+41,38
+41,38
+42,39
+42,39
+42,39
+42,40
+42,39
+42,40
+43,40
+43,40
+43,41
+43,41
+43,41
+43,42
+44,42
+44,42
+44,42
+44,43
+44,43
+44,43
+45,44
+45,44
+45,44
+45,45
+45,45
+45,45
+46,46
+46,46
+46,46
+46,47
+46,47
+47,47
+47,48
+47,48
+47,48
+47,49
+48,49
+48,49
+48,50
+48,50
+49,51
+49,51
+49,51
+49,52
+49,52
+50,53
+50,53
+50,53
+50,54
+51,54
+51,55
+51,55
+51,56
+52,56
+52,57
+52,57
+53,57
+53,58
+53,58
+53,59
+54,59
+54,60
+54,61
+55,61
+55,62
+56,63
+56,63
+56,64
+57,64
+57,65
+57,66
+58,66
+58,67
+58,67
+59,68
+59,69
+59,69
+60,70
+60,71
+61,71
+61,72
+61,73
+62,74
+62,74
+63,75
+63,76
+64,77
+64,77
+64,78
+65,79
+65,80
+66,81
+66,82
+67,82
+67,83
+68,84
+69,85
+69,86
+70,87
+70,88
+71,89
+71,90
+72,91
+73,92
+73,93
+74,95
+75,96
+75,97
+76,98
+77,99
+77,101
+78,102
+79,103
+80,105
+80,106
+81,107
+82,109
+83,110
+84,112
+85,113
+86,115
+87,117
+88,118
+89,120
+90,122
+91,124
+92,126
+93,128
+94,130
+95,132
+97,134
+98,136
+99,138
+100,140
+102,143
+103,145
+105,148
+106,151
+108,153
+110,156
+111,159
+113,162
+115,165
+117,169
+119,172
+121,176
+123,179
+125,183
+127,187
+130,191
+132,195
+135,200
+138,205
+140,210
+143,215
+146,220
+150,226
+153,232
+157,238
+161,245
+165,252
+169,259
+173,267
+178,275
+183,284
+189,293
+194,303
+201,314
+207,325
+214,337
+222,351
+230,365
+239,380
+248,397
+259,415
+271,435
+283,457
+297,481
+312,507
+330,537
+349,571
+371,608
+395,651
+424,701
+457,758
+496,826
+543,907
+600,1005
+670,1127
+759,1281
+877,1485
+1038,1765
+1275,2175
+1653,2829
+2355,4046
+4111,7086
+16399,28370
+-8177,-14197
+-3262,-5684
+-2033,-3556
+-1475,-2588
+-1156,-2035
+-949,-1678
+-805,-1427
+-698,-1242
+-616,-1100
+-550,-987
+-497,-895
+-454,-819
+-417,-755
+-385,-700
+-358,-653
+-334,-612
+-313,-576
+-295,-544
+-278,-515
+-263,-489
+-250,-466
+-238,-444
+-226,-425
+-216,-408
+-207,-392
+-198,-377
+-190,-363
+-183,-350
+-176,-338
+-169,-327
+-163,-317
+-158,-307
+-153,-298
+-148,-289
+-143,-281
+-138,-273
+-134,-266
+-130,-259
+-127,-253
+-123,-247
+-120,-241
+-116,-235
+-113,-230
+-110,-225
+-108,-220
+-105,-215
+-102,-211
+-100,-206
+-98,-202
+-95,-198
+-93,-195
+-91,-191
+-89,-188
+-87,-184
+-85,-181
+-83,-178
+-82,-175
+-80,-172
+-78,-169
\ No newline at end of file
diff --git a/fhi_lib/app/lls-cu/Makefile b/fhi_lib/app/lls-cu/Makefile
deleted file mode 100644 (file)
index 86aa9cc..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#/******************************************************************************
-#*
-#*   Copyright (c) 2019 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.
-#*
-#*******************************************************************************/
-CC := icc
-
-ifeq ($(RTE_SDK),)
-    $(error "Please define RTE_SDK environment variable")
-endif
-
-RTE_TARGET := x86_64-native-linuxapp-icc
-RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-
-ifeq ($(XRAN_DIR),)
-    XRAN_DIR=$(PWD)/../..
-endif
-
-COMMON_SRC=$(XRAN_DIR)/app/common
-SRC_SRC=$(XRAN_DIR)/app/src
-
-ifeq ($(MLOG_DIR),)
-    MLOG_DIR=$(XRAN_DIR)/../mlog
-endif
-
-APP = sample-lls-cu
-SRC = $(COMMON_SRC)/common.c \
-       ./sample-lls-cu.c \
-       $(SRC_SRC)/config.c 
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wextra -Werror -I$(XRAN_DIR)/lib/api -I$(COMMON_SRC) -I$(SRC_SRC) -I$(MLOG_DIR)/source -I$(RTE_INC)
-ifeq ($(ME),1)
-    CFLAGS += -DMLOG_ENABLED
-endif
-ifeq ($(NB),1)
-    CFLAGS += -DNightly_build
-endif
-
-ifeq ($(DEBUG),1)
-    CFLAGS += -DDEBUG -O0 -g
-else
-    CFLAGS += -O3
-endif
-
-ifeq ($(MULTI_SECTION),1)
-    CFLAGS += -DMULTI_SECTION
-endif
-
-LDFLAGS += -pthread -lrt
-
-RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
-
-XRAN_LIB_DIR=$(XRAN_DIR)/lib/bin
-LDFLAGS += -L$(XRAN_LIB_DIR) -Wl, -lxran -Wl, -L$(MLOG_DIR)/bin -Wl, $(RTE_LIBS)
-ifeq ($(ME),1)
-    LDFLAGS += -Wl,-lmlog
-endif
-
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
-
-
-all: $(APP) install
-       
-$(OBJ): %.o: %.c
-       $(CC) $(CFLAGS) -c $< -o $@ 
-
-$(APP): $(OBJ)
-       $(CC) -o $(APP) $(CFLAGS) $(OBJ)  $(LDFLAGS)
-
-install: $(APP)
-       @mkdir -p bin
-       @cp $(APP) ./bin
-
-clean:
-       @rm -rf $(APP) $(OBJ) ./bin/$(APP)
-
-#include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/fhi_lib/app/ru/Makefile b/fhi_lib/app/ru/Makefile
deleted file mode 100644 (file)
index 29ac054..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#/******************************************************************************
-#*
-#*   Copyright (c) 2019 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.
-#*
-#*******************************************************************************/
-CC := icc
-
-ifeq ($(RTE_SDK),)
-    $(error "Please define RTE_SDK environment variable")
-endif
-
-RTE_TARGET := x86_64-native-linuxapp-icc
-RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-
-ifeq ($(XRAN_DIR),)
-    XRAN_DIR=$(PWD)/../..
-endif
-
-COMMON_SRC=$(XRAN_DIR)/app/common
-SRC_SRC=$(XRAN_DIR)/app/src
-
-ifeq ($(MLOG_DIR),)
-    MLOG_DIR=$(XRAN_DIR)/../mlog
-endif
-APP = sample-ru
-SRC = $(COMMON_SRC)/common.c \
-       ../lls-cu/sample-lls-cu.c \
-       $(SRC_SRC)/config.c 
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wextra -Werror -I$(XRAN_DIR)/lib/api -I$(COMMON_SRC) -I$(SRC_SRC) -I$(MLOG_DIR)/source -I$(RTE_INC)
-ifeq ($(ME),1)
-    CFLAGS += -DMLOG_ENABLED
-endif
-
-ifeq ($(DEBUG),1)
-    CFLAGS += -DDEBUG -O0 -g
-else
-    CFLAGS += -O3
-endif
-
-ifeq ($(MULTI_SECTION),1)
-    CFLAGS += -DMULTI_SECTION
-endif
-
-LDFLAGS += -pthread -lrt
-
-RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
-
-XRAN_LIB_DIR=$(XRAN_DIR)/lib/bin
-LDFLAGS += -L$(XRAN_LIB_DIR) -Wl, -lxran -Wl, -L$(MLOG_DIR)/bin -Wl, $(RTE_LIBS)
-ifeq ($(ME),1)
-    LDFLAGS += -Wl,-lmlog
-endif
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
-
-
-all: $(APP) install
-       
-$(OBJ): %.o: %.c
-       $(CC) $(CFLAGS) -c $< -o $@ 
-
-$(APP): $(OBJ)
-       $(CC) -o $(APP) $(CFLAGS) $(OBJ)  $(LDFLAGS)
-
-install: $(APP)
-       @mkdir -p bin
-       @cp $(APP) ./bin
-
-clean:
-       @rm -rf $(APP) $(OBJ) ./bin/$(APP)
-
-#include $(RTE_SDK)/mk/rte.extapp.mk
similarity index 85%
rename from fhi_lib/app/run_lls-cu.sh
rename to fhi_lib/app/run_o_du.sh
index cec7e5b..4f6813c 100644 (file)
@@ -18,7 +18,6 @@
 #*
 #*******************************************************************************/
 
-
 ulimit -c unlimited
 echo 1 > /proc/sys/kernel/core_uses_pid
 
@@ -29,7 +28,11 @@ if ! mount | grep $huge_folder; then
  mount none $huge_folder -t hugetlbfs -o rw,mode=0777
 fi
 
-./lls-cu/bin/sample-lls-cu config_file_lls_cu.dat  0000:18:02.0 0000:18:02.1
+#40G
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat  0000:d8:02.0 0000:d8:02.1
+
+#25G
+#./build/sample-app ./usecase/mu0_10mhz/12/config_file_o_du.dat  0000:af:02.0 0000:af:02.1
 
 umount $huge_folder
 rmdir $huge_folder
similarity index 92%
rename from fhi_lib/app/run_ru.sh
rename to fhi_lib/app/run_o_ru.sh
index e84bc0a..e9204f5 100644 (file)
@@ -28,7 +28,8 @@ if ! mount | grep $huge_folder; then
  mount none $huge_folder -t hugetlbfs -o rw,mode=0777
 fi
 
-./ru/bin/sample-ru config_file_ru.dat 0000:18:02.0 0000:18:02.1
+#40G
+./build/sample-app ./usecase/mu1_100mhz/config_file_o_ru.dat 0000:d8:02.0 0000:d8:02.1
 
 umount $huge_folder
 rmdir $huge_folder
diff --git a/fhi_lib/app/src/common.c b/fhi_lib/app/src/common.c
new file mode 100644 (file)
index 0000000..d9b5d0c
--- /dev/null
@@ -0,0 +1,668 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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.
+*
+*******************************************************************************/
+
+
+#include <assert.h>
+#include <err.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "common.h"
+#include "xran_fh_o_du.h"
+#include "xran_pkt.h"
+#include "xran_pkt_up.h"
+#include "xran_cp_api.h"
+#include "xran_up_api.h"
+
+#include "xran_mlog_lnx.h"
+
+extern enum app_state state;
+
+int iq_playback_buffer_size_dl = IQ_PLAYBACK_BUFFER_BYTES;
+int iq_playback_buffer_size_ul = IQ_PLAYBACK_BUFFER_BYTES;
+
+uint8_t numCCPorts = 1;
+/* Number of antennas supported by front-end */
+
+uint8_t num_eAxc = 4;
+/* Number of CPRI ports supported by front-end */
+
+int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_tx_prach_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_prach_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_prach_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_prach_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t prach_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t prach_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_tx_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_rx_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+
+
+// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+uint16_t nNumRbsPerSymF1[3][13] =
+{
+    //  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
+        {25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0},         // Numerology 0 (15KHz)
+        {11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273},         // Numerology 1 (30KHz)
+        {0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135}          // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+uint16_t nNumRbsPerSymF2[2][4] =
+{
+    //  50Mhz  100MHz  200MHz   400MHz
+        {66,    132,    264,     0},        // Numerology 2 (60KHz)
+        {32,    66,     132,     264}       // Numerology 3 (120KHz)
+};
+
+// 38.211 - Table 4.2.1
+uint16_t nSubCarrierSpacing[5] =
+{
+    15,     // mu = 0
+    30,     // mu = 1
+    60,     // mu = 2
+    120,    // mu = 3
+    240     // mu = 4
+};
+
+// TTI interval in us (slot duration)
+uint16_t nTtiInterval[4] =
+{
+    1000,     // mu = 0
+    500,     // mu = 1
+    250,     // mu = 2
+    125,     // mu = 3
+};
+
+
+// F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
+uint16_t nCpSizeF1[3][13][2] =
+{
+    //    5MHz      10MHz      15MHz       20 MHz      25 MHz     30 MHz      40 MHz       50MHz       60 MHz      70 MHz     80 MHz     90 MHz     100 MHz
+        {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288},     {0, 0},     {0, 0},     {0, 0},     {0, 0},     {0, 0}},        // Numerology 0 (15KHz)
+        {{22, 18}, {44, 36},   {66, 54},   {88, 72},   {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}},       // Numerology 1 (30KHz)
+        {  {0, 0}, {26, 18},   {39, 27},   {52, 36},   {52, 36},   {78, 54},  {104, 72},  {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}},       // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
+int16_t nCpSizeF2[2][4][2] =
+{
+    //    50Mhz    100MHz      200MHz     400MHz
+        {  {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
+        {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
+};
+
+uint32_t gMaxSlotNum;
+uint32_t gNumDLCtx;
+uint32_t gNumULCtx;
+uint32_t gDLResetAdvance;
+uint32_t gDLProcAdvance;
+uint32_t gULProcAdvance;
+
+static uint16_t g_NumSlotTDDLoop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
+static uint16_t g_NumDLSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint16_t g_NumULSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint8_t g_SlotType[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
+float g_UlRate[XRAN_MAX_SECTOR_NR] = {0.0};
+float g_DlRate[XRAN_MAX_SECTOR_NR] = {0.0};
+
+uint32_t app_xran_get_tti_interval(uint8_t nMu)
+{
+    if (nMu < 4)
+    {
+        return nTtiInterval[nMu];
+    }
+    else
+    {
+        printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+    }
+
+    return 0;
+}
+
+uint32_t app_xran_get_scs(uint8_t nMu)
+{
+    if (nMu <= 3)
+    {
+        return nSubCarrierSpacing[nMu];
+    }
+    else
+    {
+        printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+    }
+
+    return 0;
+}
+
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ *  @param[in]   nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz,  1: 30khz,  2: 60khz 3: 120khz, 4: 240khz
+ *  @param[in]   nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ *  @param[in]   nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ *  @return  Number of RBs in cell
+ *
+ *  @description
+ *  Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t app_xran_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
+{
+    uint32_t error = 1;
+    uint16_t numRBs = 0;
+
+    if (nAbsFrePointA <= 6000000)
+    {
+        // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+        if (nNumerology < 3)
+        {
+            switch(nBandwidth)
+            {
+                case PHY_BW_5_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][0];
+                    error = 0;
+                break;
+                case PHY_BW_10_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][1];
+                    error = 0;
+                break;
+                case PHY_BW_15_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][2];
+                    error = 0;
+                break;
+                case PHY_BW_20_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][3];
+                    error = 0;
+                break;
+                case PHY_BW_25_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][4];
+                    error = 0;
+                break;
+                case PHY_BW_30_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][5];
+                    error = 0;
+                break;
+                case PHY_BW_40_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][6];
+                    error = 0;
+                break;
+                case PHY_BW_50_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][7];
+                    error = 0;
+                break;
+                case PHY_BW_60_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][8];
+                    error = 0;
+                break;
+                case PHY_BW_70_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][9];
+                    error = 0;
+                break;
+                case PHY_BW_80_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][10];
+                    error = 0;
+                break;
+                case PHY_BW_90_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][11];
+                    error = 0;
+                break;
+                case PHY_BW_100_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][12];
+                    error = 0;
+                break;
+                default:
+                    error = 1;
+                break;
+            }
+        }
+    }
+    else
+    {
+        if ((nNumerology >= 2) && (nNumerology <= 3))
+        {
+            // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+            switch(nBandwidth)
+            {
+                case PHY_BW_50_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][0];
+                    error = 0;
+                break;
+                case PHY_BW_100_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][1];
+                    error = 0;
+                break;
+                case PHY_BW_200_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][2];
+                    error = 0;
+                break;
+                case PHY_BW_400_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][3];
+                    error = 0;
+                break;
+                default:
+                    error = 1;
+                break;
+            }
+        }
+    }
+
+
+    if (error)
+    {
+        printf("ERROR: %s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA);
+    }
+    else
+    {
+        printf("%s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA, numRBs);
+    }
+
+    return numRBs;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ *  @param[in]   center frequency
+ *
+ *  @return  NR-ARFCN
+ *
+ *  @description
+ *  This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq)
+{
+    uint32_t nDeltaFglobal,nFoffs,nNoffs;
+    uint32_t nNRARFCN = 0;
+
+    if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
+    {
+        nDeltaFglobal = 5;
+        nFoffs = 0;
+        nNoffs = 0;
+    }
+    else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
+    {
+        nDeltaFglobal = 15;
+        nFoffs = 3000*1000;
+        nNoffs = 600000;
+    }
+    else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
+    {
+        nDeltaFglobal = 60;
+        nFoffs = 24250080;
+        nNoffs = 2016667;
+    }
+    else
+    {
+         printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
+         return (0);
+    }
+
+    nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
+
+    printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
+    return (nNRARFCN);
+}
+
+int32_t app_xran_slot_limit(int32_t nSfIdx)
+{
+    while (nSfIdx < 0) {
+        nSfIdx += gMaxSlotNum;
+    }
+
+    while (nSfIdx >= gMaxSlotNum) {
+        nSfIdx -= gMaxSlotNum;
+    }
+
+    return nSfIdx;
+}
+
+void app_xran_clear_slot_type(uint32_t nPhyInstanceId)
+{
+    g_UlRate[nPhyInstanceId] = 0.0;
+    g_DlRate[nPhyInstanceId] = 0.0;
+    g_NumSlotTDDLoop[nPhyInstanceId] = 1;
+}
+
+int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig)
+{
+    uint32_t nSlotNum, nSymNum, nVal, i;
+    uint32_t numDlSym, numUlSym, numGuardSym;
+    uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
+    char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
+
+    // nPhyInstanceId    Carrier ID
+    // nFrameDuplexType  0 = FDD 1 = TDD
+    // nTddPeriod        Tdd Periodicity
+    // psSlotConfig[80]  Slot Config Structure for nTddPeriod Slots
+
+    g_UlRate[nPhyInstanceId] = 0.0;
+    g_DlRate[nPhyInstanceId] = 0.0;
+    g_NumSlotTDDLoop[nPhyInstanceId] = nTddPeriod;
+
+    for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+    {
+        g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
+        g_NumDLSymSp[nPhyInstanceId][i] = 0;
+        g_NumULSymSp[nPhyInstanceId][i] = 0;
+    }
+
+    if (nFrameDuplexType == XRAN_FDD)
+    {
+        for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+        {
+            g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
+        }
+        g_NumSlotTDDLoop[nPhyInstanceId] = 1;
+        g_DlRate[nPhyInstanceId] = 1.0;
+        g_UlRate[nPhyInstanceId] = 1.0;
+    }
+    else
+    {
+        for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
+        {
+            numDlSym = 0;
+            numUlSym = 0;
+            numGuardSym = 0;
+            for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
+            {
+                switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
+                {
+                    case XRAN_SYMBOL_TYPE_DL:
+                        numDlSym++;
+                    break;
+                    case XRAN_SYMBOL_TYPE_GUARD:
+                        numGuardSym++;
+                    break;
+                    default:
+                        numUlSym++;
+                    break;
+                }
+            }
+
+            // printf("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d]\n", nSlotNum, numDlSym, numGuardSym, numUlSym);
+
+            if ((numUlSym == 0) && (numGuardSym == 0))
+            {
+                g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
+                numDlSlots++;
+            }
+            else if ((numDlSym == 0) && (numGuardSym == 0))
+            {
+                g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
+                numUlSlots++;
+            }
+            else
+            {
+                g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
+                numSpSlots++;
+
+                if (numDlSym)
+                {
+                    numSpDlSlots++;
+                    g_NumDLSymSp[nPhyInstanceId][nSlotNum] = numDlSym;
+                }
+                if (numUlSym)
+                {
+                    numSpUlSlots++;
+                    g_NumULSymSp[nPhyInstanceId][nSlotNum] = numUlSym;
+                }
+            }
+
+            // printf("            numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
+        }
+
+        g_DlRate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
+        g_UlRate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
+    }
+
+    printf("set_slot_type: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
+        nPhyInstanceId, nFrameDuplexType, nTddPeriod);
+
+    printf("DLRate[%f] ULRate[%f]\n", g_DlRate[nPhyInstanceId], g_UlRate[nPhyInstanceId]);
+
+    nVal = (g_NumSlotTDDLoop[nPhyInstanceId] < 10) ? g_NumSlotTDDLoop[nPhyInstanceId] : 10;
+
+    printf("SlotPattern:\n");
+    printf("Slot:   ");
+    for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
+    {
+        printf("%d    ", nSlotNum);
+    }
+    printf("\n");
+
+    printf("  %3d   ", 0);
+    for (nSlotNum = 0, i = 0; nSlotNum < g_NumSlotTDDLoop[nPhyInstanceId]; nSlotNum++)
+    {
+        printf("%s   ", sSlotPattern[g_SlotType[nPhyInstanceId][nSlotNum]]);
+        i++;
+        if ((i == 10) && ((nSlotNum+1) < g_NumSlotTDDLoop[nPhyInstanceId]))
+        {
+            printf("\n");
+            printf("  %3d   ", nSlotNum);
+            i = 0;
+        }
+    }
+    printf("\n\n");
+
+    return 0;
+}
+
+int32_t app_xran_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
+{
+    int32_t nSfIdxMod, nSfType, ret = 0;
+
+    nSfIdxMod = app_xran_slot_limit(nSlotdx) % ((g_NumSlotTDDLoop[nCellIdx] > 0) ? g_NumSlotTDDLoop[nCellIdx]: 1);
+    nSfType = g_SlotType[nCellIdx][nSfIdxMod];
+
+    if (nSfType == nType)
+    {
+        ret = 1;
+    }
+    else if (nSfType == XRAN_SLOT_TYPE_SP)
+    {
+        if ((nType == XRAN_SLOT_TYPE_DL) && g_NumDLSymSp[nCellIdx][nSfIdxMod])
+        {
+            ret = 1;
+        }
+
+        if ((nType == XRAN_SLOT_TYPE_UL) && g_NumULSymSp[nCellIdx][nSfIdxMod])
+        {
+            ret = 1;
+        }
+    }
+    else if (nSfType == XRAN_SLOT_TYPE_FDD)
+    {
+        ret = 1;
+    }
+
+    return ret;
+}
+
+
+
+void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+    if (size)
+    {
+        if (filename && bufname)
+        {
+            FILE           *file;
+            printf("Storing %s to file %s: ", bufname, filename);
+            file = fopen(filename, "wb");
+            if (file == NULL)
+            {
+                printf("can't open file %s!!!", filename);
+            }
+            else
+            {
+                uint32_t             num;
+                num = fwrite(pBuffer, buffers_num, size, file);
+                fflush(file);
+                fclose(file);
+                printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
+            }
+            printf(" \n");
+        }
+        else
+        {
+            printf(" the file name, buffer name are not set!!!");
+        }
+    }
+    else
+    {
+        printf(" the %s is free: size = %d bytes!!!", bufname, size);
+    }
+}
+
+int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+    unsigned int  file_size = 0;
+    int  num= 0;
+
+    if (size)
+    {
+        if (filename && bufname)
+        {
+            FILE           *file;
+            printf("Loading file %s to  %s: ", filename, bufname);
+            file = fopen(filename, "rb");
+
+
+            if (file == NULL)
+            {
+                printf("can't open file %s!!!", filename);
+                exit(-1);
+            }
+            else
+            {
+                fseek(file, 0, SEEK_END);
+                file_size = ftell(file);
+                fseek(file, 0, SEEK_SET);
+
+                if ((file_size > size) || (file_size == 0))
+                    file_size = size;
+
+                printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
+
+                num = fread(pBuffer, buffers_num, size, file);
+                fflush(file);
+                fclose(file);
+                printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
+            }
+            printf(" \n");
+
+        }
+        else
+        {
+            printf(" the file name, buffer name are not set!!!");
+        }
+    }
+    else
+    {
+        printf(" the %s is free: size = %d bytes!!!", bufname, size);
+    }
+    return num;
+}
+
+
+void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+    unsigned int i;
+    int ret = 0;
+    if (pBuffer == NULL)
+        return;
+
+    if (size)
+    {
+        if (filename && bufname)
+        {
+            FILE           *file;
+            printf("Storing %s to file %s: ", bufname, filename);
+            file = fopen(filename, "w");
+            if (file == NULL)
+            {
+                printf("can't open file %s!!!", filename);
+                exit(-1);
+            }
+            else
+            {
+                uint32_t num = 0;
+
+                signed short *ptr = (signed short*)pBuffer;
+                for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
+                {
+#ifndef CSCOPE_DEBUG
+                    ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
+#else
+                    ret = fprintf(file,"%d %d ", ptr[i], ptr[i + 1]);
+                    /*      I data => Ramp data, from 1 to 792.
+                            Q data => Contains time information of the current symbol:
+                            Bits [15:14] = Antenna-ID
+                            Bits [13:12] = \9300\94
+                            Bits [11:8]  = Subframe-ID
+                            Bits [7:4]   = Slot-ID
+                            Bits [3:0]   = Symbol-ID */
+                            fprintf(file, "0x%04x: ant %d Subframe-ID %d Slot-ID %d Symbol-ID %d\n",
+                                        ptr[i + 1], (ptr[i + 1]>>14) & 0x3,  (ptr[i + 1]>>8) & 0xF,  (ptr[i + 1]>>4) & 0xF, (ptr[i + 1]>>0) & 0xF);
+#endif
+                    if (ret < 0)
+                    {
+                        printf("fprintf %d\n", ret);
+                        fclose(file);
+                        break;
+                    }
+                    num++;
+                }
+                fflush(file);
+                fclose(file);
+                printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
+            }
+            printf(" \n");
+        }
+        else
+        {
+            printf(" the file name, buffer name are not set!!!");
+        }
+    }
+    else
+    {
+        printf(" the %s is free: size = %d bytes!!!", bufname, size);
+    }
+}
+
similarity index 61%
rename from fhi_lib/app/common/common.h
rename to fhi_lib/app/src/common.h
index fb4400d..8f9d406 100644 (file)
 *
 *******************************************************************************/
 
+
+#ifndef _XRAN_APP_COMMON_H_
+#define _XRAN_APP_COMMON_H_
+
 #include <stdio.h>
 #include <unistd.h>
 
+#include "xran_fh_o_du.h"
 #include "xran_pkt_up.h"
 
 #include <rte_common.h>
 #include <rte_mbuf.h>
 
-#define APP_LLS_CU 0
-#define APP_RU     1
+#define VERSIONX                "#DIRTY#"
+
+#define APP_O_DU  0
+#define APP_O_RU  1
 
 enum app_state
 {
@@ -33,19 +40,24 @@ enum app_state
     APP_STOPPED
 };
 
-#define NUM_OF_PRB_IN_FULL_BAND (66)
+enum nRChBwOptions
+{
+    PHY_BW_5_0_MHZ = 5,   PHY_BW_10_0_MHZ = 10, PHY_BW_15_0_MHZ = 15, PHY_BW_20_0_MHZ = 20, PHY_BW_25_0_MHZ = 25,
+    PHY_BW_30_0_MHZ = 30, PHY_BW_40_0_MHZ = 40, PHY_BW_50_0_MHZ = 50, PHY_BW_60_0_MHZ = 60, PHY_BW_70_0_MHZ = 70,
+    PHY_BW_80_0_MHZ = 80, PHY_BW_90_0_MHZ = 90, PHY_BW_100_0_MHZ = 100, PHY_BW_200_0_MHZ = 200, PHY_BW_400_0_MHZ = 400
+};
+
 #define N_SC_PER_PRB 12
 #define N_SYM_PER_SLOT 14
-#define N_FULLBAND_SC (NUM_OF_PRB_IN_FULL_BAND*N_SC_PER_PRB)
-#define MAX_ANT_CARRIER_SUPPORTED 16
-// 0.125, just for testing
-#define SLOTNUM_PER_SUBFRAME      8
+#define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR)
+
+#define SUBFRAME_DURATION_US       1000
+//#define SLOTNUM_PER_SUBFRAME       8
+
 #define SUBFRAMES_PER_SYSTEMFRAME  10
-#define PDSCH_PAYLOAD_SIZE (N_FULLBAND_SC*4)
-#define NUM_OF_SLOT_IN_TDD_LOOP         (80)
-#define IQ_PLAYBACK_BUFFER_BYTES (NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*N_FULLBAND_SC*4L)
-/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples. The payload length is 3356 octets.*/
-#define PRACH_PLAYBACK_BUFFER_BYTES (10*839*4L)
+#define IQ_PLAYBACK_BUFFER_BYTES (XRAN_NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*66*N_SC_PER_PRB*4L)
+/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples for long sequence or 144*14 (max) for short sequence. The payload length is 3356 octets.*/
+#define PRACH_PLAYBACK_BUFFER_BYTES (144*14*4L)
 
 #ifdef _DEBUG
 #define iAssert(p) if(!(p)){fprintf(stderr,\
@@ -55,19 +67,8 @@ enum app_state
 #define iAssert(p)
 #endif /* _DEBUG */
 
-struct send_symbol_cb_args
-{
-    struct rb_map *samp_buf;
-    uint8_t *symb_id;
-};
-
-struct pkt_dump
-{
-    int num_samp;
-    int num_bytes;
-    uint8_t symb;
-    struct ecpri_seq_id seq;
-} __rte_packed;
+extern int iq_playback_buffer_size_dl;
+extern int iq_playback_buffer_size_ul;
 
 extern uint8_t numCCPorts;
 /* Number of antennas supported by front-end */
@@ -78,6 +79,10 @@ extern int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
 extern int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
 extern int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
 
+extern int16_t *p_tx_prach_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+extern int32_t tx_prach_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+extern int32_t tx_prach_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
 /* Number of antennas supported by front-end */
 extern int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
 extern int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
@@ -96,4 +101,13 @@ extern int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
 void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
 void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
 int  sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
+uint32_t app_xran_get_scs(uint8_t nMu);
+uint16_t app_xran_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
+uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq);
+int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType,
+                uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig);
+uint32_t app_xran_get_tti_interval(uint8_t nMu);
+
+
 
+#endif /*_XRAN_APP_COMMON_H_*/
index 1564c8d..abe2b48 100644 (file)
 
 #include "rte_common.h"
 #include "config.h"
+#include "common.h"
+#include "debug.h"
 
 #include <rte_ethdev.h>
 
 #define MAX_LINE_SIZE 512
 /* Configuration file maximum supported line length */
 
-
 #define KEY_APP_MODE        "appMode"
 #define KEY_XRAN_MODE       "xranMode"
 #define KEY_MU_NUMBER       "mu"
+#define KEY_NDLABSFREPOINTA "nDLAbsFrePointA"
+#define KEY_NULABSFREPOINTA "nULAbsFrePointA"
+#define KEY_NDLBANDWIDTH    "nDLBandwidth"
+#define KEY_NULBANDWIDTH    "nULBandwidth"
+#define KEY_NDLFFTSIZE      "nDLFftSize"
+#define KEY_NULFFTSIZE      "nULFftSize"
+
+#define KEY_NFRAMEDUPLEXTYPE "nFrameDuplexType"
+#define KEY_NTDDPERIOD       "nTddPeriod"
+
+#define KEY_SSLOTCONFIG     "sSlotConfig"
+
 #define KEY_CC_PER_PORT_NUM "ccNum"
 #define KEY_ANT_NUM         "antNum"
 #define KEY_TTI_PERIOD      "ttiPeriod"
+
+#define KEY_MTU_SIZE        "MTUSize"
 #define KEY_LLS_CU_MAC      "llsCUMac"
 #define KEY_RU_MAC          "ruMac"
 
-#define KEY_FILE_AxC0      "antC0"
-#define KEY_FILE_AxC1      "antC1"
-#define KEY_FILE_AxC2      "antC2"
-#define KEY_FILE_AxC3      "antC3"
-#define KEY_FILE_AxC4      "antC4"
-#define KEY_FILE_AxC5      "antC5"
-#define KEY_FILE_AxC6      "antC6"
-#define KEY_FILE_AxC7      "antC7"
-#define KEY_FILE_AxC8      "antC8"
-#define KEY_FILE_AxC9      "antC9"
-#define KEY_FILE_AxC10     "antC10"
-#define KEY_FILE_AxC11     "antC11"
-#define KEY_FILE_AxC12     "antC12"
-#define KEY_FILE_AxC13     "antC13"
-#define KEY_FILE_AxC14     "antC14"
-#define KEY_FILE_AxC15     "antC15"
+#define KEY_FILE_NUMSLOTS   "numSlots"
+#define KEY_FILE_AxC        "antC"
+#define KEY_FILE_PRACH_AxC  "antPrachC"
+
 
 #define KEY_PRACH_ENABLE   "rachEanble"
-#define KEY_PRACH_OFFSET   "rachOffset"
-#define KEY_PRACH_CFG_IDX  "rachCfgIdx"
+#define KEY_PRACH_CFGIDX   "prachConfigIndex"
 
 #define KEY_IQ_SWAP        "iqswap"
 #define KEY_HTONS_SWAP     "nebyteorderswap"
@@ -89,6 +91,9 @@
 #define KEY_CP_VTAG        "c_plane_vlan_tag"
 #define KEY_UP_VTAG        "u_plane_vlan_tag"
 #define KEY_DEBUG_STOP     "debugStop"
+#define KEY_DEBUG_STOP_CNT     "debugStopCount"
+#define KEY_BBDEV_MODE     "bbdevMode"
+#define KEY_DYNA_SEC_ENA     "DynamicSectionEna"
 
 
 /**
@@ -123,6 +128,65 @@ static int fillConfigStruct(RuntimeConfig *config, const char *key, const char *
         config->numCC= atoi(value);
     } else if (strcmp(key, KEY_MU_NUMBER) == 0) {
         config->mu_number= atoi(value);
+        printf("mu_number: %d\n",config->mu_number);
+    } else if (strcmp(key, KEY_NDLABSFREPOINTA) == 0) {
+        config->nDLAbsFrePointA = atoi(value);
+        printf("nDLAbsFrePointA: %d\n",config->nDLAbsFrePointA);
+    } else if (strcmp(key, KEY_NULABSFREPOINTA) == 0) {
+        config->nULAbsFrePointA = atoi(value);
+        printf("nULAbsFrePointA: %d\n",config->nULAbsFrePointA);
+    } else if (strcmp(key, KEY_NDLBANDWIDTH) == 0) {
+        config->nDLBandwidth = atoi(value);
+        printf("nDLBandwidth: %d\n",config->nDLBandwidth);
+    } else if (strcmp(key, KEY_NULBANDWIDTH) == 0) {
+        config->nULBandwidth = atoi(value);
+        printf("nULBandwidth: %d\n",config->nULBandwidth);
+    } else if (strcmp(key, KEY_NDLFFTSIZE) == 0) {
+        config->nDLFftSize = atoi(value);
+        printf("nULFftSize: %d\n",config->nDLFftSize);
+    } else if (strcmp(key, KEY_NULFFTSIZE) == 0) {
+        config->nULFftSize = atoi(value);
+        printf("nULFftSize: %d\n",config->nULFftSize);
+    } else if (strcmp(key, KEY_NFRAMEDUPLEXTYPE) == 0) {
+        config->nFrameDuplexType = atoi(value);
+        printf("nFrameDuplexType: %d\n",config->nFrameDuplexType);
+    } else if (strcmp(key, KEY_NTDDPERIOD) == 0) {
+        config->nTddPeriod = atoi(value);
+        printf("nTddPeriod: %d\n",config->nTddPeriod);
+        if (config->nTddPeriod > XRAN_MAX_TDD_PERIODICITY)
+        {
+            printf("nTddPeriod is larger than max allowed, invalid!\n");
+            config->nTddPeriod = XRAN_MAX_TDD_PERIODICITY;
+        }
+    } else if (strncmp(key, KEY_SSLOTCONFIG, strlen(KEY_SSLOTCONFIG)) == 0) {
+        unsigned int slot_num = 0;
+        int i = 0;
+        sscanf(key,"sSlotConfig%u",&slot_num);
+        if (slot_num >= config->nTddPeriod){
+            printf("slot_num %d exceeds TddPeriod\n",slot_num);
+        }
+        else{
+            sscanf(value, "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[0],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[1],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[2],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[3],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[4],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[5],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[6],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[7],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[8],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[9],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[10],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[11],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[12],
+                                           (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[13]);
+            printf("sSlotConfig%d: ",slot_num);
+            for (i = 0; i< 14; i++){
+                printf("%d ",config->sSlotConfig[slot_num].nSymbolType[i]);
+            }
+            printf("\n");
+        }
     } else if (strcmp(key, KEY_ANT_NUM) == 0) {
         config->numAxc = atoi(value);
     } else if (strcmp(key, KEY_TTI_PERIOD) == 0) {
@@ -131,95 +195,71 @@ static int fillConfigStruct(RuntimeConfig *config, const char *key, const char *
         config->iqswap = atoi(value);
     } else if (strcmp(key, KEY_HTONS_SWAP) == 0) {
         config->nebyteorderswap = atoi(value);
+    } else if (strcmp(key, KEY_MTU_SIZE) == 0) {
+        config->mtu = atoi(value);
+        printf("mtu %d\n", config->mtu);
     } else if (strcmp(key, KEY_LLS_CU_MAC) == 0) {
-        sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->lls_cu_addr.addr_bytes[0],
-                                           (uint32_t*)&config->lls_cu_addr.addr_bytes[1],
-                                           (uint32_t*)&config->lls_cu_addr.addr_bytes[2],
-                                           (uint32_t*)&config->lls_cu_addr.addr_bytes[3],
-                                           (uint32_t*)&config->lls_cu_addr.addr_bytes[4],
-                                           (uint32_t*)&config->lls_cu_addr.addr_bytes[5]);
+        sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->o_du_addr.addr_bytes[0],
+                                           (uint32_t*)&config->o_du_addr.addr_bytes[1],
+                                           (uint32_t*)&config->o_du_addr.addr_bytes[2],
+                                           (uint32_t*)&config->o_du_addr.addr_bytes[3],
+                                           (uint32_t*)&config->o_du_addr.addr_bytes[4],
+                                           (uint32_t*)&config->o_du_addr.addr_bytes[5]);
 
         printf("lls-CU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
-            config->lls_cu_addr.addr_bytes[0],
-            config->lls_cu_addr.addr_bytes[1],
-            config->lls_cu_addr.addr_bytes[2],
-            config->lls_cu_addr.addr_bytes[3],
-            config->lls_cu_addr.addr_bytes[4],
-            config->lls_cu_addr.addr_bytes[5]);
+            config->o_du_addr.addr_bytes[0],
+            config->o_du_addr.addr_bytes[1],
+            config->o_du_addr.addr_bytes[2],
+            config->o_du_addr.addr_bytes[3],
+            config->o_du_addr.addr_bytes[4],
+            config->o_du_addr.addr_bytes[5]);
 
     } else if (strcmp(key, KEY_RU_MAC) == 0) {
-        sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->ru_addr.addr_bytes[0],
-                                           (uint32_t*)&config->ru_addr.addr_bytes[1],
-                                           (uint32_t*)&config->ru_addr.addr_bytes[2],
-                                           (uint32_t*)&config->ru_addr.addr_bytes[3],
-                                           (uint32_t*)&config->ru_addr.addr_bytes[4],
-                                           (uint32_t*)&config->ru_addr.addr_bytes[5]);
+        sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->o_ru_addr.addr_bytes[0],
+                                           (uint32_t*)&config->o_ru_addr.addr_bytes[1],
+                                           (uint32_t*)&config->o_ru_addr.addr_bytes[2],
+                                           (uint32_t*)&config->o_ru_addr.addr_bytes[3],
+                                           (uint32_t*)&config->o_ru_addr.addr_bytes[4],
+                                           (uint32_t*)&config->o_ru_addr.addr_bytes[5]);
 
         printf("RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
-            config->ru_addr.addr_bytes[0],
-            config->ru_addr.addr_bytes[1],
-            config->ru_addr.addr_bytes[2],
-            config->ru_addr.addr_bytes[3],
-            config->ru_addr.addr_bytes[4],
-            config->ru_addr.addr_bytes[5]);
-    } else if (strcmp(key, KEY_FILE_AxC0) == 0) {
-        strncpy(&config->ant_file[0][0], value, strlen(value));
-        printf("ant0: %s\n",config->ant_file[0]);
-    } else if (strcmp(key, KEY_FILE_AxC1) == 0) {
-        strncpy(&config->ant_file[1][0], value, strlen(value));
-        printf("ant1: %s\n",config->ant_file[1]);
-    } else if (strcmp(key, KEY_FILE_AxC2) == 0) {
-        strncpy(&config->ant_file[2][0], value, strlen(value));
-        printf("ant2: %s\n",config->ant_file[2]);
-    } else if (strcmp(key, KEY_FILE_AxC3) == 0) {
-        strncpy(&config->ant_file[3][0], value, strlen(value));
-        printf("ant3: %s\n",config->ant_file[3]);
-    } else if (strcmp(key, KEY_FILE_AxC4) == 0) {
-        strncpy(&config->ant_file[4][0], value, strlen(value));
-        printf("ant4: %s\n",config->ant_file[4]);
-    } else if (strcmp(key, KEY_FILE_AxC5) == 0) {
-        strncpy(&config->ant_file[5][0], value, strlen(value));
-        printf("ant5: %s\n",config->ant_file[5]);
-    } else if (strcmp(key, KEY_FILE_AxC6) == 0) {
-        strncpy(&config->ant_file[6][0], value, strlen(value));
-        printf("ant6: %s\n",config->ant_file[6]);
-    } else if (strcmp(key, KEY_FILE_AxC7) == 0) {
-        strncpy(&config->ant_file[7][0], value, strlen(value));
-        printf("ant7: %s\n",config->ant_file[7]);
-    } else if (strcmp(key, KEY_FILE_AxC8) == 0) {
-        strncpy(&config->ant_file[8][0], value, strlen(value));
-        printf("ant8: %s\n",config->ant_file[8]);
-    } else if (strcmp(key, KEY_FILE_AxC9) == 0) {
-        strncpy(&config->ant_file[9][0], value, strlen(value));
-        printf("ant9: %s\n",config->ant_file[9]);
-    } else if (strcmp(key, KEY_FILE_AxC10) == 0) {
-        strncpy(&config->ant_file[10][0], value, strlen(value));
-        printf("ant10: %s\n",config->ant_file[10]);
-    } else if (strcmp(key, KEY_FILE_AxC11) == 0) {
-        strncpy(&config->ant_file[11][0], value, strlen(value));
-        printf("ant11: %s\n",config->ant_file[11]);
-    } else if (strcmp(key, KEY_FILE_AxC12) == 0) {
-        strncpy(&config->ant_file[12][0], value, strlen(value));
-        printf("ant12: %s\n",config->ant_file[12]);
-    } else if (strcmp(key, KEY_FILE_AxC13) == 0) {
-        strncpy(&config->ant_file[13][0], value, strlen(value));
-        printf("ant13: %s\n",config->ant_file[13]);
-    } else if (strcmp(key, KEY_FILE_AxC14) == 0) {
-        strncpy(&config->ant_file[14][0], value, strlen(value));
-        printf("ant14: %s\n",config->ant_file[14]);
-    } else if (strcmp(key, KEY_FILE_AxC15) == 0) {
-        strncpy(&config->ant_file[15][0], value, strlen(value));
-        printf("ant15: %s\n",config->ant_file[15]);
+            config->o_ru_addr.addr_bytes[0],
+            config->o_ru_addr.addr_bytes[1],
+            config->o_ru_addr.addr_bytes[2],
+            config->o_ru_addr.addr_bytes[3],
+            config->o_ru_addr.addr_bytes[4],
+            config->o_ru_addr.addr_bytes[5]);
+    } else if (strcmp(key, KEY_FILE_NUMSLOTS) == 0) {
+        config->numSlots = atoi(value);
+        printf("numSlots: %d\n",config->numSlots);
+    }else if (strncmp(key, KEY_FILE_AxC, strlen(KEY_FILE_AxC)) == 0) {
+        unsigned int ant_num = 0;
+        sscanf(key,"antC%02u",&ant_num);
+        if (ant_num >= MAX_ANT_CARRIER_SUPPORTED)
+        {
+            printf("antC%d exceeds max antenna supported\n",ant_num);
+        }
+        else{
+            strncpy(&config->ant_file[ant_num][0], value, strlen(value));
+            printf("antC%d: %s\n",ant_num, config->ant_file[ant_num]);
+        }
     } else if (strcmp(key, KEY_PRACH_ENABLE) == 0) {
         config->enablePrach = atoi(value);
         printf("Prach enable: %d\n",config->enablePrach);
-    } else if (strcmp(key, KEY_PRACH_OFFSET ) == 0) {
-        config->prachOffset = atoi(value);
-        printf("Prach Offset: %d\n",config->prachOffset);
-    } else if (strcmp(key, KEY_PRACH_CFG_IDX ) == 0) {
+    } else if (strcmp(key, KEY_PRACH_CFGIDX) == 0) {
         config->prachConfigIndex = atoi(value);
-        printf("Prach Conf Index: %d\n",config->prachConfigIndex);
-
+        printf("Prach config index: %d\n",config->prachConfigIndex);
+    } else if (strncmp(key, KEY_FILE_PRACH_AxC, strlen(KEY_FILE_PRACH_AxC)) == 0) {
+        unsigned int ant_num = 0;
+        sscanf(key,"antPrachC%02u",&ant_num);
+        if (ant_num >= MAX_ANT_CARRIER_SUPPORTED)
+        {
+            printf("antC%d exceeds max antenna supported\n",ant_num);
+        }
+        else{
+            strncpy(&config->prach_file[ant_num][0], value, strlen(value));
+            printf("antPrachC%d: %s\n",ant_num, config->prach_file[ant_num]);
+        }
         /* timing */
     } else if (strcmp(key, KEY_TADV_CP_DL ) == 0) {
         config->Tadv_cp_dl = atoi(value);
@@ -279,6 +319,15 @@ static int fillConfigStruct(RuntimeConfig *config, const char *key, const char *
     } else if (strcmp(key, KEY_DEBUG_STOP ) == 0) {
         config->debugStop = atoi(value);
         printf("debugStop: %d\n",config->debugStop);
+    } else if (strcmp(key, KEY_DEBUG_STOP_CNT) == 0) {
+        config->debugStopCount = atoi(value);
+        printf("debugStopCount: %d\n",config->debugStopCount);
+    } else if (strcmp(key, KEY_BBDEV_MODE) == 0) {
+        config->bbdevMode = atoi(value);
+        printf("bbdevMode: %d\n",config->debugStopCount);
+    } else if (strcmp(key, KEY_DYNA_SEC_ENA) == 0) {
+        config->DynamicSectionEna = atoi(value);
+        printf("DynamicSectionEna: %d\n",config->DynamicSectionEna);
     } else if (strcmp(key, KEY_CP_VTAG ) == 0) {
         config->cp_vlan_tag = atoi(value);
         printf("cp_vlan_tag: %d\n",config->cp_vlan_tag);
@@ -304,11 +353,11 @@ int parseConfigFile(char *filename, RuntimeConfig *config)
     FILE *file = fopen(filename, "r");
 
     if (NULL == file) {
-        //log_err("Error while opening config file from: %s", filename);
+        log_err("Error while opening config file from: %s", filename);
         return -1;
     }
 
-    init_config(config);
+//    init_config(config);
 
     for (;;) {
         if (fgets(inputLine, MAX_LINE_SIZE, file) == NULL) {
@@ -341,7 +390,7 @@ int parseConfigFile(char *filename, RuntimeConfig *config)
                 key[i] = '\0';
                 trim(key);
                 if ((i + 1 > inputLen - 1) || (i - 2 > inputLen)) {
-                    //log_err("Parsing config file error at line %d", lineNum);
+                    log_err("Parsing config file error at line %d", lineNum);
                     fclose(file);
                     return -1;
                 }
index b2953ee..c223b0b 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdint.h>
 #include <rte_ether.h>
+#include "xran_fh_o_du.h"
 
 /** Run time configuration of application */
 typedef struct _RuntimeConfig
@@ -36,13 +37,18 @@ typedef struct _RuntimeConfig
     uint8_t appMode;      /**< Application mode: lls-CU or RU  */
     uint8_t xranMode;     /**< xran mode: Categoty A | Category B */
     uint8_t numCC;        /**< Number of CC per ports supported by RU */
-    uint8_t mu_number;    /**< Mu numner as per 3GPP */
     uint8_t numAxc;       /**< Number of Antenna Carriers per CC */
     uint32_t ttiPeriod;   /**< TTI period */
     uint32_t testVect;    /**< Test Signal to send */
-    struct ether_addr lls_cu_addr; /**<  lls-CU Ethernet Mac Address */
-    struct ether_addr ru_addr; /**<  RU Ethernet Mac Address */
-    char ant_file[16][512] /**<  file to use for test vector */ ;
+    struct ether_addr o_du_addr; /**<  lls-CU Ethernet Mac Address */
+    struct ether_addr o_ru_addr; /**<  RU Ethernet Mac Address */
+    struct ether_addr tmp_addr; /**<  Temp Ethernet Mac Address */
+
+    uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+                       xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
+    int numSlots;  /**< number of slots in IQ vector */
+    char ant_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512] /**<  file to use for test vector */ ;
+    char prach_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512] /**<  file to use for test vector */ ;
 
     /* prach config */
     uint8_t enablePrach; /**<  enable PRACH */
@@ -76,8 +82,22 @@ typedef struct _RuntimeConfig
     uint8_t up_vlan_tag; /**<  U-plane vlan tag */
 
     int32_t debugStop;
+    int32_t debugStopCount;
+    int32_t bbdevMode;
+    int32_t DynamicSectionEna;
+
+    uint8_t  mu_number;       /**< Mu numner as per 3GPP */
+    uint32_t nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+    uint32_t nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+    uint32_t nDLBandwidth;    /**< Carrier bandwidth for in MHz. Value: 5->400 */
+    uint32_t nULBandwidth;    /**< Carrier bandwidth for in MHz. Value: 5->400 */
+    uint32_t nDLFftSize;      /**< DL FFT size */
+    uint32_t nULFftSize;      /**< UL FFT size */
 
 
+    uint8_t nFrameDuplexType;
+    uint8_t nTddPeriod;
+    struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
 } RuntimeConfig;
 
 /**
diff --git a/fhi_lib/app/src/debug.h b/fhi_lib/app/src/debug.h
new file mode 100644 (file)
index 0000000..d0482a8
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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
+ * @file
+ * @ingroup
+ * @author Intel Corporation
+ **/
+
+#ifndef _SAMPLEAPP__DEBUG_H_
+#define _SAMPLEAPP__DEBUG_H_
+
+#include <stdio.h>
+
+#include "config.h"
+
+#define MAX_FILE_NAME_LEN (512)
+#define MAX_PATH_NAME_LEN (1024)
+
+#ifdef _DEBUG
+    #define log_dbg(fmt, ...)                       \
+        fprintf(stderr,                     \
+            "DEBUG: %s(%d): " fmt "\n",             \
+            __FILE__,                       \
+            __LINE__, ##__VA_ARGS__)
+#else
+    #define log_dbg(fmt, ...)
+#endif
+
+#if defined(_DEBUG) || defined(_VERBOSE)
+    #define log_wrn(fmt, ...)                               \
+        fprintf(                                            \
+            stderr,                                     \
+            "WARNING: %s(%d): " fmt "\n",                   \
+            __FILE__,                                       \
+            __LINE__, ##__VA_ARGS__)
+#else
+    #define log_dbg(fmt, ...)
+    #define log_wrn(fmt, ...)
+#endif
+
+
+#define log_err(fmt, ...)                       \
+    fprintf(stderr,                     \
+        "ERROR: %s(%d): " fmt "\n",             \
+        __FILE__,                       \
+        __LINE__, ##__VA_ARGS__)
+
+
+inline void ShowData(void* ptr, unsigned int size)
+{
+    uint8_t *d =  (uint8_t *)ptr;
+    unsigned int i;
+
+    for(i = 0; i < size; i++)
+    {
+        if ( !(i & 0xf) )
+            printf("\n");
+        printf("%02x ", d[i]);
+    }
+    printf("\n");
+}
+
+
+#endif /* _SAMPLEAPP__DEBUG_H_ */
similarity index 52%
rename from fhi_lib/app/lls-cu/sample-lls-cu.c
rename to fhi_lib/app/src/sample-app.c
index 31ffb4b..f45cf94 100644 (file)
@@ -16,6 +16,7 @@
 *
 *******************************************************************************/
 
+
 #define _GNU_SOURCE
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <pthread.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 
 #include "common.h"
 #include "config.h"
+#include "xran_mlog_lnx.h"
 
-#ifndef MLOG_ENABLED
-#include "../../lib/src/mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
-
-
-#include "xran_fh_lls_cu.h"
-//#include "xran_pkt.h"
-//#include "xran_up_api.h"
+#include "xran_fh_o_du.h"
 #include "xran_cp_api.h"
 #include "xran_sync_api.h"
 #include "xran_mlog_task_id.h"
 
+#define MAX_BBU_POOL_CORE_MASK  (4)
+
+
 #define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024
 #define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024
 #define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024
@@ -67,16 +67,16 @@ static uint64_t tsc_resolution_hz = 0;
 
 RuntimeConfig startupConfiguration = {0};
 
-//FH FPGA buffer
+/* buffers size */
 uint32_t    nFpgaToSW_FTH_RxBufferLen;
 uint32_t    nFpgaToSW_PRACH_RxBufferLen;
 uint32_t    nSW_ToFpga_FTH_TxBufferLen;
 
-static XRANFHINIT xranInit;
+static struct xran_fh_init xranInit;
 void * xranHandle = NULL;
 
-XRANFHCONFIG  xranConf;
-PXRANFHCONFIG pXranConf = NULL;
+struct xran_fh_config  xranConf;
+struct xran_fh_config  *pXranConf = NULL;
 
 typedef struct
 {
@@ -100,7 +100,9 @@ typedef struct XranLibConfig
 }XranLibConfigStruct;
 typedef enum {
     XRANFTHTX_OUT = 0,
+    XRANFTHTX_PRB_MAP_OUT,
     XRANFTHRX_IN,
+    XRANFTHRX_PRB_MAP_IN,
     XRANFTHRACH_IN,
     MAX_SW_XRAN_INTERFACE_NUM
 }SWXRANInterfaceTypeEnum;
@@ -121,7 +123,7 @@ typedef struct {
                        // -1 means that DL packet to be transmitted is not ready in BS
     int32_t nSegTransferred; // number of data segments has been transmitted or received
     struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
-    XRANBufferListStruct sBufferList;
+    struct xran_buffer_list sBufferList;
 } BbuIoBufCtrlStruct;
 
 typedef struct  {
@@ -134,32 +136,31 @@ typedef struct  {
 
     /* io struct */
     BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
     BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
     BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
 
     /* buffers lists */
-    XRANFlatBufferStruct sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
-    XRANFlatBufferStruct sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
-    XRANFlatBufferStruct sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
 
     void*    nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
     uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   // every api owns unique buffer pool
     uint16_t nInstanceNum;
 
-    /*subframe type for this TTI:
-        0: DL control + DL data
-        1: DL control + DL data + UL control
-        2: DL control + UL data
-        3: DL control + UL data + UL control
-    */
-    uint8_t nSubframeType;
-
     uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
 } BbuXranIoIfStruct;
 
 static BbuXranIoIfStruct    gsXranIoIf;
 static XranLibConfigStruct *gpXranLibConfig = NULL;
 
+extern long rx_counter;
+extern long tx_counter;
+
 #define CPU_HZ tick_per_usec //us
 
 /* Application User space functions */
@@ -180,15 +181,44 @@ static void print_menu()
     puts("+---------------------------------------+");
 }
 
-void xran_fh_rx_callback(void *pCallbackTag, XranStatusInt32 status)
+static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
+{
+    int32_t nSfIdx = -1;
+    uint32_t nFrameIdx;
+    uint32_t nSubframeIdx;
+    uint32_t nSlotIdx;
+    uint64_t nSecond;
+
+    uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
+    nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
+        + nSubframeIdx*nNrOfSlotInSf
+        + nSlotIdx;
+#if 0
+    printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
+        nXranTime,
+        nSfIdx,
+        nFrameIdx,
+        nSubframeIdx,
+        nSlotIdx,
+        __rdtsc()/CPU_HZ);
+#endif
+
+    return nSfIdx;
+}
+
+void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
 {
     uint64_t t1 = MLogTick();
     uint32_t mlogVar[10];
     uint32_t mlogVarCnt = 0;
+    uint8_t Numerlogy = xranConf.frame_conf.nNumerology;
+    uint8_t nNrOfSlotInSf = 1<<Numerlogy;
+    int32_t sfIdx = get_xran_sfidx(nNrOfSlotInSf);
 
     mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
     mlogVar[mlogVarCnt++] = status >> 16; /* tti */
     mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
+    mlogVar[mlogVarCnt++] = (uint32_t)sfIdx;
     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
     rte_pause();
 
@@ -196,10 +226,18 @@ void xran_fh_rx_callback(void *pCallbackTag, XranStatusInt32 status)
     return;
 }
 
-void xran_fh_rx_prach_callback(void *pCallbackTag, XranStatusInt32 status)
+void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
 {
     uint64_t t1 = MLogTick();
+    uint32_t mlogVar[10];
+    uint32_t mlogVarCnt = 0;
+
+    mlogVar[mlogVarCnt++] = 0xDDDDDDDD;
+    mlogVar[mlogVarCnt++] = status >> 16; /* tti */
+    mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
+    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
     rte_pause();
+
     MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
 }
 
@@ -304,12 +342,13 @@ int physide_ul_full_slot_call_back(void * param)
 int32_t init_xran(void)
 {
     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
-    XranStatusInt32 status;
+    xran_status_t status;
     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
     int32_t nSectorNum;
     int32_t i, j, k, z;
 
     void *ptr;
+    void *mb;
     uint32_t *u32dptr;
     uint16_t *u16dptr;
     uint8_t  *u8dptr;
@@ -318,23 +357,12 @@ int32_t init_xran(void)
 
     XranLibConfigStruct  *ptrLibConfig;
 
-    XRANBufferListStruct *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
-    XRANBufferListStruct *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
-    XRANBufferListStruct *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
-
-    FPGAPhaseCompCfg *pPhaseCompDl = NULL;
-    FPGAPhaseCompCfg *pPhaseCompUl = NULL;
-    uint32_t nPhaseCompDl,nPhaseCompUl;
+    struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+    struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+    struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+    struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+    struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
 
-
-#if 0
-    printf("init_xran: nFpgaProbe[%d] nSecNum[%d] nUENum[%d] nTimeAdvance[%d] nEthPorts[%d] nPhaseCompFlag[%d]\n",
-        psFPGAInitPara->nFpgaProbe, psFPGAInitPara->nSecNum, psFPGAInitPara->nUENum, psFPGAInitPara->nTimeAdvance, psFPGAInitPara->nEthPorts, psFPGAInitPara->nPhaseCompFlag);
-    for (i = 0; i < nSectorNum; i ++)
-    {
-        printf("           [%d]: nDlArfcn[%d] nUlArfcn[%d]\n", i, psFPGAInitPara->nDlArfcn[i], psFPGAInitPara->nUlArfcn[i]);
-    }
-#endif
     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
     {
         nSectorIndex[nSectorNum] = nSectorNum;
@@ -352,12 +380,15 @@ int32_t init_xran(void)
     psBbuIo->nInstanceNum = numCCPorts;
 
     for (k = 0; k < XRAN_PORTS_NUM; k++) {
-        status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,psBbuIo->nInstanceHandle[k]);
+        status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]);
         if (status != XRAN_STATUS_SUCCESS)
         {
             printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
             exit(-1);
         }
+        for (i = 0; i < psBbuIo->nInstanceNum; i++){
+            printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]);
+        }
     }
 
     printf("Sucess xran_mm_init \n");
@@ -365,7 +396,7 @@ int32_t init_xran(void)
     ptrLibConfig = gpXranLibConfig;
     if (ptrLibConfig)
     {
-        #if 0
+    #if 0
         ptrLibConfig->nDriverCoreId =  psBbuIo->nDriverCoreId;
         ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
         ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
@@ -378,7 +409,7 @@ int32_t init_xran(void)
         {
             ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
         }
-        #endif
+    #endif
     }
     else
     {
@@ -392,7 +423,8 @@ int32_t init_xran(void)
     for(i = 0; i<nSectorNum; i++)
     {
         eInterfaceType = XRANFTHTX_OUT;
-        status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+        printf("nSectorIndex[%d] = %d\n",i,  nSectorIndex[i]);
+        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
             XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
         if(XRAN_STATUS_SUCCESS != status)
         {
@@ -414,13 +446,14 @@ int32_t init_xran(void)
                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
-                    status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                     if(XRAN_STATUS_SUCCESS != status)
                     {
                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                         iAssert(status == XRAN_STATUS_SUCCESS);
                     }
                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
 
                     if(ptr){
                         u32dptr = (uint32_t*)(ptr);
@@ -434,12 +467,58 @@ int32_t init_xran(void)
                 }
             }
         }
+
+        /* C-plane DL */
+        eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
+        printf("nSectorIndex[%d] = %d\n",i,  nSectorIndex[i]);
+        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+            XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
+        if(XRAN_STATUS_SUCCESS != status)
+        {
+            printf("Failed at  xran_bm_init , status %d\n", status);
+            iAssert(status == XRAN_STATUS_SUCCESS);
+        }
+        for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
+        {
+            for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z];
+
+                {
+                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
+                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
+                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
+                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
+                    if(XRAN_STATUS_SUCCESS != status)
+                    {
+                        printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
+                        iAssert(status == XRAN_STATUS_SUCCESS);
+                    }
+                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
+                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
+
+                    if(ptr){
+                        u32dptr = (uint32_t*)(ptr);
+                        uint8_t *ptr_temp = (uint8_t *)ptr;
+                        memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
+                        ptr_temp[0] = j; // TTI
+                        ptr_temp[1] = i; // Sec
+                        ptr_temp[2] = z; // Ant
+                        ptr_temp[3] = k; // sym
+                    }
+                }
+            }
+        }
     }
 
     for(i = 0; i<nSectorNum; i++)
     {
         eInterfaceType = XRANFTHRX_IN;
-        status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
+        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
         if(XRAN_STATUS_SUCCESS != status)
         {
             printf("Failed at xran_bm_init, status %d\n", status);
@@ -460,13 +539,14 @@ int32_t init_xran(void)
                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
-                    status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                     if(XRAN_STATUS_SUCCESS != status)
                     {
-                        printf("Failed at  cpa_bb_bm_allocate_buffer , status %d\n",status);
+                        printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                         iAssert(status == XRAN_STATUS_SUCCESS);
                     }
                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
                     if(ptr){
                         u32dptr = (uint32_t*)(ptr);
                         uint8_t *ptr_temp = (uint8_t *)ptr;
@@ -479,13 +559,57 @@ int32_t init_xran(void)
                 }
             }
         }
+
+        /* C-plane */
+        eInterfaceType = XRANFTHRX_PRB_MAP_IN;
+        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+                XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
+        if(XRAN_STATUS_SUCCESS != status)
+        {
+            printf("Failed at xran_bm_init, status %d\n", status);
+            iAssert(status == XRAN_STATUS_SUCCESS);
+        }
+
+        for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
+        {
+            for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z];
+                {
+                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
+                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
+                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
+                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
+                    if(XRAN_STATUS_SUCCESS != status)
+                    {
+                        printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
+                        iAssert(status == XRAN_STATUS_SUCCESS);
+                    }
+                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
+                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
+                    if(ptr){
+                        u32dptr = (uint32_t*)(ptr);
+                        uint8_t *ptr_temp = (uint8_t *)ptr;
+                        memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
+                        ptr_temp[0] = j; // TTI
+                        ptr_temp[1] = i; // Sec
+                        ptr_temp[2] = z; // Ant
+                        ptr_temp[3] = k; // sym
+                    }
+                }
+            }
+        }
     }
 
     // add prach rx buffer
     for(i = 0; i<nSectorNum; i++)
     {
         eInterfaceType = XRANFTHRACH_IN;
-        status =xran_bm_init(xranHandle,&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
+        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
         if(XRAN_STATUS_SUCCESS != status)
         {
             printf("Failed at xran_bm_init, status %d\n", status);
@@ -500,19 +624,19 @@ int32_t init_xran(void)
                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
-                //for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
-                k = 0; // one PRACH buffer per antenna per slot
+                for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
                 {
                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
-                    status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                     if(XRAN_STATUS_SUCCESS != status)
                     {
                         printf("Failed at  xran_bm_allocate_buffer, status %d\n",status);
                         iAssert(status == XRAN_STATUS_SUCCESS);
                     }
                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
                     if(ptr){
                         u32dptr = (uint32_t*)(ptr);
                         memset(u32dptr, 0xCC, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
@@ -528,7 +652,9 @@ int32_t init_xran(void)
         {
             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
                 pFthTxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
+                pFthTxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
                 pFthRxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
+                pFthRxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
                 pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
             }
         }
@@ -540,7 +666,9 @@ int32_t init_xran(void)
         {
             xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
                 pFthTxBuffer[i],
+                pFthTxPrbMapBuffer[i],
                 pFthRxBuffer[i],
+                pFthRxPrbMapBuffer[i],
                 xran_fh_rx_callback,  &pFthRxBuffer[i][0]);
         }
 
@@ -553,37 +681,13 @@ int32_t init_xran(void)
         ptrLibConfig->nFhBufIntFlag = 1;
     }
 
-    /*config phase compensation*/
-    /* TODO: add phase compensation handling */
-    for(i=0; i<nSectorNum; i++)
-    {
-        pPhaseCompDl = (FPGAPhaseCompCfg *)(&nPhaseCompDl);
-        pPhaseCompDl->NRARFCN = 0;//psFPGAInitPara->nDlArfcn[i];
-        pPhaseCompDl->phaseFlag = 0;//psFPGAInitPara->nPhaseCompFlag;
-        pPhaseCompDl->SULFlag = 0;
-        pPhaseCompDl->SULFreShift = 0;
-        pPhaseCompDl->rsv = 0;
-
-        pPhaseCompUl = (FPGAPhaseCompCfg *)(&nPhaseCompUl);
-        pPhaseCompUl->NRARFCN =  0;//psFPGAInitPara->nUlArfcn[i];
-        pPhaseCompUl->phaseFlag = 0;// psFPGAInitPara->nPhaseCompFlag;
-        pPhaseCompUl->SULFlag = 0;
-        pPhaseCompUl->SULFreShift = 0;
-        pPhaseCompUl->rsv = 0;
-
-        xran_5g_pre_compenstor_cfg(psBbuIo->nInstanceHandle[0][i],nPhaseCompDl,nPhaseCompUl,i);
-
-        printf("@@@ NB cell %d DL NR-ARFCN  %d,DL phase comp flag %d UL NR-ARFCN  %d,UL phase comp flag %d \n",
-            i,pPhaseCompDl->NRARFCN,pPhaseCompDl->phaseFlag,
-            pPhaseCompUl->NRARFCN,pPhaseCompUl->phaseFlag);
-    }
     return status;
 }
 
 int init_xran_iq_content(void)
 {
     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
-    XranStatusInt32 status;
+    xran_status_t status;
     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
     int32_t nSectorNum;
     int32_t cc_id, ant_id, sym_id, tti;
@@ -600,6 +704,7 @@ int init_xran_iq_content(void)
     uint8_t  *u8dptr;
 
     char        *pos = NULL;
+    struct xran_prb_map *pRbMap = NULL;
 
     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
     {
@@ -614,17 +719,16 @@ int init_xran_iq_content(void)
         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
-                    flowId = nSectorNum * ant_id + cc_id;
+
+                    flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
 
                     if(p_tx_play_buffer[flowId]){
-                        /* (0-79 slots) 10ms of IQs */
                         pos =  ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
-
                         ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
 
-                        if(ptr){
+                        if(ptr && pos){
                             u32dptr = (uint32_t*)(ptr);
-                            rte_memcpy(u32dptr, pos, PDSCH_PAYLOAD_SIZE);
+                            rte_memcpy(u32dptr, pos, pXranConf->nDLRBs*N_SC_PER_PRB*4);
 #ifdef DEBUG_XRAN_BUFFERS
                             uint8_t *ptr_temp = (uint8_t *)ptr;
                                 ptr_temp[0] = tti; // TTI
@@ -632,10 +736,52 @@ int init_xran_iq_content(void)
                                 ptr_temp[2] = ant_id; // Ant
                                 ptr_temp[3] = sym_id; // sym
 #endif
-                        }else
+                        } else {
+                            exit(-1);
                             printf("ptr ==NULL\n");
-
-                        tx_play_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
+                        }
+
+                        /* c-plane DL */
+                        pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
+                        if(pRbMap){
+                            pRbMap->dir = XRAN_DIR_DL;
+                            pRbMap->xran_port = 0;
+                            pRbMap->band_id = 0;
+                            pRbMap->cc_id = cc_id;
+                            pRbMap->ru_port_id = ant_id;
+                            pRbMap->tti_id = tti;
+                            pRbMap->start_sym_id = 0;
+                            pRbMap->nPrbElm = 1;
+                            pRbMap->prbMap[0].nRBStart = 0;
+                            pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
+                            pRbMap->prbMap[0].nBeamIndex = 0;
+                            pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
+                        }else{
+                            printf("DL pRbMap ==NULL\n");
+                            exit(-1);
+                        }
+
+                        /* c-plane UL */
+                        pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
+                        if(pRbMap){
+                            pRbMap->dir = XRAN_DIR_UL;
+                            pRbMap->xran_port = 0;
+                            pRbMap->band_id = 0;
+                            pRbMap->cc_id = cc_id;
+                            pRbMap->ru_port_id = ant_id;
+                            pRbMap->tti_id = tti;
+                            pRbMap->start_sym_id = 0;
+                            pRbMap->nPrbElm = 1;
+                            pRbMap->prbMap[0].nRBStart = 0;
+                            pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
+                            pRbMap->prbMap[0].nBeamIndex = 0;
+                            pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
+                        }else {
+                            printf("UL: pRbMap ==NULL\n");
+                            exit(-1);
+                        }
+
+                        tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4;
 
                         if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
                             tx_play_buffer_position[flowId] = 0;
@@ -644,8 +790,40 @@ int init_xran_iq_content(void)
                     }
                 }
             }
-        }
 
+            /* prach TX for RU only */
+            if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+                for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
+                    for(sym_id = 0; sym_id < 1; sym_id++) {
+                        flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
+
+                        if(p_tx_prach_play_buffer[flowId]){
+                            /* (0-79 slots) 10ms of IQs */
+                            pos =  ((char*)p_tx_prach_play_buffer[flowId]);
+
+                            ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+
+                            if(ptr && pos){
+                                u32dptr = (uint32_t*)(ptr);
+                                rte_memcpy(u32dptr, pos, PRACH_PLAYBACK_BUFFER_BYTES);
+#ifdef DEBUG_XRAN_BUFFERS
+                                uint8_t *ptr_temp = (uint8_t *)ptr;
+                                    ptr_temp[0] = tti; // TTI
+                                    ptr_temp[1] = cc_id; // Sec
+                                    ptr_temp[2] = ant_id; // Ant
+                                    ptr_temp[3] = sym_id; // sym
+#endif
+                            } else {
+                                exit(-1);
+                                printf("ptr ==NULL\n");
+                            }
+                        } else {
+                            //printf("flowId %d\n", flowId);
+                        }
+                    }
+                }
+            }
+        }
     }
 
     return 0;
@@ -653,7 +831,7 @@ int init_xran_iq_content(void)
 
 void stop_xran(void)
 {
-    XranStatusInt32 status = 0;
+    xran_status_t status = 0;
     SWXRANInterfaceTypeEnum eInterfaceType;
 
     free(gpXranLibConfig);
@@ -668,35 +846,10 @@ void stop_xran(void)
     }
 }
 
-int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
-{
-    int32_t nSfIdx = -1;
-    uint32_t nFrameIdx;
-    uint32_t nSubframeIdx;
-    uint32_t nSlotIdx;
-    uint64_t nSecond;
-
-    uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
-    nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
-        + nSubframeIdx*nNrOfSlotInSf
-        + nSlotIdx;
-#if 0
-    printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
-        nXranTime,
-        nSfIdx,
-        nFrameIdx,
-        nSubframeIdx,
-        nSlotIdx,
-        __rdtsc()/CPU_HZ);
-#endif
-
-    return nSfIdx;
-}
-
 int get_xran_iq_content(void)
 {
     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
-    XranStatusInt32 status;
+    xran_status_t status;
     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
     int32_t nSectorNum;
     int32_t cc_id, ant_id, sym_id, tti;
@@ -727,14 +880,14 @@ int get_xran_iq_content(void)
         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti++) {
             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
-                    flowId = nSectorNum * ant_id + cc_id;
+                    flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
                     if(p_rx_log_buffer[flowId]){
                         /* (0-79 slots) 10ms of IQs */
                         pos =  ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
                         ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
                         if(ptr){
                             u32dptr = (uint32_t*)(ptr);
-                            rte_memcpy(pos, u32dptr, PDSCH_PAYLOAD_SIZE);
+                            rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4);
 #ifdef DEBUG_XRAN_BUFFERS
                             if (pos[0] != tti||
                                 pos[1] != cc_id  ||
@@ -746,7 +899,7 @@ int get_xran_iq_content(void)
                         }else
                             printf("ptr ==NULL\n");
 
-                        rx_log_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
+                        rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;
 
                         if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
                             rx_log_buffer_position[flowId] = 0;
@@ -754,6 +907,39 @@ int get_xran_iq_content(void)
                         //printf("flowId %d\n", flowId);
                     }
                 }
+
+                /* prach RX for O-DU only */
+                if(startupConfiguration.appMode == APP_O_DU){
+                    flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
+                    sym_id = 0;
+
+                    if(p_prach_log_buffer[flowId]){
+                        /* (0-79 slots) 10ms of IQs */
+                        pos =  ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId];
+                        ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+                        if(ptr){
+                            u32dptr = (uint32_t*)(ptr);
+                            rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES);
+#ifdef DEBUG_XRAN_BUFFERS
+                            if (pos[0] != tti||
+                                pos[1] != cc_id  ||
+                                pos[2] != ant_id ||
+                                pos[3] != sym_id){
+                                    printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
+                            }
+#endif
+                        }else
+                            printf("ptr ==NULL\n");
+
+                        prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES;
+
+                        if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId])
+                            prach_log_buffer_position[flowId] = 0;
+                    } else {
+                        //printf("flowId %d\n", flowId);
+                    }
+                }
+
             }
         }
     }
@@ -761,15 +947,65 @@ int get_xran_iq_content(void)
     return 0;
 }
 
+void version_print(void)
+{
+    char            sysversion[100];
+    char           *compilation_date = __DATE__;
+    char           *compilation_time = __TIME__;
+
+    uint32_t          nLen;
+    uint32_t          i;
+
+    snprintf(sysversion, 99, "Version: %s", VERSIONX);
+    nLen = strlen(sysversion);
+
+    printf("\n\n");
+    printf("===========================================================================================================\n");
+    printf("SAMPLE-APP VERSION\n");
+    printf("===========================================================================================================\n");
+
+    printf("%s\n", sysversion);
+    printf("build-date: %s\n", compilation_date);
+    printf("build-time: %s\n", compilation_time);
+}
+
 int main(int argc, char *argv[])
 {
     int i;
-    int j;
+    int j, len;
     int  lcore_id = 0;
     char filename[64];
+    uint32_t nCenterFreq;
+    int32_t xret = 0;
+    struct stat st = {0};
+    uint32_t filenameLength = strlen(argv[1]);
+    char *pCheckName1 = NULL, *pCheckName2 = NULL;
+    enum xran_if_state xran_curr_if_state = XRAN_INIT;
 
     if (argc == 3)
         errx(2, "Need two argument - the PCI address of the network port");
+    if (filenameLength >= 64)
+    {
+        printf("Config file name input is too long, exiting!\n");
+        exit(-1);
+    }
+
+    version_print();
+
+    //add for Klocworks
+    len = strlen(argv[1]) + 1;
+    if (len > (sizeof(filename) - 10))
+        len = (sizeof(filename) - 10);
+    strncpy(filename, argv[1], (sizeof(filename) - 10));
+    filename[len] = '\0';
+
+    pCheckName1 = strstr(filename, "config_file_o_du.dat");
+    pCheckName2 = strstr(filename, "config_file_o_ru.dat");
+    if ((pCheckName1 == NULL) && (pCheckName2 == NULL))
+    {
+        printf("config file name %s is not valid!\n", filename);
+        exit(-1);
+    }
 
     if (xran_is_synchronized() != 0)
         printf("Machine is not synchronized using PTP!\n");
@@ -778,7 +1014,7 @@ int main(int argc, char *argv[])
 
     memset(&startupConfiguration, 0, sizeof(RuntimeConfig));
 
-    if (parseConfigFile(argv[1], &startupConfiguration) != 0) {
+    if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) {
         printf("Configuration file error.\n");
         return 0;
     }
@@ -787,21 +1023,34 @@ int main(int argc, char *argv[])
         printf("it looks like test vector for antennas were not provided\n");
         exit(-1);
     }
+    if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR)
+    {
+        printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR);
+        startupConfiguration.numCC = XRAN_MAX_SECTOR_NR;
 
+    }
     numCCPorts = startupConfiguration.numCC;
     num_eAxc   = startupConfiguration.numAxc;
 
     printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);
 
-    /* Numerology 3 */
-    nFpgaToSW_FTH_RxBufferLen    = 3328; //3200 * 14;
-    nFpgaToSW_PRACH_RxBufferLen  = 8192;
-    nSW_ToFpga_FTH_TxBufferLen   = 3328; //3200; * 14;
+    if (startupConfiguration.mu_number <= 1){
+        nFpgaToSW_FTH_RxBufferLen    = 13168; /* 273*12*4 + 64*/
+        nFpgaToSW_PRACH_RxBufferLen  = 8192;
+        nSW_ToFpga_FTH_TxBufferLen   = 13168; /* 273*12*4 + 64*/
+    } else if (startupConfiguration.mu_number == 3){
+        nFpgaToSW_FTH_RxBufferLen    = 3328;
+        nFpgaToSW_PRACH_RxBufferLen  = 8192;
+        nSW_ToFpga_FTH_TxBufferLen   = 3328;
+    } else {
+        printf("given numerology is not supported %d\n", startupConfiguration.mu_number);
+        exit(-1);
+    }
 
-    memset(&xranInit, 0, sizeof(XRANFHINIT));
+    memset(&xranInit, 0, sizeof(struct xran_fh_init));
 
-    if(startupConfiguration.appMode == APP_LLS_CU) {
-        printf("set lls-CU\n");
+    if(startupConfiguration.appMode == APP_O_DU) {
+        printf("set O-DU\n");
         xranInit.io_cfg.id = 0;//ID_LLS_CU;
         xranInit.io_cfg.core          = 4+1;
         xranInit.io_cfg.system_core   = 0;
@@ -809,7 +1058,7 @@ int main(int argc, char *argv[])
         xranInit.io_cfg.pkt_aux_core  = 0; /* do not start*/
         xranInit.io_cfg.timing_core   = 4+3;
     } else {
-        printf("set RU\n");
+        printf("set O-DU\n");
         xranInit.io_cfg.id = 1; /* ID_LLS_CU;*/
         xranInit.io_cfg.core          = 1;
         xranInit.io_cfg.system_core   = 0;
@@ -818,8 +1067,7 @@ int main(int argc, char *argv[])
         xranInit.io_cfg.timing_core   = 3;
     }
 
-    xranInit.llscuId        = 0;    // for ecpriRtcid/ecpriPcid
-    xranInit.nSec           = 1;    // shall be one
+    xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
 
     xranInit.eAxCId_conf.mask_cuPortId      = 0xf000;
     xranInit.eAxCId_conf.mask_bandSectorId  = 0x0f00;
@@ -832,9 +1080,12 @@ int main(int argc, char *argv[])
 
     xranInit.io_cfg.dpdk_dev[XRAN_UP_VF]      = argv[2];
     xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]      = argv[3];
-    xranInit.p_lls_cu_addr = (int8_t*)&startupConfiguration.lls_cu_addr;
-    xranInit.p_ru_addr     = (int8_t*)&startupConfiguration.ru_addr;
-    xranInit.ttiPeriod     = startupConfiguration.ttiPeriod;
+    xranInit.mtu           = startupConfiguration.mtu;
+
+    xranInit.p_o_du_addr = (int8_t*)&startupConfiguration.o_du_addr;
+    xranInit.p_o_ru_addr = (int8_t*)&startupConfiguration.o_ru_addr;
+    xranInit.filePrefix  = "wls";
+    xranInit.xranCat     = XRAN_CATRGORY_A;
 
     xranInit.Tadv_cp_dl     = startupConfiguration.Tadv_cp_dl;
     xranInit.T2a_min_cp_dl  = startupConfiguration.T2a_min_cp_dl;
@@ -854,17 +1105,30 @@ int main(int argc, char *argv[])
     xranInit.Ta4_min        = startupConfiguration.Ta4_min;
     xranInit.Ta4_max        = startupConfiguration.Ta4_max;
 
-    xranInit.enableCP = startupConfiguration.enableCP;
-    xranInit.debugStop = startupConfiguration.debugStop;
+    xranInit.enableCP       = startupConfiguration.enableCP;
+    xranInit.prachEnable    = startupConfiguration.enablePrach;
+    xranInit.debugStop      = startupConfiguration.debugStop;
+    xranInit.debugStopCount = startupConfiguration.debugStopCount;
+    xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna;
+    xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; //startupConfiguration.bbdevMode;
+
+    xranInit.cp_vlan_tag    = startupConfiguration.cp_vlan_tag;
+    xranInit.up_vlan_tag    = startupConfiguration.up_vlan_tag;
 
-    xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag;
-    xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag;
+    printf("IQ files size is %d slots\n", startupConfiguration.numSlots);
 
+    iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
+                                 app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
+                                 *4L);
+
+    iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
+                                 app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
+                                 *4L);
 
     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        p_tx_play_buffer[i]    = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
-        tx_play_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
+        p_tx_play_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_dl);
+        tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;
 
         if (p_tx_play_buffer[i] == NULL)
             exit(-1);
@@ -877,11 +1141,27 @@ int main(int argc, char *argv[])
         tx_play_buffer_position[i] = 0;
     }
 
+    if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+             p_tx_prach_play_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
+             tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
+
+             if (p_tx_prach_play_buffer[i] == NULL)
+                 exit(-1);
+
+             tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i],
+                                 "PRACH IQ Samples in binary format",
+                                 (uint8_t*) p_tx_prach_play_buffer[i],
+                                 tx_prach_play_buffer_size[i],
+                                 1);
+             tx_prach_play_buffer_position[i] = 0;
+         }
+    }
     /* log of ul */
     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        p_rx_log_buffer[i]    = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
-        rx_log_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
+        p_rx_log_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_ul);
+        rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul;
 
         if (p_rx_log_buffer[i] == NULL)
             exit(-1);
@@ -894,8 +1174,8 @@ int main(int argc, char *argv[])
     /* log of Prach */
     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        p_prach_log_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
-        prach_log_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
+        p_prach_log_buffer[i]    = (int16_t*)malloc(startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES);
+        prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES;
 
         if (p_prach_log_buffer[i] == NULL)
             exit(-1);
@@ -904,21 +1184,41 @@ int main(int argc, char *argv[])
         prach_log_buffer_position[i] = 0;
     }
 
+    if (stat("./logs", &st) == -1) {
+        mkdir("./logs", 0777);
+    }
+
     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "%s-play_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
+        sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
         sys_save_buf_to_file_txt(filename,
                             "DL IFFT IN IQ Samples in human readable format",
                             (uint8_t*) p_tx_play_buffer[i],
                             tx_play_buffer_size[i],
                             1);
 
-        sprintf(filename, "%s-play_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+        sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
         sys_save_buf_to_file(filename,
                             "DL IFFT IN IQ Samples in binary format",
                             (uint8_t*) p_tx_play_buffer[i],
                             tx_play_buffer_size[i]/sizeof(short),
                             sizeof(short));
+
+        if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+            sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
+            sys_save_buf_to_file_txt(filename,
+                                "DL IFFT IN IQ Samples in human readable format",
+                                (uint8_t*) p_tx_prach_play_buffer[i],
+                                tx_prach_play_buffer_size[i],
+                                1);
+
+            sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+            sys_save_buf_to_file(filename,
+                                "DL IFFT IN IQ Samples in binary format",
+                                (uint8_t*) p_tx_prach_play_buffer[i],
+                                tx_prach_play_buffer_size[i]/sizeof(short),
+                                sizeof(short));
+        }
     }
     if (startupConfiguration.iqswap == 1){
         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
@@ -936,12 +1236,30 @@ int main(int argc, char *argv[])
                 }
             }
         }
+        if (startupConfiguration.appMode == APP_O_RU){
+            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+                printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
+                {
+                    /* swap I and Q */
+                    int32_t j;
+                    signed short *ptr = (signed short *)  p_tx_prach_play_buffer[i];
+                    signed short temp;
+
+                    for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
+                       temp    = ptr[j];
+                       ptr[j]  = ptr[j + 1];
+                       ptr[j + 1] = temp;
+                    }
+                }
+            }
+        }
+
     }
 
 #if 0
     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "swap_IQ_play_ant%d.txt", i);
+        sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
         sys_save_buf_to_file_txt(filename,
                             "DL IFFT IN IQ Samples in human readable format",
                             (uint8_t*) p_tx_play_buffer[i],
@@ -956,12 +1274,21 @@ int main(int argc, char *argv[])
                 p_tx_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
             }
         }
+
+        if (startupConfiguration.appMode == APP_O_RU){
+            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+                printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
+                for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){
+                    p_tx_prach_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]);
+                }
+            }
+        }
     }
 
 #if 0
     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "swap_be_play_ant%d.txt", i);
+        sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
         sys_save_buf_to_file_txt(filename,
                             "DL IFFT IN IQ Samples in human readable format",
                             (uint8_t*) p_tx_play_buffer[i],
@@ -970,37 +1297,62 @@ int main(int argc, char *argv[])
     }
 #endif
 
+
     timer_set_tsc_freq_from_clock();
-    xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
+    xret =  xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
+    if(xret != XRAN_STATUS_SUCCESS){
+        printf("xran_init failed %d\n", xret);
+        exit(-1);
+    }
+
     if(xranHandle == NULL)
         exit(1);
 
-    memset(&xranConf, 0, sizeof(XRANFHCONFIG));
+    memset(&xranConf, 0, sizeof(struct xran_fh_config));
     pXranConf = &xranConf;
 
-    for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
-        pXranConf->playback_conf.TxPlayBufAddr[i] = (unsigned long)p_tx_play_buffer[i];
-        pXranConf->playback_conf.TxPlayBufSize    = tx_play_buffer_size[i];
-    }
-
     pXranConf->sector_id                        = 0;
     pXranConf->nCC                              = numCCPorts;
     pXranConf->neAxc                            = num_eAxc;
 
-    pXranConf->frame_conf.nFrameDuplexType      = 1;    // TDD
-    pXranConf->frame_conf.nNumerology           = startupConfiguration.mu_number;    // 120KHz; same as XRAN_SCS_120KHz?
-//  pXranConf->frame_conf.nTddPeriod            = ;
+    pXranConf->frame_conf.nFrameDuplexType      = startupConfiguration.nFrameDuplexType;
+    pXranConf->frame_conf.nNumerology           = startupConfiguration.mu_number;
+    pXranConf->frame_conf.nTddPeriod            = startupConfiguration.nTddPeriod;
 
-    pXranConf->prach_conf.nPrachSubcSpacing     = XRAN_SCS_120KHZ;
+    for (i = 0; i < startupConfiguration.nTddPeriod; i++){
+        pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i];
+    }
+
+    pXranConf->prach_conf.nPrachSubcSpacing     = startupConfiguration.mu_number;
     pXranConf->prach_conf.nPrachFreqStart       = 0;
     pXranConf->prach_conf.nPrachFilterIdx       = XRAN_FILTERINDEX_PRACH_ABC;
-    pXranConf->prach_conf.nPrachConfIdx         = 81;
+    pXranConf->prach_conf.nPrachConfIdx         = startupConfiguration.prachConfigIndex;
     pXranConf->prach_conf.nPrachFreqOffset      = -792;
 
     pXranConf->ru_conf.iqWidth                  = 16;
     pXranConf->ru_conf.compMeth                 = XRAN_COMPMETHOD_NONE;
-    pXranConf->ru_conf.fftSize                  = XRAN_FFTSIZE_2048;
+    pXranConf->ru_conf.fftSize                  = 0;
+    while (startupConfiguration.nULFftSize >>= 1)
+        ++pXranConf->ru_conf.fftSize;
+
+    pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER  ;
+    pXranConf->ru_conf.iqOrder   = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;
+
+    printf("FFT Order %d\n", pXranConf->ru_conf.fftSize);
 
+    pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA);
+    pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA);
+
+    nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
+    pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
+    printf("DL center freq %d DL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN);
+
+    nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
+    pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
+    printf("UL center freq %d UL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN);
+
+    pXranConf->bbdev_dec = NULL;
+    pXranConf->bbdev_enc = NULL;
 
     if(init_xran() != 0)
         exit(-1);
@@ -1011,31 +1363,62 @@ int main(int argc, char *argv[])
 
     init_xran_iq_content();
 
-    xran_open(xranHandle, pXranConf);
+    xret = xran_open(xranHandle, pXranConf);
+
+    if(xret != XRAN_STATUS_SUCCESS){
+        printf("xran_open failed %d\n", xret);
+        exit(-1);
+    }
+
+    sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru");
+
+//    MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
 
-    sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "lls-cu" : "ru");
+    MLogOpen(256, 3, 20000, 0xFFFFFFFF, filename);
 
-    MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
     puts("----------------------------------------");
     printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
     puts("----------------------------------------");
 
+
+    uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
+     nActiveCoreMask[0] = 1 << xranInit.io_cfg.timing_core;
+    uint32_t numCarriers = startupConfiguration.numCC;
+
+    MLogAddTestCase(nActiveCoreMask, numCarriers);
+
+    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+
     state = APP_RUNNING;
-    sleep(6);
+    printf("Start XRAN traffic\n");
+    xran_start(xranHandle);
+    sleep(3);
+    print_menu();
     for (;;) {
-        print_menu();
+        struct xran_common_counters x_counters;
         char input[10];
-        int sel_opt;
-//#ifdef Nightly_build
-//        sel_opt = 3;
-//        sleep(10);
-//#else
-        if (NULL == fgets(input, 10, stdin)) {
-            state = APP_STOPPED;
+        sleep(1);
+        xran_curr_if_state = xran_get_if_state();
+        if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) {
+            printf("rx %ld tx %ld  [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld\n", rx_counter, tx_counter,
+                   x_counters.Rx_on_time,
+                   x_counters.Rx_early,
+                   x_counters.Rx_late,
+                   x_counters.Rx_corrupt,
+                   x_counters.Rx_pkt_dupl,
+                   x_counters.Total_msgs_rcvd);
+        } else {
+            printf("error xran_get_common_counters\n");
+        }
+
+        if (xran_curr_if_state == XRAN_STOPPED){
             break;
         }
-        sel_opt = atoi(input);
-//#endif
+        if (NULL == fgets(input, 10, stdin)) {
+            continue;
+        }
+
+        const int sel_opt = atoi(input);
         switch (sel_opt) {
             case 1:
                 xran_start(xranHandle);
@@ -1048,18 +1431,10 @@ int main(int argc, char *argv[])
                 printf("Stop XRAN traffic\n");
                 state = APP_STOPPED;
                 break;
-            case 4:
-//                send_cpmsg_dlul(XRAN_DIR_DL, flowId,
-//                                    frame_id, subframe_id, slot_id,
-//                                    0, XRAN_SYMBOLPERSLOT_MAX, NUM_OF_PRB_IN_FULL_BAND,
-//                                    beam_id, cc_id, ant_id,
-//                                    cp_seq_id_num[XRAN_DIR_DL][ant_id]++);
-                break;
             default:
                 puts("Wrong option passed!");
                 break;
         }
-
         if (APP_STOPPED == state)
             break;
     }
@@ -1102,14 +1477,14 @@ int main(int argc, char *argv[])
 
     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
+        sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
         sys_save_buf_to_file_txt(filename,
                             "UL FFT OUT IQ Samples in human readable format",
                             (uint8_t*) p_rx_log_buffer[i],
                             rx_log_buffer_size[i],
                             1);
 
-        sprintf(filename, "%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+        sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
         sys_save_buf_to_file(filename,
                             "UL FFT OUT IQ Samples in binary format",
                             (uint8_t*) p_rx_log_buffer[i],
@@ -1117,48 +1492,52 @@ int main(int argc, char *argv[])
                             sizeof(short));
     }
 
-    if (startupConfiguration.iqswap == 1){
-        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
-            printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
-            {
-                /* swap I and Q */
-                int32_t j;
-                signed short *ptr = (signed short *)  p_prach_log_buffer[i];
-                signed short temp;
-
-                for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
-                   temp    = ptr[j];
-                   ptr[j]  = ptr[j + 1];
-                   ptr[j + 1] = temp;
+    if (startupConfiguration.appMode == APP_O_DU &&  startupConfiguration.enablePrach){
+        if (startupConfiguration.iqswap == 1){
+            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+                printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
+                {
+                    /* swap I and Q */
+                    int32_t j;
+                    signed short *ptr = (signed short *)  p_prach_log_buffer[i];
+                    signed short temp;
+
+                    for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
+                       temp    = ptr[j];
+                       ptr[j]  = ptr[j + 1];
+                       ptr[j + 1] = temp;
+                    }
                 }
             }
         }
-    }
 
-    if (startupConfiguration.nebyteorderswap == 1){
-        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
-            printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
-            for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
-                p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
+
+        if (startupConfiguration.nebyteorderswap == 1){
+            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+                printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
+                for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
+                    p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
+                }
             }
         }
-    }
 
-    for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
-        sys_save_buf_to_file_txt(filename,
-                            "PRACH FFT OUT IQ Samples in human readable format",
-                            (uint8_t*) p_prach_log_buffer[i],
-                            prach_log_buffer_size[i],
-                            1);
+        for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
 
-        sprintf(filename, "%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
-        sys_save_buf_to_file(filename,
-                            "PRACH FFT OUT IQ Samples in binary format",
-                            (uint8_t*) p_prach_log_buffer[i],
-                            prach_log_buffer_size[i]/sizeof(short),
-                            sizeof(short));
+            sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
+            sys_save_buf_to_file_txt(filename,
+                                "PRACH FFT OUT IQ Samples in human readable format",
+                                (uint8_t*) p_prach_log_buffer[i],
+                                prach_log_buffer_size[i],
+                                1);
+
+            sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+            sys_save_buf_to_file(filename,
+                                "PRACH FFT OUT IQ Samples in binary format",
+                                (uint8_t*) p_prach_log_buffer[i],
+                                prach_log_buffer_size[i]/sizeof(short),
+                                sizeof(short));
+        }
     }
 
     return 0;
index 23a673c..ed6c11d 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file has the System Debug Trace Logger (Mlog) Task IDs used by PHY
  * @file mlog_task_id.h
 #ifndef _XRAN_TASK_ID_H_
 #define _XRAN_TASK_ID_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define RESOURCE_CORE_0                             0
 #define RESOURCE_CORE_1                             1
 #define RESOURCE_CORE_2                             2
 // XRAN APP
 //--------------------------------------------------------------------
 
-#define PID_GNB_PROC_TIMING                     902
-#define PID_GNB_PROC_TIMING_TIMEOUT             903
-#define PID_GNB_SYM_CB                          904
-#define PID_GNB_PRACH_CB                        905
+#define PID_GNB_PROC_TIMING                             70
+#define PID_GNB_PROC_TIMING_TIMEOUT                     71
+#define PID_GNB_SYM_CB                                  72
+#define PID_GNB_PRACH_CB                                73
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _XRAN_TASK_ID_H_ */
 
diff --git a/fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_du.dat b/fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..6bea1cf
--- /dev/null
@@ -0,0 +1,139 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=12 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/12/ant_0.bin    #CC0
+antC1=./usecase/mu0_10mhz/12/ant_1.bin    #CC0
+antC2=./usecase/mu0_10mhz/12/ant_2.bin    #CC0
+antC3=./usecase/mu0_10mhz/12/ant_3.bin    #CC0
+antC4=./usecase/mu0_10mhz/12/ant_4.bin    #CC1
+antC5=./usecase/mu0_10mhz/12/ant_5.bin    #CC1
+antC6=./usecase/mu0_10mhz/12/ant_6.bin    #CC1
+antC7=./usecase/mu0_10mhz/12/ant_7.bin    #CC1
+antC8=./usecase/mu0_10mhz/12/ant_8.bin    #CC2
+antC9=./usecase/mu0_10mhz/12/ant_9.bin    #CC2
+antC10=./usecase/mu0_10mhz/12/ant_10.bin  #CC2
+antC11=./usecase/mu0_10mhz/12/ant_11.bin  #CC2
+antC12=./usecase/mu0_10mhz/12/ant_12.bin  #CC3
+antC13=./usecase/mu0_10mhz/12/ant_13.bin  #CC3
+antC14=./usecase/mu0_10mhz/12/ant_14.bin  #CC3
+antC15=./usecase/mu0_10mhz/12/ant_15.bin  #CC3
+antC16=./usecase/mu0_10mhz/12/ant_0.bin   #CC4
+antC17=./usecase/mu0_10mhz/12/ant_1.bin   #CC4
+antC18=./usecase/mu0_10mhz/12/ant_2.bin   #CC4
+antC19=./usecase/mu0_10mhz/12/ant_3.bin   #CC4
+antC20=./usecase/mu0_10mhz/12/ant_4.bin   #CC5
+antC21=./usecase/mu0_10mhz/12/ant_5.bin   #CC5
+antC22=./usecase/mu0_10mhz/12/ant_6.bin   #CC5
+antC23=./usecase/mu0_10mhz/12/ant_7.bin   #CC5
+antC24=./usecase/mu0_10mhz/12/ant_8.bin   #CC6
+antC25=./usecase/mu0_10mhz/12/ant_9.bin   #CC6
+antC26=./usecase/mu0_10mhz/12/ant_10.bin  #CC6
+antC27=./usecase/mu0_10mhz/12/ant_11.bin  #CC6
+antC28=./usecase/mu0_10mhz/12/ant_12.bin  #CC7
+antC29=./usecase/mu0_10mhz/12/ant_13.bin  #CC7
+antC30=./usecase/mu0_10mhz/12/ant_14.bin  #CC7
+antC31=./usecase/mu0_10mhz/12/ant_15.bin  #CC7
+antC32=./usecase/mu0_10mhz/12/ant_0.bin   #CC8
+antC33=./usecase/mu0_10mhz/12/ant_1.bin   #CC8
+antC34=./usecase/mu0_10mhz/12/ant_2.bin   #CC8
+antC35=./usecase/mu0_10mhz/12/ant_3.bin   #CC8
+antC36=./usecase/mu0_10mhz/12/ant_4.bin   #CC9
+antC37=./usecase/mu0_10mhz/12/ant_5.bin   #CC9
+antC38=./usecase/mu0_10mhz/12/ant_6.bin   #CC9
+antC39=./usecase/mu0_10mhz/12/ant_7.bin   #CC9
+antC40=./usecase/mu0_10mhz/12/ant_8.bin   #CC10
+antC41=./usecase/mu0_10mhz/12/ant_9.bin   #CC10
+antC42=./usecase/mu0_10mhz/12/ant_10.bin  #CC10
+antC43=./usecase/mu0_10mhz/12/ant_11.bin  #CC10
+antC44=./usecase/mu0_10mhz/12/ant_12.bin  #CC11
+antC45=./usecase/mu0_10mhz/12/ant_13.bin  #CC11
+antC46=./usecase/mu0_10mhz/12/ant_14.bin  #CC11
+antC47=./usecase/mu0_10mhz/12/ant_15.bin  #CC11
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_ru.dat b/fhi_lib/app/usecase/mu0_10mhz/12/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..84cff6f
--- /dev/null
@@ -0,0 +1,190 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=12 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70 #lls-CU PF for tcpdump
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/12/ant_0.bin    #CC0
+antC1=./usecase/mu0_10mhz/12/ant_1.bin    #CC0
+antC2=./usecase/mu0_10mhz/12/ant_2.bin    #CC0
+antC3=./usecase/mu0_10mhz/12/ant_3.bin    #CC0
+antC4=./usecase/mu0_10mhz/12/ant_4.bin    #CC1
+antC5=./usecase/mu0_10mhz/12/ant_5.bin    #CC1
+antC6=./usecase/mu0_10mhz/12/ant_6.bin    #CC1
+antC7=./usecase/mu0_10mhz/12/ant_7.bin    #CC1
+antC8=./usecase/mu0_10mhz/12/ant_8.bin    #CC2
+antC9=./usecase/mu0_10mhz/12/ant_9.bin    #CC2
+antC10=./usecase/mu0_10mhz/12/ant_10.bin  #CC2
+antC11=./usecase/mu0_10mhz/12/ant_11.bin  #CC2
+antC12=./usecase/mu0_10mhz/12/ant_12.bin  #CC3
+antC13=./usecase/mu0_10mhz/12/ant_13.bin  #CC3
+antC14=./usecase/mu0_10mhz/12/ant_14.bin  #CC3
+antC15=./usecase/mu0_10mhz/12/ant_15.bin  #CC3
+antC16=./usecase/mu0_10mhz/12/ant_0.bin   #CC4
+antC17=./usecase/mu0_10mhz/12/ant_1.bin   #CC4
+antC18=./usecase/mu0_10mhz/12/ant_2.bin   #CC4
+antC19=./usecase/mu0_10mhz/12/ant_3.bin   #CC4
+antC20=./usecase/mu0_10mhz/12/ant_4.bin   #CC5
+antC21=./usecase/mu0_10mhz/12/ant_5.bin   #CC5
+antC22=./usecase/mu0_10mhz/12/ant_6.bin   #CC5
+antC23=./usecase/mu0_10mhz/12/ant_7.bin   #CC5
+antC24=./usecase/mu0_10mhz/12/ant_8.bin   #CC6
+antC25=./usecase/mu0_10mhz/12/ant_9.bin   #CC6
+antC26=./usecase/mu0_10mhz/12/ant_10.bin  #CC6
+antC27=./usecase/mu0_10mhz/12/ant_11.bin  #CC6
+antC28=./usecase/mu0_10mhz/12/ant_12.bin  #CC7
+antC29=./usecase/mu0_10mhz/12/ant_13.bin  #CC7
+antC30=./usecase/mu0_10mhz/12/ant_14.bin  #CC7
+antC31=./usecase/mu0_10mhz/12/ant_15.bin  #CC7
+antC32=./usecase/mu0_10mhz/12/ant_0.bin   #CC8
+antC33=./usecase/mu0_10mhz/12/ant_1.bin   #CC8
+antC34=./usecase/mu0_10mhz/12/ant_2.bin   #CC8
+antC35=./usecase/mu0_10mhz/12/ant_3.bin   #CC8
+antC36=./usecase/mu0_10mhz/12/ant_4.bin   #CC9
+antC37=./usecase/mu0_10mhz/12/ant_5.bin   #CC9
+antC38=./usecase/mu0_10mhz/12/ant_6.bin   #CC9
+antC39=./usecase/mu0_10mhz/12/ant_7.bin   #CC9
+antC40=./usecase/mu0_10mhz/12/ant_8.bin   #CC10
+antC41=./usecase/mu0_10mhz/12/ant_9.bin   #CC10
+antC42=./usecase/mu0_10mhz/12/ant_10.bin  #CC10
+antC43=./usecase/mu0_10mhz/12/ant_11.bin  #CC10
+antC44=./usecase/mu0_10mhz/12/ant_12.bin  #CC11
+antC45=./usecase/mu0_10mhz/12/ant_13.bin  #CC11
+antC46=./usecase/mu0_10mhz/12/ant_14.bin  #CC11
+antC47=./usecase/mu0_10mhz/12/ant_15.bin  #CC11
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC1=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC2=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC3=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC4=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC5=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC6=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC7=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC8=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC9=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC10=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC11=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC12=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC13=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC14=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC15=./usecase/mu0_10mhz/12/ant_15.bin
+antPrachC16=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC17=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC18=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC19=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC20=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC21=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC22=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC23=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC24=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC25=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC26=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC27=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC28=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC29=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC30=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC31=./usecase/mu0_10mhz/12/ant_15.bin
+antPrachC32=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC33=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC34=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC35=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC36=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC37=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC38=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC39=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC40=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC41=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC42=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC43=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC44=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC45=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC46=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC47=./usecase/mu0_10mhz/12/ant_15.bin
+
+
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_10mhz/config_file_o_du.dat b/fhi_lib/app/usecase/mu0_10mhz/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..7355ab1
--- /dev/null
@@ -0,0 +1,139 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/ant_0.bin    #CC0  
+antC1=./usecase/mu0_10mhz/ant_1.bin    #CC0  
+antC2=./usecase/mu0_10mhz/ant_2.bin    #CC0  
+antC3=./usecase/mu0_10mhz/ant_3.bin    #CC0  
+antC4=./usecase/mu0_10mhz/ant_4.bin    #CC1  
+antC5=./usecase/mu0_10mhz/ant_5.bin    #CC1  
+antC6=./usecase/mu0_10mhz/ant_6.bin    #CC1  
+antC7=./usecase/mu0_10mhz/ant_7.bin    #CC1  
+antC8=./usecase/mu0_10mhz/ant_8.bin    #CC2  
+antC9=./usecase/mu0_10mhz/ant_9.bin    #CC2  
+antC10=./usecase/mu0_10mhz/ant_10.bin  #CC2   
+antC11=./usecase/mu0_10mhz/ant_11.bin  #CC2   
+antC12=./usecase/mu0_10mhz/ant_12.bin  #CC3   
+antC13=./usecase/mu0_10mhz/ant_13.bin  #CC3   
+antC14=./usecase/mu0_10mhz/ant_14.bin  #CC3   
+antC15=./usecase/mu0_10mhz/ant_15.bin  #CC3   
+antC16=./usecase/mu0_10mhz/ant_0.bin   #CC4   
+antC17=./usecase/mu0_10mhz/ant_1.bin   #CC4   
+antC18=./usecase/mu0_10mhz/ant_2.bin   #CC4   
+antC19=./usecase/mu0_10mhz/ant_3.bin   #CC4   
+antC20=./usecase/mu0_10mhz/ant_4.bin   #CC5   
+antC21=./usecase/mu0_10mhz/ant_5.bin   #CC5   
+antC22=./usecase/mu0_10mhz/ant_6.bin   #CC5   
+antC23=./usecase/mu0_10mhz/ant_7.bin   #CC5   
+antC24=./usecase/mu0_10mhz/ant_8.bin   #CC6   
+antC25=./usecase/mu0_10mhz/ant_9.bin   #CC6   
+antC26=./usecase/mu0_10mhz/ant_10.bin  #CC6   
+antC27=./usecase/mu0_10mhz/ant_11.bin  #CC6   
+antC28=./usecase/mu0_10mhz/ant_12.bin  #CC7   
+antC29=./usecase/mu0_10mhz/ant_13.bin  #CC7   
+antC30=./usecase/mu0_10mhz/ant_14.bin  #CC7   
+antC31=./usecase/mu0_10mhz/ant_15.bin  #CC7   
+antC32=./usecase/mu0_10mhz/ant_0.bin   #CC8  
+antC33=./usecase/mu0_10mhz/ant_1.bin   #CC8  
+antC34=./usecase/mu0_10mhz/ant_2.bin   #CC8  
+antC35=./usecase/mu0_10mhz/ant_3.bin   #CC8  
+antC36=./usecase/mu0_10mhz/ant_4.bin   #CC9  
+antC37=./usecase/mu0_10mhz/ant_5.bin   #CC9  
+antC38=./usecase/mu0_10mhz/ant_6.bin   #CC9  
+antC39=./usecase/mu0_10mhz/ant_7.bin   #CC9  
+antC40=./usecase/mu0_10mhz/ant_8.bin   #CC10 
+antC41=./usecase/mu0_10mhz/ant_9.bin   #CC10 
+antC42=./usecase/mu0_10mhz/ant_10.bin  #CC10 
+antC43=./usecase/mu0_10mhz/ant_11.bin  #CC10 
+antC44=./usecase/mu0_10mhz/ant_12.bin  #CC11 
+antC45=./usecase/mu0_10mhz/ant_13.bin  #CC11 
+antC46=./usecase/mu0_10mhz/ant_14.bin  #CC11 
+antC47=./usecase/mu0_10mhz/ant_15.bin  #CC11 
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+bbdevMode=-1 #bbdev mode, -1 = not use bbdev, 0: use software mode, 1: use hardware mode
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_10mhz/config_file_o_ru.dat b/fhi_lib/app/usecase/mu0_10mhz/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..d0d8cce
--- /dev/null
@@ -0,0 +1,145 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/ant_0.bin    #CC0  
+antC1=./usecase/mu0_10mhz/ant_1.bin    #CC0  
+antC2=./usecase/mu0_10mhz/ant_2.bin    #CC0  
+antC3=./usecase/mu0_10mhz/ant_3.bin    #CC0  
+antC4=./usecase/mu0_10mhz/ant_4.bin    #CC1  
+antC5=./usecase/mu0_10mhz/ant_5.bin    #CC1  
+antC6=./usecase/mu0_10mhz/ant_6.bin    #CC1  
+antC7=./usecase/mu0_10mhz/ant_7.bin    #CC1  
+antC8=./usecase/mu0_10mhz/ant_8.bin    #CC2  
+antC9=./usecase/mu0_10mhz/ant_9.bin    #CC2  
+antC10=./usecase/mu0_10mhz/ant_10.bin  #CC2   
+antC11=./usecase/mu0_10mhz/ant_11.bin  #CC2   
+antC12=./usecase/mu0_10mhz/ant_12.bin  #CC3   
+antC13=./usecase/mu0_10mhz/ant_13.bin  #CC3   
+antC14=./usecase/mu0_10mhz/ant_14.bin  #CC3   
+antC15=./usecase/mu0_10mhz/ant_15.bin  #CC3   
+antC16=./usecase/mu0_10mhz/ant_0.bin   #CC4   
+antC17=./usecase/mu0_10mhz/ant_1.bin   #CC4   
+antC18=./usecase/mu0_10mhz/ant_2.bin   #CC4   
+antC19=./usecase/mu0_10mhz/ant_3.bin   #CC4   
+antC20=./usecase/mu0_10mhz/ant_4.bin   #CC5   
+antC21=./usecase/mu0_10mhz/ant_5.bin   #CC5   
+antC22=./usecase/mu0_10mhz/ant_6.bin   #CC5   
+antC23=./usecase/mu0_10mhz/ant_7.bin   #CC5   
+antC24=./usecase/mu0_10mhz/ant_8.bin   #CC6   
+antC25=./usecase/mu0_10mhz/ant_9.bin   #CC6   
+antC26=./usecase/mu0_10mhz/ant_10.bin  #CC6   
+antC27=./usecase/mu0_10mhz/ant_11.bin  #CC6   
+antC28=./usecase/mu0_10mhz/ant_12.bin  #CC7   
+antC29=./usecase/mu0_10mhz/ant_13.bin  #CC7   
+antC30=./usecase/mu0_10mhz/ant_14.bin  #CC7   
+antC31=./usecase/mu0_10mhz/ant_15.bin  #CC7   
+antC32=./usecase/mu0_10mhz/ant_0.bin   #CC8  
+antC33=./usecase/mu0_10mhz/ant_1.bin   #CC8  
+antC34=./usecase/mu0_10mhz/ant_2.bin   #CC8  
+antC35=./usecase/mu0_10mhz/ant_3.bin   #CC8  
+antC36=./usecase/mu0_10mhz/ant_4.bin   #CC9  
+antC37=./usecase/mu0_10mhz/ant_5.bin   #CC9  
+antC38=./usecase/mu0_10mhz/ant_6.bin   #CC9  
+antC39=./usecase/mu0_10mhz/ant_7.bin   #CC9  
+antC40=./usecase/mu0_10mhz/ant_8.bin   #CC10 
+antC41=./usecase/mu0_10mhz/ant_9.bin   #CC10 
+antC42=./usecase/mu0_10mhz/ant_10.bin  #CC10 
+antC43=./usecase/mu0_10mhz/ant_11.bin  #CC10 
+antC44=./usecase/mu0_10mhz/ant_12.bin  #CC11 
+antC45=./usecase/mu0_10mhz/ant_13.bin  #CC11 
+antC46=./usecase/mu0_10mhz/ant_14.bin  #CC11 
+antC47=./usecase/mu0_10mhz/ant_15.bin  #CC11 
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_10mhz/ant_0.bin
+antPrachC1=./usecase/mu0_10mhz/ant_1.bin
+antPrachC2=./usecase/mu0_10mhz/ant_2.bin
+antPrachC3=./usecase/mu0_10mhz/ant_3.bin
+
+
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_20mhz/config_file_o_du.dat b/fhi_lib/app/usecase/mu0_20mhz/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..6913532
--- /dev/null
@@ -0,0 +1,105 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=2048
+nULFftSize=2048
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+antC0=./usecase/mu0_20mhz/ant_0.bin   #CC0
+antC1=./usecase/mu0_20mhz/ant_1.bin   #CC0
+antC2=./usecase/mu0_20mhz/ant_2.bin   #CC0
+antC3=./usecase/mu0_20mhz/ant_3.bin   #CC0
+antC4=./usecase/mu0_20mhz/ant_4.bin   #CC1
+antC5=./usecase/mu0_20mhz/ant_5.bin   #CC1
+antC6=./usecase/mu0_20mhz/ant_6.bin   #CC1
+antC7=./usecase/mu0_20mhz/ant_7.bin   #CC1
+antC8=./usecase/mu0_20mhz/ant_8.bin   #CC2
+antC9=./usecase/mu0_20mhz/ant_9.bin   #CC2
+antC10=./usecase/mu0_20mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_20mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_20mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_20mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_20mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_20mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_20mhz/config_file_o_ru.dat b/fhi_lib/app/usecase/mu0_20mhz/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..e6befa1
--- /dev/null
@@ -0,0 +1,111 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=2048
+nULFftSize=2048
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+antC0=./usecase/mu0_20mhz/ant_0.bin   #CC0
+antC1=./usecase/mu0_20mhz/ant_1.bin   #CC0
+antC2=./usecase/mu0_20mhz/ant_2.bin   #CC0
+antC3=./usecase/mu0_20mhz/ant_3.bin   #CC0
+antC4=./usecase/mu0_20mhz/ant_4.bin   #CC1
+antC5=./usecase/mu0_20mhz/ant_5.bin   #CC1
+antC6=./usecase/mu0_20mhz/ant_6.bin   #CC1
+antC7=./usecase/mu0_20mhz/ant_7.bin   #CC1
+antC8=./usecase/mu0_20mhz/ant_8.bin   #CC2
+antC9=./usecase/mu0_20mhz/ant_9.bin   #CC2
+antC10=./usecase/mu0_20mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_20mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_20mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_20mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_20mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_20mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_20mhz/ant_0.bin
+antPrachC1=./usecase/mu0_20mhz/ant_1.bin
+antPrachC3=./usecase/mu0_20mhz/ant_3.bin
+antPrachC4=./usecase/mu0_20mhz/ant_4.bin
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=0 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_5mhz/config_file_o_du.dat b/fhi_lib/app/usecase/mu0_5mhz/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..5aaf308
--- /dev/null
@@ -0,0 +1,106 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=512
+nULFftSize=512
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu0_5mhz/ant_0.bin   #CC0
+antC1=./usecase/mu0_5mhz/ant_1.bin   #CC0
+antC2=./usecase/mu0_5mhz/ant_2.bin   #CC0
+antC3=./usecase/mu0_5mhz/ant_3.bin   #CC0
+antC4=./usecase/mu0_5mhz/ant_4.bin   #CC1
+antC5=./usecase/mu0_5mhz/ant_5.bin   #CC1
+antC6=./usecase/mu0_5mhz/ant_6.bin   #CC1
+antC7=./usecase/mu0_5mhz/ant_7.bin   #CC1
+antC8=./usecase/mu0_5mhz/ant_8.bin   #CC2
+antC9=./usecase/mu0_5mhz/ant_9.bin   #CC2
+antC10=./usecase/mu0_5mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_5mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_5mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_5mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_5mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_5mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#prachConfigIndex=1 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu0_5mhz/config_file_o_ru.dat b/fhi_lib/app/usecase/mu0_5mhz/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..1cdde48
--- /dev/null
@@ -0,0 +1,105 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=512
+nULFftSize=512
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+antC0=./usecase/mu0_5mhz/ant_0.bin   #CC0
+antC1=./usecase/mu0_5mhz/ant_1.bin   #CC0
+antC2=./usecase/mu0_5mhz/ant_2.bin   #CC0
+antC3=./usecase/mu0_5mhz/ant_3.bin   #CC0
+antC4=./usecase/mu0_5mhz/ant_4.bin   #CC1
+antC5=./usecase/mu0_5mhz/ant_5.bin   #CC1
+antC6=./usecase/mu0_5mhz/ant_6.bin   #CC1
+antC7=./usecase/mu0_5mhz/ant_7.bin   #CC1
+antC8=./usecase/mu0_5mhz/ant_8.bin   #CC2
+antC9=./usecase/mu0_5mhz/ant_9.bin   #CC2
+antC10=./usecase/mu0_5mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_5mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_5mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_5mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_5mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_5mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#prachConfigIndex=1 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400  #in us  
+T2a_max_cp_dl=1120 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us  
+T2a_max_cp_ul=1120 #in us 
+
+#Reception Window U-plane
+T2a_min_up=200  # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu1_100mhz/config_file_o_du.dat b/fhi_lib/app/usecase/mu1_100mhz/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..c343ccf
--- /dev/null
@@ -0,0 +1,116 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=1 #30Khz Sub Carrier Spacing
+
+ttiPeriod=500 # in us TTI period (30Khz default 500us)
+
+nDLAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=4096
+nULFftSize=4096
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=10 #[0-9] DDDSUUDDDD, for S it\92s 6:4:4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,0,0,0,0,0,2,2,2,2,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig4=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55    # RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu1_100mhz/ant_0.bin   #CC0
+antC1=./usecase/mu1_100mhz/ant_1.bin   #CC0
+antC2=./usecase/mu1_100mhz/ant_2.bin   #CC0
+antC3=./usecase/mu1_100mhz/ant_3.bin   #CC0
+antC4=./usecase/mu1_100mhz/ant_4.bin   #CC1
+antC5=./usecase/mu1_100mhz/ant_5.bin   #CC1
+antC6=./usecase/mu1_100mhz/ant_6.bin   #CC1
+antC7=./usecase/mu1_100mhz/ant_7.bin   #CC1
+antC8=./usecase/mu1_100mhz/ant_8.bin   #CC2
+antC9=./usecase/mu1_100mhz/ant_9.bin   #CC2
+antC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 # in us
+              # C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+#Reception Window C-plane DL
+T2a_min_cp_dl=285 # 285.42us
+T2a_max_cp_dl=429 # 428.12us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=285 # 285.42us
+T2a_max_cp_ul=429 # 428.12us
+
+#Reception Window U-plane
+T2a_min_up=71  # 71.35in us
+T2a_max_up=428 # 428.12us
+
+#Transmission Window
+Ta3_min=20 # in us 
+Ta3_max=32 # in us 
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=285
+T1a_max_cp_dl=429
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=285
+T1a_max_cp_ul=300
+
+#U-plane
+##Transmission Window
+T1a_min_up=96  #71 + 25 us
+T1a_max_up=196 #71 + 25 us
+
+#Reception Window
+Ta4_min=0  # in us 
+Ta4_max=75 # in us 
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu1_100mhz/config_file_o_ru.dat b/fhi_lib/app/usecase/mu1_100mhz/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..bed1922
--- /dev/null
@@ -0,0 +1,134 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=1 #30Khz Sub Carrier Spacing
+
+ttiPeriod=500 # in us TTI period (30Khz default 500us)
+
+nDLAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=4096
+nULFftSize=4096
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=10 #[0-9] DDDSUUDDDD, for S it\92s 6:4:4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,0,0,0,0,0,2,2,2,2,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig4=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70
+ruMac=00:11:22:33:44:55    # RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu1_100mhz/ant_0.bin   #CC0
+antC1=./usecase/mu1_100mhz/ant_1.bin   #CC0
+antC2=./usecase/mu1_100mhz/ant_2.bin   #CC0
+antC3=./usecase/mu1_100mhz/ant_3.bin   #CC0
+antC4=./usecase/mu1_100mhz/ant_4.bin   #CC1
+antC5=./usecase/mu1_100mhz/ant_5.bin   #CC1
+antC6=./usecase/mu1_100mhz/ant_6.bin   #CC1
+antC7=./usecase/mu1_100mhz/ant_7.bin   #CC1
+antC8=./usecase/mu1_100mhz/ant_8.bin   #CC2
+antC9=./usecase/mu1_100mhz/ant_9.bin   #CC2
+antC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+antPrachC0=./usecase/mu1_100mhz/ant_0.bin   #CC0
+antPrachC1=./usecase/mu1_100mhz/ant_1.bin   #CC0
+antPrachC2=./usecase/mu1_100mhz/ant_2.bin   #CC0
+antPrachC3=./usecase/mu1_100mhz/ant_3.bin   #CC0
+antPrachC4=./usecase/mu1_100mhz/ant_4.bin   #CC1
+antPrachC5=./usecase/mu1_100mhz/ant_5.bin   #CC1
+antPrachC6=./usecase/mu1_100mhz/ant_6.bin   #CC1
+antPrachC7=./usecase/mu1_100mhz/ant_7.bin   #CC1
+antPrachC8=./usecase/mu1_100mhz/ant_8.bin   #CC2
+antPrachC9=./usecase/mu1_100mhz/ant_9.bin   #CC2
+antPrachC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antPrachC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antPrachC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antPrachC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antPrachC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antPrachC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=1
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 # in us
+              # C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+#Reception Window C-plane DL
+T2a_min_cp_dl=285 # 285.42us
+T2a_max_cp_dl=429 # 428.12us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=285 # 285.42us
+T2a_max_cp_ul=429 # 428.12us
+
+#Reception Window U-plane
+T2a_min_up=71  # 71.35in us
+T2a_max_up=428 # 428.12us
+
+#Transmission Window
+Ta3_min=20 # in us TODO: update
+Ta3_max=32 # in us TODO: update
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=285
+T1a_max_cp_dl=429
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=285
+T1a_max_cp_ul=300
+
+#U-plane
+##Transmission Window
+T1a_min_up=96  #71 + 25 us
+T1a_max_up=196 #71 + 25 us
+
+#Reception Window
+Ta4_min=0  # in us TODO: update
+Ta4_max=75 # in us TODO: update
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu3_100mhz/config_file_o_du.dat b/fhi_lib/app/usecase/mu3_100mhz/config_file_o_du.dat
new file mode 100644 (file)
index 0000000..049aba4
--- /dev/null
@@ -0,0 +1,116 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=3 #mmWave 120Khz Sub Carrier Spacing
+ttiPeriod=125 # in us TTI period (mmWave default 125us)
+nDLAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=4 #[0-5] TDD priod e.g. DDDS 4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+# not used
+#sSlotConfig4=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu3_100mhz/ant_0.bin   #CC0
+antC1=./usecase/mu3_100mhz/ant_1.bin   #CC0
+antC2=./usecase/mu3_100mhz/ant_2.bin   #CC0
+antC3=./usecase/mu3_100mhz/ant_3.bin   #CC0
+antC4=./usecase/mu3_100mhz/ant_4.bin   #CC1
+antC5=./usecase/mu3_100mhz/ant_5.bin   #CC1
+antC6=./usecase/mu3_100mhz/ant_6.bin   #CC1
+antC7=./usecase/mu3_100mhz/ant_7.bin   #CC1
+antC8=./usecase/mu3_100mhz/ant_8.bin   #CC2
+antC9=./usecase/mu3_100mhz/ant_9.bin   #CC2
+antC10=./usecase/mu3_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu3_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu3_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu3_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu3_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu3_100mhz/ant_15.bin #CC3
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=81
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=50 #in us  
+T2a_max_cp_dl=140 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=50 #in us  
+T2a_max_cp_ul=140 #in us 
+
+#Reception Window U-plane
+T2a_min_up=25 #in us
+T2a_max_up=140 #in us
+
+#Transmission Window
+Ta3_min=20 #in us
+Ta3_max=32 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=70
+T1a_max_cp_dl=100
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=60
+T1a_max_cp_ul=70
+
+#U-plane
+##Transmission Window
+T1a_min_up=35
+T1a_max_up=50
+
+#Reception Window
+Ta4_min=0
+Ta4_max=45
+###########################################################
+
diff --git a/fhi_lib/app/usecase/mu3_100mhz/config_file_o_ru.dat b/fhi_lib/app/usecase/mu3_100mhz/config_file_o_ru.dat
new file mode 100644 (file)
index 0000000..1959bcc
--- /dev/null
@@ -0,0 +1,122 @@
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A  (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=3 #mmWave 120Khz Sub Carrier Spacing
+ttiPeriod=125 # in us TTI period (mmWave default 125us)
+nDLAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=4 #[0-5] TDD priod e.g. DDDS 4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+ #not used
+#sSlotConfig4=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single 
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70 #lls-CU PF for tcpdump
+ruMac=00:11:22:33:44:55  #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu3_100mhz/ant_0.bin   #CC0
+antC1=./usecase/mu3_100mhz/ant_1.bin   #CC0
+antC2=./usecase/mu3_100mhz/ant_2.bin   #CC0
+antC3=./usecase/mu3_100mhz/ant_3.bin   #CC0
+antC4=./usecase/mu3_100mhz/ant_4.bin   #CC1
+antC5=./usecase/mu3_100mhz/ant_5.bin   #CC1
+antC6=./usecase/mu3_100mhz/ant_6.bin   #CC1
+antC7=./usecase/mu3_100mhz/ant_7.bin   #CC1
+antC8=./usecase/mu3_100mhz/ant_8.bin   #CC2
+antC9=./usecase/mu3_100mhz/ant_9.bin   #CC2
+antC10=./usecase/mu3_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu3_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu3_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu3_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu3_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu3_100mhz/ant_15.bin #CC3
+
+antPrachC0=./usecase/mu1_100mhz/ant_0.bin   #CC0
+antPrachC1=./usecase/mu1_100mhz/ant_1.bin   #CC0
+antPrachC2=./usecase/mu1_100mhz/ant_2.bin   #CC0
+antPrachC3=./usecase/mu1_100mhz/ant_3.bin   #CC0
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=81
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us  TODO: update per RU implementation
+              #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=50 #in us  
+T2a_max_cp_dl=140 #in us 
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=50 #in us  
+T2a_max_cp_ul=140 #in us 
+
+#Reception Window U-plane
+T2a_min_up=25 #in us
+T2a_max_up=140 #in us
+
+#Transmission Window
+Ta3_min=20 #in us
+Ta3_max=32 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=70
+T1a_max_cp_dl=100
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=60
+T1a_max_cp_ul=70
+
+#U-plane
+##Transmission Window
+T1a_min_up=35
+T1a_max_up=50
+
+#Reception Window
+Ta4_min=0
+Ta4_max=45
+###########################################################
+
index 149ad8a..32d8af0 100644 (file)
 
 XRAN_FH_LIB_DIR=$XRAN_DIR/lib
 XRAN_FH_APP_DIR=$XRAN_DIR/app
+XRAN_FH_TEST_DIR=$XRAN_DIR/test/test_xran
+LIBXRANSO=0
+MLOG=0
+COMMAND_LINE=
 
-echo 'Building XRAN Library'
-cd $XRAN_FH_LIB_DIR 
-make clean; make #DEBUG=1 VERBOSE=1
+echo Number of commandline arguments: $#
+while [[ $# -ne 0 ]]
+do
+key="$1"
 
-echo 'Building XRAN Test Application' 
-cd $XRAN_FH_APP_DIR 
-make clean; make #DEBUG=1 VERBOSE=1
+#echo Parsing: $key
+case $key in
+    LIBXRANSO)
+    LIBXRANSO=1
+    ;;
+    MLOG)
+    MLOG=1
+    ;;
+    xclean)
+    COMMAND_LINE+=$key
+    COMMAND_LINE+=" "
+       ;;
+    *)
+    echo $key is unknown command        # unknown option
+    ;;
+esac
+shift # past argument or value
+done
+
+if [ -z "$MLOG_DIR" ]
+then
+       echo 'MLOG folder is not set. Disable MLOG (MLOG_DIR='$MLOG_DIR')'
+       MLOG=0
+else
+       echo 'MLOG folder is set. Enable MLOG (MLOG_DIR='$MLOG_DIR')'
+       MLOG=1
+fi
+
+echo 'Building xRAN Library'
+echo "LIBXRANSO = ${LIBXRANSO}"
+echo "MLOG      = ${MLOG}"
+
+cd $XRAN_FH_LIB_DIR
+make $COMMAND_LINE MLOG=${MLOG} LIBXRANSO=${LIBXRANSO} #DEBUG=1 VERBOSE=1
+
+echo 'Building xRAN Test Application'
+cd $XRAN_FH_APP_DIR
+make $COMMAND_LINE MLOG=${MLOG} #DEBUG=1 VERBOSE=1
+
+if [ -z ${GTEST_ROOT+x} ];
+then
+    echo "GTEST_ROOT is not set. Unit tests are not compiled";
+else
+       echo 'Building xRAN Test Application ('$GTEST_ROOT')'
+       cd $XRAN_FH_TEST_DIR
+       make clean;
+       make
+fi
 
index d65eef1..7b33916 100644 (file)
 #*   limitations under the License.
 #*
 #*******************************************************************************/
-CC := icc
-AR := xiar
+
+
+MYCUSTOMTAB='     '
+MYCUSTOMSPACE='============================================================================================'
+MYCUSTOMSPACE1='------------------------------------------------------------'
+
+##############################################################
+#  Tools configuration
+##############################################################
+CC  := icc
+CPP := icpc
+AS := as
+AR := ar
+LD := icc
+OBJDUMP := objdump
+
+ifeq ($(SHELL),cmd.exe)
+MD := mkdir.exe -p
+CP := cp.exe -f
+RM := rm.exe -rf
+else
+MD := mkdir -p
+CP := cp -f
+RM := rm -rf
+endif
+
+PROJECT_NAME := libxran
+PROJECT_TYPE := lib
+PROJECT_DIR  := $(XRAN_DIR)/lib
+BUILDDIR := ./build
+PROJECT_BINARY := $(BUILDDIR)/$(PROJECT_NAME).a
 
 ifeq ($(RTE_SDK),)
     $(error "Please define RTE_SDK environment variable")
 endif
 
-RTE_TARGET := x86_64-native-linuxapp-icc
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
 RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-API_DIR := $(PWD)/api
-SRC_DIR := $(PWD)/src
-ETH_DIR := $(PWD)/ethernet
 
+API_DIR := $(PROJECT_DIR)/api
+SRC_DIR := $(PROJECT_DIR)/src
+ETH_DIR := $(PROJECT_DIR)/ethernet
 
+ifeq ($(MLOG),1)
 ifeq ($(MLOG_DIR),)
     MLOG_DIR=$(XRAN_DIR)/../mlog
 endif
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wno-deprecated-declarations -Wextra -Werror -qopt-report-phase:all -qopt-zmm-usage=high \
-       -fdata-sections \
-       -ffunction-sections \
-       -restrict \
-       -g \
-       -Wall \
-       -Wimplicit-function-declaration \
-       -Werror \
-       -Wextra \
-       -no-inline-max-total-size \
-       -no-inline-max-size \
-        -I$(API_DIR) -I$(ETH_DIR) -I$(MLOG_DIR)/source -I$(RTE_INC) -g -O3
-
-ifeq ($(ME),1)
-    CFLAGS += -DMLOG_ENABLED
 endif
-SRC = $(ETH_DIR)/ethdi.c \
+
+CC_SRC = $(ETH_DIR)/ethdi.c \
        $(ETH_DIR)/ethernet.c \
        $(SRC_DIR)/xran_up_api.c \
        $(SRC_DIR)/xran_sync_api.c \
        $(SRC_DIR)/xran_timer.c \
        $(SRC_DIR)/xran_cp_api.c        \
-       $(SRC_DIR)/xran_transport.c  \
+       $(SRC_DIR)/xran_transport.c     \
        $(SRC_DIR)/xran_common.c        \
        $(SRC_DIR)/xran_ul_tables.c     \
-       $(SRC_DIR)/xran_main.c 
+       $(SRC_DIR)/xran_frame_struct.c  \
+       $(SRC_DIR)/xran_app_frag.c \
+       $(SRC_DIR)/xran_main.c
+
+CPP_SRC = $(SRC_DIR)/xran_compression.cpp
+
+CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations  \
+       -fdata-sections \
+       -ffunction-sections \
+       -g \
+       -Wall \
+       -Wimplicit-function-declaration \
+        -g -O3
+
+CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+                -no-prec-div -fp-model fast=2\
+                -no-prec-sqrt  -falign-functions=16 -fast-transcendentals \
+        -Werror -Wno-unused-variable -std=c++11 -mcmodel=large
+
+INC :=  -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) -I$(RTE_INC)
+DEF :=
+ifeq ($(MLOG),1)
+       INC  += -I$(MLOG_DIR)/source
+       DEF += -DMLOG_ENABLED
+else
+       DEF += -UMLOG_ENABLED
+endif
+
+AS_FLAGS :=
+AR_FLAGS := rc
+
+PROJECT_OBJ_DIR := build/obj
 
-FLEX_C_CRAN_LIB = libxran.a
+CC_OBJS := $(patsubst %.c,%.o,$(CC_SRC))
+CPP_OBJS := $(patsubst %.cpp,%.o,$(CPP_SRC))
+AS_OBJS := $(patsubst %.s,%.o,$(AS_SRC))
+OBJS    := $(CC_OBJS) $(CPP_OBJS) $(AS_OBJS) $(LIBS)
+DIRLIST := $(addprefix $(PROJECT_OBJ_DIR)/,$(sort $(dir $(OBJS))))
 
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
+CC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CC_OBJS))
+CPP_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS))
 
+AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
 
-all: flex_lib install
+CC_FLAGS_FULL  := $(CC_FLAGS)  $(INC) $(DEF)
+CPP_FLAGS_FULL := $(CPP_FLAGS) $(INC) $(DEF)
 
-$(OBJ): %.o: %.c
-       $(CC) $(CFLAGS) -I$(API_DIR) -c $< -o $@ 
+AS_FLAGS := $(AS_FLAGS) $(INC)
 
+PROJECT_DEP_FILE := $(PROJECT_OBJ_DIR)/$(PROJECT_NAME).dep
 
-flex_lib:$(FLEX_C_CRAN_LIB)
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+GENERATE_DEPS :=
+else
 
-$(FLEX_C_CRAN_LIB): $(OBJ)
-       $(AR) rsu $@ $^
+CC_DEPS  := $(addprefix __dep__,$(subst ../,__up__,$(CC_SRC)))
+CPP_DEPS  := $(addprefix __dep__,$(subst ../,__up__,$(CPP_SRC)))
+GENERATE_DEPS := generate_deps
+endif
+
+all : welcome_line     $(PROJECT_BINARY)
+       @echo $(PROJECT_BINARY)
+
+.PHONY : clear_dep
+clear_dep:
+       @$(RM) $(PROJECT_DEP_FILE)
+       @echo [DEP]   $(subst $(PROJECT_OBJ_DIR)/,,$(PROJECT_DEP_FILE))
+
+$(CC_DEPS) :
+       @$(CC) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.c,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CC_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+$(CPP_DEPS) :
+       @$(CPP) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.cpp,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CPP_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+.PHONY : generate_deps
+generate_deps : clear_dep $(CC_DEPS) $(CPP_DEPS)
+
+
+.PHONY : echo_start_build
+echo_start_build :
+       @echo [BUILD] $(PROJECT_TYPE) : $(PROJECT_NAME)
+
+$(DIRLIST) :
+       -@$(MD) $@
+
+$(CC_OBJTARGETS) :
+       @echo [CC]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(CC) -c $(CC_FLAGS_FULL) -o"$@" $(patsubst %.o,%.c,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(CPP_OBJTARGETS) :
+       @echo [CPP]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(CPP) -c $(CPP_FLAGS_FULL) -o"$@" $(patsubst %.o,%.cpp,$(subst $(PROJECT_OBJ_DIR)/,,$@))
 
-install: $(FLEX_C_CRAN_LIB)
-       mkdir -p bin
-       @mv $(FLEX_C_CRAN_LIB) ./bin
+$(AS_OBJTARGETS) :
+       @echo [AS]    $(subst $(PROJECT_OBJ_DIR)/,,$@)
+       @$(AS) $(AS_FLAGS) -o"$@" $(patsubst %.o,%.s,$(subst $(PROJECT_OBJ_DIR)/,,$@))
 
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+
+include $(PROJECT_DEP_FILE)
+
+endif
+
+.PHONY: clean xclean
 clean:
-       @rm -rf $(FLEX_C_CRAN_LIB) $(OBJ) ./bin/$(FLEX_C_CRAN_LIB)
+       @echo [CLEAN]  : $(PROJECT_NAME)
+       @$(RM) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+
+xclean: clean
+ifneq ($(wildcard $(PROJECT_DIR)/$(PROJECT_MAKE)),)
+       @echo [XCLEAN] : $(PROJECT_NAME)
+       @$(RM) $(PROJECT_BINARY) $(PROJECT_BINARY_LIB) $(PROJECT_DEP_FILE)
+endif
+
+.PHONY : welcome_line
+welcome_line :
+       @echo $(MYCUSTOMSPACE)
+       @echo Building  $(PROJECT_BINARY)
+       @echo $(MYCUSTOMTAB)RTE_TARGET           = $(RTE_TARGET)
+       @echo $(MYCUSTOMSPACE)
+
+
+.PHONY : debug release
+
+debug :  all
+release :  all
 
-#include $(RTE_SDK)/mk/rte.extlib.mk
+$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+       @echo [AR]    $(subst $(BUILDDIR)/,,$@)
+       @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
diff --git a/fhi_lib/lib/api/xran_compression.hpp b/fhi_lib/lib/api/xran_compression.hpp
new file mode 100644 (file)
index 0000000..a2ee478
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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.
+*
+*******************************************************************************/
+
+#pragma once
+#include <stdint.h>
+
+// This configuration file sets global constants and macros which are
+// of general use throughout the project.
+
+// All current IA processors of interest align their cache lines on
+// this boundary. If the cache alignment for future processors changes
+// then the most restrictive alignment should be set.
+constexpr unsigned k_cacheByteAlignment = 64;
+
+// Force the data to which this macro is applied to be aligned on a cache line.
+// For example:
+//
+// CACHE_ALIGNED float data[64];
+#define CACHE_ALIGNED alignas(k_cacheByteAlignment)
+
+// Hint to the compiler that the data to which this macro is applied
+// can be assumed to be aligned to a cache line. This allows the
+// compiler to generate improved code by using aligned reads and
+// writes.
+#define ASSUME_CACHE_ALIGNED(data) __assume_aligned(data, k_cacheByteAlignment);
+
+/// Intel compiler frequently complains about templates not being declared in an external
+/// header. Templates are used throughout this project's source files to define local type-specific
+/// versions of functions. Defining every one of these in a header is unnecessary, so the warnings
+/// about this are turned off globally.
+#pragma warning(disable:1418)
+#pragma warning(disable:1419)
+
+
+namespace BlockFloatCompander
+{
+  /// Compute 32 RB at a time
+  static constexpr int k_numBitsIQ = 16;
+  static constexpr int k_numRB = 16;
+  static constexpr int k_numRE = 12;
+  static constexpr int k_numREReal = k_numRE * 2;
+  static constexpr int k_numSampsExpanded = k_numRB * k_numREReal;
+  static constexpr int k_numSampsCompressed = k_numSampsExpanded + k_numRB;
+  static constexpr int k_iqWidth = 8;
+
+
+  struct CompressedData
+  {
+    /// Compressed data
+    CACHE_ALIGNED int8_t dataCompressed[k_numSampsCompressed];
+  };
+
+  struct ExpandedData
+  {
+    /// Expanded data or input data to compressor
+    CACHE_ALIGNED int16_t dataExpanded[k_numSampsExpanded];
+  };
+
+  void BlockFloatCompress_AVX512(const ExpandedData& dataIn, CompressedData* dataOut);
+
+  void BlockFloatExpand_AVX512(const CompressedData& dataIn, ExpandedData* dataOut);
+
+  void BlockFloatCompress_Basic(const ExpandedData& dataIn, CompressedData* dataOut);
+
+  void BlockFloatExpand_Basic(const CompressedData& dataIn, ExpandedData* dataOut);
+
+}
index 9d08e42..9972ea1 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the definitions for Control Plane Messages APIs.
  *
 #ifndef _XRAN_CP_API_H_
 #define _XRAN_CP_API_H_
 
-#include "xran_fh_lls_cu.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "xran_fh_o_du.h"
 #include "xran_pkt_cp.h"
+#include "xran_transport.h"
+
+#define XRAN_MAX_SECTIONDB_CTX              2
+
+#define XRAN_MAX_NUM_EXTENSIONS     4       /* Maximum number of extensions in a section */
+#define XRAN_MAX_NUM_UE             16      /* Maximum number of UE */
+#define XRAN_MAX_NUM_ANT_BF         64      /* Maximum number of beamforming antenna,
+                                             * could be defined as XRAN_MAX_ANTENNA_NR */
+/* Maximum total number of beamforming weights (5.4.7.1.2) */
+#define XRAN_MAX_BFW_N              (XRAN_MAX_NUM_ANT_BF*XRAN_MAX_NUM_UE)
+#define XRAN_MAX_MODCOMP_ADDPARMS   2
+
+#define XRAN_SECTIONEXT_ALIGN       4       /* alignment size in byte for section extension */
 
-/* Error Codes
- *  For errors and exceptions, all values will be negative */
-enum xran_errcodes {
-    XRAN_ERRCODE_OK             = 0,
-    XRAN_ERRCODE_INVALIDPARAM,
-    XRAN_ERRCODE_OUTOFMEMORY,
-    XRAN_ERRCODE_FAILTOSEND,
-    XRAN_ERRCODE_INVALIDPACKET,
-    XRAN_ERRCODE_MAX
-    };
 
 /** Control Plane section types, defined in 5.4 Table 5.1 */
 enum xran_cp_sectiontype {
@@ -107,6 +114,11 @@ enum xran_cp_symbolnuminc {
     XRAN_SYMBOLNUMBER_INC_MAX
     };
 
+/** Macro to convert the number of PRBs as defined in 5.4.5.6 */
+#define XRAN_CONVERT_NUMPRBC(x)             ((x) > 255 ? 0 : (x))
+
+#define XRAN_CONVERT_IQWIDTH(x)             ((x) > 15 ? 0 : (x))
+
 /** Minimum number of symbols, defined in 5.4.5.7 */
 #define XRAN_SYMBOLNUMBER_MIN               1
 /** Maximum number of symbols, defined in  5.4.5.7 */
@@ -126,28 +138,131 @@ enum xran_cp_symbolnuminc {
 #define XRAN_LBTMODE_PARTIAL34              2
 #define XRAN_LBTMODE_FULLSTOP               3
 
+
+/** Control Plane section extension commands, defined in 5.4.6 Table 5.13 */
+enum xran_cp_sectionextcmd {
+    XRAN_CP_SECTIONEXTCMD_0 = 0,    /**< Reserved, for future use */
+    XRAN_CP_SECTIONEXTCMD_1 = 1,    /**< Beamforming weights */
+    XRAN_CP_SECTIONEXTCMD_2 = 2,    /**< Beamforming attributes */
+    XRAN_CP_SECTIONEXTCMD_3 = 3,    /**< DL Precoding configuration parameters and indications, not supported */
+    XRAN_CP_SECTIONEXTCMD_4 = 4,    /**< Modulation compression parameter */
+    XRAN_CP_SECTIONEXTCMD_5 = 5,    /**< Modulation compression additional scaling parameters */
+    XRAN_CP_SECTIONEXTCMD_MAX       /* 6~127 reserved for future use */
+    };
+
+/** Macro to convert bfwIqWidth defined in 5.4.7.1.1, Table 5-15 */
+#define XRAN_CONVERT_BFWIQWIDTH(x)          ((x) > 15 ? 0 : (x))
+
+/** Beamforming Weights Compression Method 5.4.7.1.1, Table 5-16 */
+enum xran_cp_bfw_compression_method {
+    XRAN_BFWCOMPMETHOD_NONE         = 0,    /**< Uncopressed I/Q value */
+    XRAN_BFWCOMPMETHOD_BLKFLOAT     = 1,    /**< I/Q mantissa value */
+    XRAN_BFWCOMPMETHOD_BLKSCALE     = 2,    /**< I/Q scaled value */
+    XRAN_BFWCOMPMETHOD_ULAW         = 3,    /**< compressed I/Q value */
+    XRAN_BFWCOMPMETHOD_BEAMSPACE    = 4,    /**< beamspace I/Q coefficient */
+    XRAN_BFWCOMPMETHOD_MAX                  /* reserved for future methods */
+    };
+
+/** Beamforming Attributes Bitwidth 5.4.7.2.1 */
+enum xran_cp_bfa_bitwidth {
+    XRAN_BFABITWIDTH_NO             = 0,    /**< the filed is no applicable or the default value shall be used */
+    XRAN_BFABITWIDTH_2BIT           = 1,    /**< the filed is 2-bit bitwidth */
+    XRAN_BFABITWIDTH_3BIT           = 2,    /**< the filed is 3-bit bitwidth */
+    XRAN_BFABITWIDTH_4BIT           = 3,    /**< the filed is 4-bit bitwidth */
+    XRAN_BFABITWIDTH_5BIT           = 4,    /**< the filed is 5-bit bitwidth */
+    XRAN_BFABITWIDTH_6BIT           = 5,    /**< the filed is 6-bit bitwidth */
+    XRAN_BFABITWIDTH_7BIT           = 6,    /**< the filed is 7-bit bitwidth */
+    XRAN_BFABITWIDTH_8BIT           = 7,    /**< the filed is 8-bit bitwidth */
+    };
+
 /**
  * This structure contains the information to generate the section body of C-Plane message */
 struct xran_section_info {
+    uint8_t     type;       /* type of this section  */
                             /* section type   bit-    */
                             /*  0 1 3 5 6 7    length */
-    uint16_t    id;         /*  X X X X X     12bits */
-    uint8_t     rb;         /*  X X X X X      1bit  */
-    uint8_t     symInc;     /*  X X X X X      1bit  */
-    uint16_t    startPrbc;  /*  X X X X X     10bits */
-    uint8_t     numPrbc;    /*  X X X X X      8bits */
+    uint8_t     startSymId; /*  X X X X X X    4bits */
     uint8_t     numSymbol;  /*  X X X X        4bits */
+    uint8_t     symInc;     /*  X X X X X      1bit  */
+    uint16_t    id;         /*  X X X X X     12bits */
     uint16_t    reMask;     /*  X X X X       12bits */
+    uint16_t    startPrbc;  /*  X X X X X     10bits */
+    uint16_t    numPrbc;    /*  X X X X X      8bits */ /* will be converted to zero if >255 */
+    uint8_t     rb;         /*  X X X X X      1bit  */
+    uint8_t     iqWidth;    /*    X X X        4bits */
+    uint8_t     compMeth;   /*    X X X        4bits */
+    uint8_t     ef;         /*    X X X X      1bit  */
+    int32_t     freqOffset; /*      X         24bits */
     uint16_t    beamId;     /*    X X         15bits */
     uint16_t    ueId;       /*        X X     15bits */
     uint16_t    regFactor;  /*          X     16bits */
-    int32_t     freqOffset; /*      X         24bits */
-    uint8_t     ef;         /*    X X X X      1bit  */
-
-    uint8_t     type;       /* type of this section  */
     uint16_t    pad0;
     };
 
+
+struct xran_sectionext1_info {
+    uint16_t    bfwNumber;                  /* number of bf weights in this section */
+    uint8_t     bfwiqWidth;
+    uint8_t     bfwCompMeth;
+    uint16_t    bfwIQ[XRAN_MAX_BFW_N*2];    /* I/Q pair, max 4KB with 16bits, 16UE and 64ANT */
+    union {
+        uint8_t     exponent;
+        uint8_t     blockScaler;
+        uint8_t     compBitWidthShift;
+        uint8_t     activeBeamspaceCoeffMask[XRAN_MAX_BFW_N];   /* ceil(N/8)*8, should be multiple of 8 */
+        } bfwCompParam;
+    };
+
+struct xran_sectionext2_info {
+    uint8_t     bfAzPtWidth;    /* beamforming zenith beamwidth parameter */
+    uint8_t     bfAzPt;
+    uint8_t     bfZePtWidth;    /* beamforming azimuth beamwidth parameter */
+    uint8_t     bfZePt;
+    uint8_t     bfAz3ddWidth;   /* beamforming zenith pointing parameter */
+    uint8_t     bfAz3dd;
+    uint8_t     bfZe3ddWidth;   /* beamforming azimuth pointing parameter */
+    uint8_t     bfZe3dd;
+
+    uint8_t     bfAzSI;
+    uint8_t     bfZeSI;
+    };
+
+struct xran_sectionext3_info {  /* NOT SUPPORTED */
+    uint8_t     codebookIdx;
+    uint8_t     layerId;
+    uint8_t     numLayers;
+    uint8_t     txScheme;
+    uint16_t    crsReMask;
+    uint8_t     crsShift;
+    uint8_t     crsSymNum;
+    uint16_t    beamIdAP1;
+    uint16_t    beamIdAP2;
+    uint16_t    beamIdAP3;
+    };
+
+struct xran_sectionext4_info {
+    uint8_t     csf;
+    uint8_t     pad0;
+    uint16_t    modCompScaler;
+    };
+
+struct xran_sectionext5_info {
+    uint8_t     num_sets;
+    struct {
+        uint16_t    csf;
+//        uint16_t    pad0;
+        uint16_t    mcScaleReMask;
+        uint16_t    mcScaleOffset;
+        } mc[XRAN_MAX_MODCOMP_ADDPARMS];
+    };
+
+struct xran_sectionext_info {
+    uint16_t    type;
+    uint16_t    len;
+    void        *data;
+    };
+
+
 /**
  * This structure contains the information to generate the section header of C-Plane message */
 struct xran_cp_header_params {
@@ -171,12 +286,15 @@ struct xran_cp_header_params {
 /**
  * This structure to hold the information to generate the sections of C-Plane message */
 struct xran_section_gen_info {
-    struct xran_section_info info; /**< The information for section */
+    struct xran_section_info info;  /**< The information for section */
 
-    uint32_t    exDataSize;
-    /**< Extension or type 6/7 data size, not supported */
-    void        *exData;
-    /*(< The pointer to the extension or type 6/7 data, not supported */
+    uint32_t    exDataSize;         /**< The number of Extensions or type 6/7 data */
+    /** the array to store section extension */
+    struct {
+        uint16_t    type;           /**< the type of section extension */
+        uint16_t    len;            /**< length of extension data */
+        void        *data;          /**< pointer to extension data */
+        } exData[XRAN_MAX_NUM_EXTENSIONS];
     };
 
 /**
@@ -192,8 +310,25 @@ struct xran_cp_gen_params {
     /**< Array of the section information */
     };
 
+/**
+ * This structure to hold the information of RB allocation from PHY
+ * to send data for allocated RBs only. */
+struct xran_cp_rbmap_list {
+    uint16_t    grp_id;     /**< group id for this entry, reserved for future use */
+
+    uint8_t     sym_start;  /**< Start symbol ID */
+    uint8_t     sym_num;    /**< Number of symbols */
+
+    uint16_t    rb_start;   /**< Start RB position */
+    uint16_t    rb_num;     /**< Number of RBs */
+
+    uint16_t    beam_id;    /**< Bean Index */
+    uint8_t     comp_meth;  /**< Compression method */
+    uint8_t     pad0;
+    };
+
 
-uint16_t xran_get_cplength(int cpLength, int uval);
+uint16_t xran_get_cplength(int cpLength);
 int32_t xran_get_freqoffset(int freqOffset, int scs);
 
 int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
@@ -201,20 +336,29 @@ int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
                         uint8_t CC_ID, uint8_t Ant_ID,
                         uint8_t seq_id);
 
+int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
+                    struct xran_cp_gen_params *result,
+                    struct xran_recv_packet_info *pkt_info);
+
 int xran_cp_init_sectiondb(void *pHandle);
 int xran_cp_free_sectiondb(void *pHandle);
 int xran_cp_add_section_info(void *pHandle,
         uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id,
-        struct xran_section_info *info);
+        uint8_t ctx_id, struct xran_section_info *info);
+int xran_cp_add_multisection_info(void *pHandle,
+        uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
+        struct xran_cp_gen_params *gen_info);
 struct xran_section_info *xran_cp_find_section_info(void *pHandle,
         uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id,
-        uint16_t section_id);
+        uint8_t ctx_id, uint16_t section_id);
 struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
         uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id, uint32_t *next);
-int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id);
-int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id);
+        uint8_t ctx_id, uint32_t *next);
+int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
+int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _XRAN_CP_API_H_ */
similarity index 57%
rename from fhi_lib/lib/api/xran_fh_lls_cu.h
rename to fhi_lib/lib/api/xran_fh_o_du.h
index 24bacba..6274662 100644 (file)
 
 
 /**
- * @brief This file provides public interface to XRAN Front Haul layer implementation as defined in the
- *      XRAN-FH.CUS.0-v02.00 spec. Implementation is specific to lls-CU node
- *      for 5G NR Radio Access technology
+ * @brief This file provides public interface to xRAN Front Haul layer implementation as defined in the
+ *      ORAN-WG4.CUS.0-v01.00 spec. Implementation specific to
+ *      Lower Layer Split Central Unit (O-DU): a logical node that includes the eNB/gNB functions as
+ *      listed in section 2.1 split option 7-2x, excepting those functions allocated exclusively to the O-RU.
+ *      The O-DU controls the operation of O-RUs for 5G NR Radio Access technology
  *
- * @file xran_fh_lls_cu.h
+ * @file xran_fh_o_du.h
  * @ingroup group_lte_source_xran
  * @author Intel Corporation
  *
  **/
 
-#ifndef _XRAN_FH_LLS_CU_H_
-#define _XRAN_FH_LLS_CU_H_
+#ifndef _XRAN_FH_O_DU_H_
+#define _XRAN_FH_O_DU_H_
 
 #ifdef __cplusplus
 extern "C" {
@@ -88,31 +90,54 @@ extern "C" {
  *  parameters supplied.  This may be because a particular
  *  capability is not supported by the current implementation. */
 
-/** Macro to calculate TTI number [0:7999] from symbol index [0: 112000-1] used by timing thread */
+#define XRAN_STATUS_INVALID_PACKET (-7)
+/**<
+ *  @ingroup xran
+ *  Recevied packet does not have correct format. */
+
+/** Macro to calculate TTI number from symbol index used by timing thread */
 #define XranGetTtiNum(symIdx, numSymPerTti) (((uint32_t)symIdx / (uint32_t)numSymPerTti))
-/** Macro to calculate Symbol number [0:7] for given slot from symbol index [0: 112000-1] */
+/** Macro to calculate Symbol number for given slot from symbol index  */
 #define XranGetSymNum(symIdx, numSymPerTti) (((uint32_t)symIdx % (uint32_t)numSymPerTti))
-/** Macro to calculate Frame number [0:99] for given tti [0: 7999] */
+/** Macro to calculate Frame number for given tti */
 #define XranGetFrameNum(tti,numSubFramePerSystemFrame, numSlotPerSubFrame)  ((uint32_t)tti / ((uint32_t)numSubFramePerSystemFrame * (uint32_t)numSlotPerSubFrame))
-/** Macro to calculate Subframe number [0:9] for given tti [0: 7999] */
+/** Macro to calculate Subframe number for given tti */
 #define XranGetSubFrameNum(tti, numSlotPerSubFrame, numSubFramePerSystemFrame) (((uint32_t)tti/(uint32_t)numSlotPerSubFrame) % (uint32_t)numSubFramePerSystemFrame)
-/** Macro to calculate Slot number [0:7] for given tti [0: 7999] */
+/** Macro to calculate Slot number */
 #define XranGetSlotNum(tti, numSlotPerSfn) ((uint32_t)tti % ((uint32_t)numSlotPerSfn))
 
-#define XRAN_PORTS_NUM      (1) /**< number of XRAN ports supported */
-#define XRAN_N_FE_BUF_LEN   (80)/** Number of TTIs (slots) */
-#define XRAN_MAX_SECTOR_NR  (4) /**< Max sectors per XRAN port */
-#define XRAN_MAX_ANTENNA_NR (4) /**< Max antenna per port */
-#define XRAN_NUM_OF_SYMBOL_PER_SLOT          ( 14 ) /**< Number of symbols per slot */
+#define XRAN_PORTS_NUM      (1)  /**< number of XRAN ports (aka O-RU devices) supported */
+#define XRAN_N_FE_BUF_LEN   (80) /**< Number of TTIs (slots) */
+#define XRAN_MAX_SECTOR_NR  (12) /**< Max sectors per XRAN port */
+#define XRAN_MAX_ANTENNA_NR (4)  /**< Max antenna per port */
+#define XRAN_NUM_OF_SYMBOL_PER_SLOT  (14) /**< Number of symbols per slot */
+#define XRAN_MAX_TDD_PERIODICITY     (80)   /**< Max TDD pattern period */
+#define XRAN_MAX_CELLS_PER_PORT      (XRAN_MAX_SECTOR_NR) /**< Max cells mapped to XRAN port */
+#define XRAN_COMPONENT_CARRIERS_MAX  (XRAN_MAX_SECTOR_NR) /**< number of CCs */
+#define XRAN_NUM_OF_ANT_RADIO        (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR) /**< Max Number of Antennas supported for all CC on single XRAN port */
+#define XRAN_MAX_PRBS                (275) /**< Max of PRBs per CC per antanna for 5G NR */
 
-#define XRAN_MAX_CELLS_PER_PORT      (4) /**< Max cells mapped to XRAN port */
-#define XRAN_COMPONENT_CARRIERS_MAX  XRAN_MAX_SECTOR_NR /**< number of CCs */
-#define XRAN_NUM_OF_ANT_RADIO        16  /**< Max Number of Antennas supported for all CC on single XRAN port */
 
 #define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */
 #define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */
 
-#define XRAN_STRICT_PARM_CHECK      (1) /**< enable parameter check for C-plane */
+#define XRAN_STRICT_PARM_CHECK               (1) /**< enable parameter check for C-plane */
+
+/* Slot type definition */
+#define XRAN_SLOT_TYPE_INVALID               (0) /**< invalid slot type */
+#define XRAN_SLOT_TYPE_DL                    (1) /**< DL slot */
+#define XRAN_SLOT_TYPE_UL                    (2) /**< UL slot */
+#define XRAN_SLOT_TYPE_SP                    (3) /**< Special slot */
+#define XRAN_SLOT_TYPE_FDD                   (4) /**< FDD slot */
+#define XRAN_SLOT_TYPE_LAST                  (5) /**< MAX slot */
+
+/* symbol type definition */
+#define XRAN_SYMBOL_TYPE_DL                  (0) /**< DL symbol  */
+#define XRAN_SYMBOL_TYPE_UL                  (1) /**< UL symbol  */
+#define XRAN_SYMBOL_TYPE_GUARD               (2) /**< GUARD symbol */
+#define XRAN_SYMBOL_TYPE_FDD                 (3) /**< FDD symbol */
+
+#define XRAN_NUM_OF_SLOT_IN_TDD_LOOP         (80)/**< MAX number of slot for TDD repetition */
 
 //#define _XRAN_DEBUG   /**< Enable debug log */
 //#define _XRAN_VERBOSE /**< Enable verbose log */
@@ -145,6 +170,18 @@ extern "C" {
         __FILE__,                       \
         __LINE__, ##__VA_ARGS__)
 
+enum XranFrameDuplexType
+{
+    XRAN_FDD = 0, XRAN_TDD
+};
+
+enum xran_if_state
+{
+    XRAN_INIT = 0,
+    XRAN_RUNNING,
+    XRAN_STOPPED
+};
+
 /**
  ******************************************************************************
  * @ingroup xran
@@ -159,7 +196,7 @@ enum xran_compression_method {
     XRAN_COMPMETHOD_ULAW        = 3,
     XRAN_COMPMETHOD_MODULATION  = 4,
     XRAN_COMPMETHOD_MAX
-    };
+};
 
 /**
  ******************************************************************************
@@ -176,35 +213,23 @@ enum callback_to_phy_id
     XRAN_CB_MAX /**< max number of callbacks */
 };
 
-typedef int32_t XranStatusInt32; /**< Xran status return value */
+typedef int32_t xran_status_t; /**< Xran status return value */
 
 /** callback function type for Symbol packet */
-typedef void (*XRANFHSYMPROCCB)(void*);
+typedef void (*xran_callback_sym_fn)(void*);
 
 /** Callback function type for TTI event */
-typedef int (*XRANFHTTIPROCCB)(void* );
+typedef int (*xran_fh_tti_callback_fn)(void*);
 
 /** Callback function type packet arrival from transport layer (ETH or IP) */
-typedef void (*XranTransportBlockCallbackFn)(void*, int32_t);
+typedef void (*xran_transport_callback_fn)(void*, int32_t);
+
+/** Callback functions to poll BBdev encoder */
+typedef int16_t (*phy_encoder_poll_fn)(void);
+
+/** Callback functions to poll BBdev secoder */
+typedef int16_t (*phy_decoder_poll_fn)(void);
 
-/**
-* Component Carrier Initialization
-*/
-typedef struct tagXRANCCINIT
-{
-    uint32_t RadioMode; /**< XRAN mode Cat A or Cat B on given CC */
-    uint32_t nTxAnt;    /**< Number of TX antennas */
-    uint32_t nRxAnt;    /**< Number of RX antennas */
-    uint32_t radiobw;   /**< bandwidth id */
-    uint32_t dpdk_port; /**< networking layer port id */
-    char *dpdk_pcie_eth_dev; /**< pcie device for this cc */
-    char *ru_mac_str;       /**< mac address of RU */
-    uint32_t ulAgc;     /**< state of UL AGC (ON/OFF) */
-    uint32_t numCell;   /**< Number of Cells per port per CC */
-    uint32_t phyInsId[XRAN_MAX_CELLS_PER_PORT]; /**< Mapping of Cell ID to CC */
-    uint32_t dpdkRxCore; /**< DPDK RX Core */
-    uint32_t dpdkTxCore; /**< DPDK TX Core */
-}XRANCCINIT, *PXRANCCINIT;
 
 /** XRAN port enum */
 enum xran_vf_ports
@@ -214,22 +239,47 @@ enum xran_vf_ports
     XRAN_VF_MAX
 };
 
-/** DPDK IO configuration for XRAN layer */
-typedef struct tagXRAN_IO_LOOP_CFG
+/** XRAN category enum */
+enum xran_category
+{
+    XRAN_CATRGORY_A = 0,
+    XRAN_CATRGORY_B = 1,
+    XRAN_CATRGORY_MAX
+};
+
+/** type of beamforming */
+enum xran_beamforming_type
 {
-    uint8_t id;
-    char *dpdk_dev[XRAN_VF_MAX];
-    int core;
-    int system_core;    /* Needed as DPDK will change your starting core. */
-    int pkt_proc_core;  /* Needed for packet processing thread. */
-    int pkt_aux_core;   /* Needed for debug purposes. */
-    int timing_core;    /* Needed for getting precise time */
-    int port[XRAN_VF_MAX];  /* This is auto-detected, no need to set. */
-}XRAN_IO_LOOP_CFG, *PXRAN_IO_LOOP_CFG;
+    XRAN_BEAM_ID_BASED = 0, /**< beam index based */
+    XRAN_BEAM_WEIGHT,       /**< beam forming weights */
+    XRAN_BEAM_ATTRIBUTE,    /**< beam index based */
+};
 
-/** XRAN spec section 3.1.3.1.6 ecpriRtcid / ecpriPcid define */
-typedef struct tagXRANEAXCIDCONFIG
+/** state of bbdev with xran */
+enum xran_bbdev_init
 {
+    XRAN_BBDEV_NOT_USED    = -1, /**< BBDEV is disabled */
+    XRAN_BBDEV_MODE_HW_OFF = 0,  /**< BBDEV is enabled for SW sim mode */
+    XRAN_BBDEV_MODE_HW_ON  = 1,  /**< BBDEV is enable for HW */
+    XRAN_BBDEV_MODE_MAX
+};
+
+/** DPDK IO configuration for XRAN layer */
+struct xran_io_cfg {
+    uint8_t id; /**< should be (0) for O-DU or (1) O-RU (debug) */
+    char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices  */
+    char *bbdev_dev[1];     /**< BBDev dev name */
+    int32_t bbdev_mode;     /**< DPDK for BBDev */
+    int32_t core;           /**< reservd */
+    int32_t system_core;    /**< reservd */
+    int32_t pkt_proc_core;  /**< reservd */
+    int32_t pkt_aux_core;   /**< reservd */
+    int32_t timing_core;    /**< core used by xRAN */
+    int32_t port[XRAN_VF_MAX];  /**< VFs ports */
+};
+
+/** XRAN spec section 3.1.3.1.6 ecpriRtcid / ecpriPcid define */
+struct xran_eaxcid_config {
     uint16_t mask_cuPortId;     /**< Mask CU PortId */
     uint16_t mask_bandSectorId; /**< Mask Band */
     uint16_t mask_ccId;         /**< Mask CC */
@@ -237,35 +287,27 @@ typedef struct tagXRANEAXCIDCONFIG
 
     uint8_t bit_cuPortId;       /**< bandsectorId + ccId + ruportId */
     uint8_t bit_bandSectorId;   /**< ccId + ruPortId */
-    uint8_t bit_ccId;           /**<  ruportId */
-    uint8_t bit_ruPortId;       /**<  0 */
-}XRANEAXCIDCONFIG, *PXRANEAXCIDCONFIG;
+    uint8_t bit_ccId;           /**< ruportId */
+    uint8_t bit_ruPortId;       /**< 0 */
+};
 
 /**
 * XRAN Front haul interface initialization settings
 */
-typedef struct tagXRANFHINIT
-{
-    uint32_t llscuId;    /**< lls-cu ID */
-    uint32_t nSec;       /**< number of sectors, shall be 1 */
-    XRANCCINIT ccCfg[XRAN_COMPONENT_CARRIERS_MAX]; /**< configuration of each CCs */
-    XRANEAXCIDCONFIG eAxCId_conf; /**< config of ecpriRtcid/ecpriPcid */
-    uint32_t radio_iface;         /**< enable/disable radio */
-    uint32_t dpdkMasterCore;      /**< master core of DPDK */
-    uint32_t dpdkMemorySize;      /**< huge pages allocation for DPDK */
-    uint32_t dpdkIrqMode;         /**< DPDK IRQ or PMD mode */
+struct xran_fh_init {
+    struct xran_io_cfg io_cfg;/**< DPDK IO for XRAN */
+    struct xran_eaxcid_config eAxCId_conf; /**< config of ecpriRtcid/ecpriPcid */
+
     uint32_t dpdkBasebandFecMode; /**< DPDK Baseband FEC device mode (0-SW, 1-HW) */
     char *dpdkBasebandDevice;     /**< DPDK Baseband device address */
-    uint32_t singleThreadTxRx;
-    uint32_t bbuPoolCores;  /**< DPDK cores for BBU pool */
-    uint32_t radioEnabled;  /**< reserved */
-    uint32_t powerSaveEn;   /**< reserved */
-    char *filePrefix;       /**< DPDK prefix */
-    XRAN_IO_LOOP_CFG io_cfg;/**< DPDK IO for XRAN */
-    uint8_t xranMode;       /**< mode: lls-CU or RU */
-    int8_t *p_lls_cu_addr;  /**<  lls-CU Ethernet Mac Address */
-    int8_t *p_ru_addr;      /**<  RU Ethernet Mac Address */
-    uint32_t ttiPeriod;     /**< TTI period */
+    char *filePrefix;             /**< DPDK prefix */
+
+    enum xran_category xranCat;   /**< mode: Catergory A or Category B */
+
+    uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+                       xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
+    int8_t   *p_o_du_addr;  /**<  O-DU Ethernet Mac Address */
+    int8_t   *p_o_ru_addr;  /**<  O-RU Ethernet Mac Address */
 
     uint16_t Tadv_cp_dl;    /**< Table 2 7 : xRAN Delay Management Model Parameters */
     uint16_t T2a_min_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
@@ -285,158 +327,157 @@ typedef struct tagXRANFHINIT
     uint16_t Ta4_min;       /**< Table 2 7 : xRAN Delay Management Model Parameters */
     uint16_t Ta4_max;       /**< Table 2 7 : xRAN Delay Management Model Parameters */
 
-    uint8_t enableCP;    /**<  enable C-plane */
-    uint8_t cp_vlan_tag; /**<  C-plane vlan tag */
-    uint8_t up_vlan_tag; /**<  U-plane vlan tag */
-    int32_t debugStop;   /**<  enable auto stop */
-} XRANFHINIT, *PXRANFHINIT;
+    uint8_t enableCP;       /**<  enable C-plane */
+    uint8_t prachEnable;    /**<  enable PRACH   */
+    uint8_t cp_vlan_tag;    /**<  C-plane vlan tag */
+    uint8_t up_vlan_tag;    /**<  U-plane vlan tag */
+    int32_t debugStop;      /**<  enable auto stop */
+    int32_t debugStopCount;      /**<  enable auto stop after number of Tx packets */
+    int32_t DynamicSectionEna; /**<  enable dynamic C-Plane section allocation */
+};
 
-/** XRAN Playback format */
-typedef enum {
-    XRAN_RADIO_PLAYBACK_TIME_DOMAIN = 0,
-    XRAN_RADIO_PLAYBACK_FREQ_DOMAIN = 1
-} XranPlaybackFormatEnum;
+struct xran_cp_bf_weight{
+    int16_t weight[64];
+};
+struct xran_cp_bf_attribute{
+    int16_t weight[4];
+};
+struct xran_cp_bf_precoding{
+    int16_t weight[4];
+};
+
+/** PRB element structure */
+struct xran_prb_elm {
+    int16_t nRBStart; /**< start RB of RB allocation */
+    int16_t nRBSize;  /**< number of RBs used */
+    int16_t nStartSymb; /**< start symbol ID */
+    int16_t numSymb;  /**< number of symbol */
+    int16_t nBeamIndex; /**< beam index for given PRB */
+    int16_t compMethod; /**< compression index for given PRB */
+    int16_t BeamFormingType;
+    union {
+        struct xran_cp_bf_attribute bf_attribute;
+        struct xran_cp_bf_precoding bf_precoding;
+    };
+};
+
+/** PRB map structure */
+struct xran_prb_map {
+    uint8_t   dir;        /**< DL or UL direction */
+    uint8_t   xran_port;  /**< xran id of given RU [0-(XRAN_PORTS_NUM-1)] */
+    uint16_t  band_id;    /**< xran band id */
+    uint16_t  cc_id;      /**< componnent carrier id [0 - (XRAN_MAX_SECTOR_NR-1)] */
+    uint16_t  ru_port_id; /**< RU device antenna port id [0 - (XRAN_MAX_ANTENNA_NR-1) */
+    uint16_t  tti_id;     /**< xRAN slot id [0 - (max tti-1)] */
+    uint8_t   start_sym_id;     /**< start symbol Id [0-13] */
+    uint8_t   bf_weight_update;     /**need to update beam weight or not*/
+    uint32_t  nPrbElm;    /**< total number of PRBs for given map [0- (XRAN_MAX_PRBS-1)] */
+    struct xran_prb_elm prbMap[XRAN_MAX_PRBS];
+    struct xran_cp_bf_weight bf_weight;
+};
 
 /* PRACH config required for XRAN based FH */
-typedef struct tagXRANPRACHCONFIG
+struct xran_prach_config
 {
-    /**** word 5 *****/
     /* PRACH config*/
-    /** PRACH Configuration Index*/
-    uint8_t      nPrachConfIdx;
-    /** PRACH Sub-carrier spacing
+    uint8_t      nPrachConfIdx;  /**< PRACH Configuration Index*/
+    uint8_t      nPrachSubcSpacing;
+    /**< PRACH Sub-carrier spacing
     Value:0->1
     For below 6GHz the values indicate 15kHz or 30kHz
     For above 6GHz the values indicate 60kHz or 120kHz*/
-    /*PRACH zeroCorrelationZoneConfig */
-    uint8_t      nPrachSubcSpacing;
-    /** PRACH zeroCorrelationZoneConfig */
-    uint8_t      nPrachZeroCorrConf;
-    /** PRACH restrictedSetConfig */
-    uint8_t      nPrachRestrictSet;
-
-    /**** word 6 *****/
-    /** PRACH Root Sequence Index */
-    uint16_t     nPrachRootSeqIdx;
-    /** PRACH prach-frequency-start  */
-    uint16_t     nPrachFreqStart;
-
-    /** PRACH prach-frequency-offset */
-    int32_t     nPrachFreqOffset;
-    /** PRACH Filter index */
-    uint8_t     nPrachFilterIdx;
-}XRANPRACHCONFIG, *PXRANPRACHCONFIG;
-
-/** XRAN front haul playback configuration (not supported in 19.03) */
-typedef struct tagXRANFHPLAYBACK
-{
-    XranPlaybackFormatEnum TxPlayFormatType; /**< type of play back files [Time|Freq] */
-
-    unsigned long TxPlayBufAddr[XRAN_NUM_OF_ANT_RADIO]; /**< pointer to buffers to play */
-    uint32_t TxPlayBufSize; /**< Buffer size */
-
-    char*      TxPlayFileName[XRAN_NUM_OF_ANT_RADIO]; /**< files to play */
-    uint32_t   TxPlayFileSize; /**< expected the same size for all Ant */
-
-}XRANPLAYBACKCONFIG,*PXRANPLAYBACKCONFIG;
-
-/** XRAN front haul logging configuration (not supported in 19.03) */
-typedef struct tagXRANFHLOGCONF
-{
-    /* logging */
-    unsigned long TxLogBufAddr;
-    uint32_t TxLogBufSize;
-
-    unsigned long TxLogIfftInAddr;
-    uint32_t  TxLogIfftInSize;
-
-    unsigned long TxLogIfft1200InAddr;
-    uint32_t  TxLogIfft1200InSize;
-
-    unsigned long RxLogFftOutAddr;
-    uint32_t  RxLogFftOutSize;
-
-    unsigned long RxLogFftOutExpAddr;
-    uint32_t  RxLogFftOutExpSize;
-
-    unsigned long RxLogFftOutGainAddr;
-    uint32_t  RxLogFftOutGainSize;
-
-    unsigned long RxLogBufAddr;
-    uint32_t  RxLogBufSize;
-
-    unsigned long RxLogAlawBufAddr;
-    uint32_t  RxLogAlawBufSize;
+    uint8_t      nPrachZeroCorrConf; /**< PRACH zeroCorrelationZoneConfig */
+    uint8_t      nPrachRestrictSet;  /**< PRACH restrictedSetConfig */
+    uint16_t     nPrachRootSeqIdx; /**< PRACH Root Sequence Index */
+    uint16_t     nPrachFreqStart;  /**< PRACH prach-frequency-start  */
+    int32_t      nPrachFreqOffset; /**< PRACH prach-frequency-offset */
+    uint8_t      nPrachFilterIdx;  /**< PRACH Filter index */
+};
 
-    unsigned long RxLogPrachBufAddr;
-    uint32_t  RxLogPrachBufSize;
+/** XRAN slot configuration */
+struct xran_slot_config {
+    uint8_t nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT]; /**< Defines the Symbol type for all 14 symbols in a slot. 0: DL, 1: UL, 2: Guard */
+    uint8_t reserved[2];
+};
 
-    uint32_t  cfg_dl_iq_buf_enabled;
-    uint32_t  cfg_ul_iq_buf_enabled;
+/** XRAN front haul frame config */
+struct xran_frame_config {
+    uint8_t      nFrameDuplexType; /**< Frame Duplex type:  0 -> FDD, 1 -> TDD */
+    uint8_t      nNumerology; /**< Numerology, determine sub carrier spacing, Value: 0->4
+                                   0: 15khz,  1: 30khz,  2: 60khz
+                                   3: 120khz, 4: 240khz */
+    uint8_t      nTddPeriod;  /**< TDD period */
+    struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
+    /**< TDD Slot configuration - If nFrameDuplexType = TDD(1), then this config defines the slot config type for each slot.*/
+    /* The number of slots need to be equal to nTddPeriod */
+};
 
-}XRANFHLOGCONF, *PXRANFHLOGCONF;
+/** XRAN-PHY interface byte order */
+enum xran_input_byte_order {
+    XRAN_NE_BE_BYTE_ORDER = 0, /**< Network byte order (Big endian), xRAN lib doesn't do swap */
+    XRAN_CPU_LE_BYTE_ORDER     /**< CPU byte order (Little endian), xRAN lib does do swap */
+};
 
-/** XRAN front haul frame config */
-typedef struct tagXRANFRAMECONFIG
-{
-    /** Frame Duplex type:  0 -> FDD, 1 -> TDD */
-    uint8_t      nFrameDuplexType;
-    /** Numerology, determine sub carrier spacing, Value: 0->4
-       0: 15khz,  1: 30khz,  2: 60khz
-       3: 120khz, 4: 240khz */
-    uint8_t      nNumerology;
-    /** TDD period */
-    uint8_t      nTddPeriod;
-}XRANFRAMECONFIG, *PXRANFRAMECONFIG;
-
-/** XRAN front haul BBU pooling config */
-typedef struct tagXRANBBUPOOLCONFIG
-{
-    uint32_t isBbuPool; /**< FH running with BBU pool */
-}XRANBBUPOOLCONFIG, *PXRANBBUPOOLCONFIG;
+/** XRAN-PHY interface I and Q order */
+enum xran_input_i_q_order {
+    XRAN_I_Q_ORDER = 0,  /**< I , Q */
+    XRAN_Q_I_ORDER       /**< Q , I */
+};
 
 /** XRAN front haul IQ compression settings */
-typedef struct tagXRANRUCONFIG
-{
+struct xran_ru_config {
     uint8_t iqWidth;        /**< IQ bit width */
     uint8_t compMeth;       /**< Compression method */
     uint8_t fftSize;        /**< FFT Size */
-}XRANRUCONFIG, *PXRANRUCONFIG;
-
-/** XRAN front haul Phase compensation settings */
-typedef struct
-{
-    uint32_t nSecNum;
-    uint32_t nPhaseCompFlag;
-    uint32_t nDlArfcn[XRAN_MAX_SECTOR_NR];
-    uint32_t nUlArfcn[XRAN_MAX_SECTOR_NR];
-}XRANPHASECompConfig;
+    enum xran_input_byte_order byteOrder; /**< Order of bytes in int16_t in buffer. Big or little endian */
+    enum xran_input_i_q_order  iqOrder;   /**< order of IQs in the buffer */
+};
 
 /**
  * @ingroup xran
- *XRAN front haul general configuration */
-typedef struct tagXRANFHCONFIG
-{
+ * XRAN front haul general configuration */
+struct xran_fh_config {
     uint32_t            dpdk_port; /**< DPDK port number used for FH */
     uint32_t            sector_id; /**< Band sector ID for FH */
     uint32_t            nCC;       /**< number of Component carriers supported on FH */
-    uint32_t            neAxc;     /**< number of eAxc supported on FH */
-    XRANPLAYBACKCONFIG  playback_conf;/**< configuration of playback of IQs supported with FH */
-    XRANFHLOGCONF       log_conf;     /**< config of logging functionality supported by FH */
-    XRANFHTTIPROCCB     ttiCb;        /**< call back for TTI event */
+    uint32_t            neAxc;     /**< number of eAxc supported on one CC*/
+    uint16_t            nDLFftSize;  /**< DL FFT size */
+    uint16_t            nULFftSize;  /**< UL FFT size */
+    uint16_t            nDLRBs;      /**< DL PRB  */
+    uint16_t            nULRBs;      /**< UL PRB  */
+    uint32_t            nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+    uint32_t            nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+    uint32_t            nDLCenterFreqARFCN;   /**< center frerquency for DL in MHz */
+    uint32_t            nULCenterFreqARFCN;   /**< center frerquency for UL in MHz */
+    xran_fh_tti_callback_fn     ttiCb;        /**< call back for TTI event */
     void                *ttiCbParam;  /**< parameters of call back function */
-    XRANPRACHCONFIG     prach_conf;   /**< PRACH specific configurations for FH */
-    XRANFRAMECONFIG     frame_conf;   /**< frame config */
-    XRANBBUPOOLCONFIG   bbu_conf;     /**< BBU pool config */
-    XRANRUCONFIG        ru_conf;      /**< config of RU as per XRAN spec */
-    XRANPHASECompConfig phase_compensation; /**< phase compensation settings */
-}XRANFHCONFIG, *PXRANFHCONFIG;
 
+    struct xran_prach_config     prach_conf;   /**< PRACH specific configurations for FH */
+    struct xran_frame_config     frame_conf;   /**< frame config */
+    struct xran_ru_config        ru_conf;      /**< config of RU as per XRAN spec */
+
+    phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
+    phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
+
+    uint32_t log_level; /**< configuration of log level */
+};
+
+/**
+ * @ingroup xran
+ * XRAN front haul statistic counters according to Table 7 1 : Common Counters for both DL and UL */
+struct xran_common_counters{
+    uint64_t Rx_on_time;      /**< Data was received on time (applies to user data reception window) */
+    uint64_t Rx_early;        /**< Data was received too early (applies to user data reception window) */
+    uint64_t Rx_late;         /**< Data was received too late (applies to user data reception window) */
+    uint64_t Rx_corrupt;      /**< Corrupt/Incorrect header packet */
+    uint64_t Rx_pkt_dupl;     /**< Duplicated packet */
+    uint64_t Total_msgs_rcvd; /**< Total messages received (on all links) */
+};
 
 /**
  * @ingroup xran
  * CC instance handle pointer type */
-typedef void * XranCcInstanceHandleVoidP;
+typedef void * xran_cc_handle_t;
 
 /**
  *****************************************************************************
@@ -448,7 +489,7 @@ typedef void * XranCcInstanceHandleVoidP;
  *      buffer segment may contain several equally sized elements.
  *
  *****************************************************************************/
-typedef struct XRANFlatBuffer
+struct xran_flat_buffer
 {
     uint32_t nElementLenInBytes;
     /**< The Element length specified in bytes.
@@ -465,7 +506,9 @@ typedef struct XRANFlatBuffer
     /**< The data pointer is a virtual address, however the actual data pointed
      * to is required to be in contiguous physical memory unless the field
      requiresPhysicallyContiguousMemory in CpaInstanceInfo is false. */
-} XRANFlatBufferStruct;
+    void *pCtrl;
+    /**< pointer to control section coresponding to data buffer */
+};
 
 /**
  *****************************************************************************
@@ -485,11 +528,11 @@ typedef struct XRANFlatBuffer
  *      the pPrivateMetaData memory.
  *
  *****************************************************************************/
-typedef struct XRANBufferList
+struct xran_buffer_list
 {
     uint32_t nNumBuffers;
     /**< Number of pointers */
-    XRANFlatBufferStruct *pBuffers;
+    struct xran_flat_buffer *pBuffers;
     /**< Pointer to an unbounded array containing the number of CpaFlatBuffers
      * defined by nNumBuffers */
     void *pUserData;
@@ -501,7 +544,7 @@ typedef struct XRANBufferList
      * cpaCyBufferListGetMetaSize. If cpaCyBufferListGetMetaSize returns a size
      * of zero no memory needs to be allocated, and this parameter can be NULL.
      */
-} XRANBufferListStruct;
+};
 
 /**
  * @ingroup xran
@@ -519,7 +562,7 @@ typedef struct XRANBufferList
  *   0 - on success
  *   Error codes returned via rte_errno
  */
-int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle);
+int32_t xran_init(int argc, char *argv[], struct xran_fh_init *p_xran_fh_init, char *appName, void ** pHandle);
 
 /**
  * @ingroup xran
@@ -532,13 +575,13 @@ int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appN
  * @param nNumInstances
  *   total number of instances of CC
  * @param pSectorInstanceHandles
- *   Pointer to XranCcInstanceHandleVoidP where to store Handle pointer
+ *   Pointer to xran_cc_handle_t where to store Handle pointer
  *
  * @return
  *   0 - on success
  */
 int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
-               XranCcInstanceHandleVoidP * pSectorInstanceHandles);
+               xran_cc_handle_t * pSectorInstanceHandles);
 
 /**
  * @ingroup xran
@@ -587,13 +630,16 @@ int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfB
  *   Pointer to XRAN layer handle for given CC
  * @param nPoolIndex
  *   buffer pool identification
- * @param ppVirtAddr
+ * @param ppData
  *   Pointer to pointer where to store address of new buffer
+ * @param ppCtrl
+ *   Pointer to pointer where to store address of internal private control information
+ *
  *
  * @return
  *   0 - on success
  */
-int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr);
+int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData,  void **ppCtrl);
 
 /**
  * @ingroup xran
@@ -602,13 +648,15 @@ int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVi
  *
  * @param pHandle
  *   Pointer to XRAN layer handle for given CC
- * @param pVirtAddr
+ * @param pData
  *   Pointer to buffer
+ * @param pData
+ *   Pointer to internal private control information
  *
  * @return
  *   0 - on success
  */
-int32_t xran_bm_free_buffer(void * pHandle, void *pVirtAddr);
+int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl);
 
 /**
  * @ingroup xran
@@ -633,9 +681,13 @@ int32_t xran_mm_destroy (void * pHandle);
  *   Pointer to XRAN layer handle for given CC
  * @param pSrcBuffer
  *   list of memory buffers to use to fetch IQs from PHY to XRAN layer (DL)
+ * @param pSrcCpBuffer
+ *   list of memory buffers to use to configure C-plane (DL)
  * @param pDstBuffer
  *   list of memory buffers to use to deliver IQs from XRAN layer to PHY (UL)
- * @param XranTransportBlockCallbackFn pCallback
+ * @param pDstCpBuffer
+ *   list of memory buffers to use to configure C-plane (UL)
+ * @param xran_transport_callback_fn pCallback
  *   Callback function to call with arrival of all packets for given CC for given symbol
  * @param pCallbackTag
  *   Parameters of Callback function
@@ -644,11 +696,13 @@ int32_t xran_mm_destroy (void * pHandle);
  *   0  - on success
  *   -1 - on error
  */
-int32_t xran_5g_fronthault_config (void * pHandle,
-                XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XranTransportBlockCallbackFn pCallback,
-                void *pCallbackTag);
+ int32_t xran_5g_fronthault_config (void * pHandle,
+                    struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                    struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                    struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                    struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                    xran_transport_callback_fn pCallback,
+                    void *pCallbackTag);
 
 /**
  * @ingroup xran
@@ -659,7 +713,7 @@ int32_t xran_5g_fronthault_config (void * pHandle,
  *   Pointer to XRAN layer handle for given CC
  * @param pDstBuffer
  *   list of memory buffers to use to deliver PRACH IQs from xran layer to PHY
- * @param XranTransportBlockCallbackFn pCallback
+ * @param xran_transport_callback_fn pCallback
  *   Callback function to call with arrival of PRACH packets for given CC
  * @param pCallbackTag
  *   Parameters of Callback function
@@ -669,30 +723,9 @@ int32_t xran_5g_fronthault_config (void * pHandle,
  *   -1 - on error
  */
 int32_t xran_5g_prach_req (void *  pHandle,
-                XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XranTransportBlockCallbackFn pCallback,
+                struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                xran_transport_callback_fn pCallback,
                 void *pCallbackTag);
-/**
- * @ingroup xran
- *
- *   Function configures phase compensation for RU via XRAN layer with given handle
- *
- * @param pHandle
- *   Pointer to XRAN layer handle for given CC
- * @param nTxPhaseCps
- *   TX(DL) phase compensation settings
- * @param nTxPhaseCps
- *   RX(UL) phase compensation settings
- * @param nSectorId
- *   Sector id to use with given settings
- *
- * @return
- *   0 - on success
- */
-int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
-                uint32_t nTxPhaseCps,
-                uint32_t nRxPhaseCps,
-                uint8_t nSectorId);
 
 /**
  * @ingroup xran
@@ -701,13 +734,13 @@ int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
  *
  * @param pHandle
  *   Pointer to XRAN layer handle for given CC
- * @param PXRANFHCONFIG pConf
+ * @param pointer to struct xran_fh_config pConf
  *   Pointer to XRAN configuration structure with specific settings to use
  *
  * @return
  *   0 - on success
  */
-int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf);
+int32_t xran_open(void *pHandle, struct xran_fh_config* pConf);
 
 /**
  * @ingroup xran
@@ -768,7 +801,7 @@ int32_t xran_close(void *pHandle);
  *    0 - in case of success
  *   -1 - in case of failure
  */
-int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb, uint8_t ant);
+int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant);
 
 /**
  * @ingroup xran
@@ -791,7 +824,7 @@ int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam,
  *    0 - in case of success
  *   -1 - in case of failure
  */
-int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id);
+int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id);
 
 /**
  * @ingroup xran
@@ -815,8 +848,27 @@ int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, in
  */
 int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx,  uint32_t *nSlotIdx, uint64_t *nSecond);
 
+/**
+ * @ingroup xran
+ *
+ *   Function retrun XRAN layer common counters for given handle
+ *
+ * @param pHandle
+ *   Pointer to XRAN layer handle for given CC
+ *
+ * @param pStats
+ *   Pointer to pointer of common counter structure
+ *
+ * @return
+ *   0 - on success
+ */
+int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats);
+
+enum xran_if_state xran_get_if_state(void);
+
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* _XRAN_FH_LLS_CU_H_*/
+#endif /* _XRAN_FH_O_DU_H_*/
similarity index 89%
rename from fhi_lib/lib/src/mlog_lnx_xRAN.h
rename to fhi_lib/lib/api/xran_mlog_lnx.h
index 5494045..8629009 100644 (file)
 *
 *******************************************************************************/
 
-#ifndef _MLOG_LNX_XRAN_H_
-#define _MLOG_LNX_XRAN_H_
+
+#ifndef _XRAN_MLOG_LNX_H_
+#define _XRAN_MLOG_LNX_H_
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
+#ifdef MLOG_ENABLED
+#include <mlog_lnx.h>
+#else
+
+/* stubs for MLOG functions */
 #define MLOG_FALSE                  ( 0 )
 
 #define MLogOpen(a, b, c, d, e)     MLOG_FALSE
@@ -47,9 +53,11 @@ extern "C"
 #define MLogAddTestCase(a, b)       MLOG_FALSE
 #define MLogAddPowerStats(a, b, c, d, e) MLOG_FALSE
 
+#endif /* MLOG_ENABLED */
+
 #ifdef __cplusplus
 }
 #endif /* #ifdef __cplusplus */
 
-#endif  /* #ifndef _MLOG_LNX_H_ */
+#endif  /* #ifndef _XRAN_MLOG_LNX_H_ */
 
index 112ea41..69a17f2 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief Definitions and support functions to process XRAN packet
  * @file xran_pkt.h
@@ -24,7 +23,9 @@
  * @author Intel Corporation
  **/
 
-/* XRAN-FH.CUS.0-v02.01.03 xRAN Front haul Working Group Control, User and Synchronization Plane Specification */
+/* ORAN-WG4.CUS.0-v01.00 O-RAN Fronthaul Working Group
+                         Control, User and Synchronization Plane Specification
+*/
 
 /*
  * Layer common to data and control packets
 #ifndef _XRAN_PKT_H_
 #define _XRAN_PKT_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <rte_common.h>
 #include <rte_ether.h>
 #include <rte_byteorder.h>
 
-
 /**
  *****************************************************************************
  * @file xran_pkt.h
@@ -92,9 +96,9 @@ enum ecpri_msg_type
  *****************************************************************************/
 struct ecpri_seq_id
 {
-    uint8_t seq_id:8; /**< Sequence ID */
-    uint8_t sub_seq_id:7; /**< Subsequence ID */
-    uint8_t e_bit:1;  /**< E bit */
+    uint8_t seq_id:8;       /**< Sequence ID */
+    uint8_t sub_seq_id:7;   /**< Subsequence ID */
+    uint8_t e_bit:1;        /**< E bit */
 } __rte_packed;
 
 
@@ -106,54 +110,13 @@ struct ecpri_seq_id
  *       Structure holds common eCPRI header as per
  *       Table 3 1 : eCPRI Transport Header Field Definitions
  *****************************************************************************/
-struct xran_ecpri_hdr
+struct xran_ecpri_cmn_hdr
 {
-    uint8_t ecpri_concat:1; /**< This parameter indicates when eCPRI concatenation is in use
-                            (allowing multiple eCPRI messages in a single Ethernet payload).
-                            NOTE: This parameter is part of the eCPRI common header. */
-    uint8_t ecpri_resv:3; /**< This parameter is reserved for eCPRI future use.
-                               NOTE: This parameter is part of the eCPRI common header. */
-    uint8_t ecpri_ver:4; /**< This parameter indicates the eCPRI protocol version.
-                              NOTE: This parameter is part of the eCPRI common header. */
-    uint8_t ecpri_mesg_type:8; /**< This parameter indicates the type of service conveyed by
-                               the message type. NOTE: This parameter is part of the eCPRI
-                               common header. NOTE: In this version of the specification,
-                               only values "0000 0000b" and "0000 0010b" and "0000 0101b" are used. */
-    rte_be16_t ecpri_payl_size:16; /**< This parameter is the size in bytes of the payload part
-                                    of the corresponding eCPRI message. It does not include any padding bytes
-                                    following the eCPRI message. The maximum supported payload size is 216-1,
-                                    but the actual size may be further limited by the maximum payload size of
-                                    the underlying transport network. NOTE: This parameter is part of the
-                                    eCPRI common header. */
-
-    rte_be16_t ecpri_xtc_id;  /**< 3.1.3.1.6 This parameter is a component_eAxC identifier (c_eAxC ID) and
-                            identifies the specific data flow associated with each C-Plane (ecpriRtcid) or
-                            U-Plane (ecpriPcid) message.  It is the analog of CPRI's "AxC" (antenna-carrier)
-                            value so is designated here as "eAxC" ("e" for "extended" to accommodate multiple
-                            bands and multiple component carriers).  In addition, the "eAxC" is divided into
-                            "component eAxC" parts (c_eAxC) because multiple lls-CU processors may contribute
-                            to a single eAxC and must be identified for correct data routing. */
-
-    struct ecpri_seq_id ecpri_seq_id; /**< This parameter provides unique message identification and ordering on
-        two different levels. The first octet of this parameter is the Sequence ID, which is used to identify ordering of
-        messages within an eAxC message stream.  The Sequence ID field increments and wraps independently for each U-Plane
-        eAxC DL, U-Plane eAxC UL, C-Plane eAxC DL, and C-Plane eAxC UL, even if they share the same eAxC ID.
-        The Sequence ID is used to verify that all messages are received and also to reorder messages that are received out of order.
-        The second octet of this parameter is the Subsequence ID. The Subsequence ID is used to verify ordering and implement
-        reordering when radio-transport-level (eCPRI or IEEE-1914.3) fragmentation occurs.
-        Radio-transport (eCPRI or IEEE-1914.3) fragmentation is a method of splitting U-plane messages containing one or
-        more sections whose length exceeds the maximum packet or message length of the underlying protocol.
-        The Subsequence ID field consists of a 7 bit Subsequence counter and a single bit field, called E-bit.
-        The Subsequence number increments starting from zero for each fragment of a U-plane message.  The E bit
-        is used to indicate the last message of the radio-transport level fragments.  It is always set to zero
-        except for the last message of the U-plane fragment. In the case of C-plane messages radio-transport
-        fragmentation is not allowed, therefore the Subsequence ID shall be set to zero, and the E bit set to one.
-        See Section 3.1.4 for a description of the fragmentation process.
-        NOTE: As an alternative to radio-transport-level fragmentation, application fragmentation can be implemented.
-        In this case the application can take the responsibility to ensure all transport messages are not too long
-        (fit within the necessary transport payload size).  When this "application layer fragmentation" is used,
-        the subsequence identifier shall always be set to "0", and the E-bit set to "1" (See Section 3.1.4). */
-
+    uint8_t     ecpri_concat:1;     /**< 3.1.3.1.3 eCPRI concatenation indicator */
+    uint8_t     ecpri_resv:3;       /**< 3.1.3.1.2 eCPRI reserved */
+    uint8_t     ecpri_ver:4;        /**< 3.1.3.1.1 eCPRI protocol revision, defined in XRAN_ECPRI_VER */
+    uint8_t     ecpri_mesg_type;    /**< 3.1.3.1.4 eCPRI message type, defined in ecpri_msg_type */
+    uint16_t    ecpri_payl_size;    /**< 3.1.3.1.5 eCPRI payload size, without common header and any padding bytes */
 } __rte_packed;
 
 /**
@@ -161,15 +124,16 @@ struct xran_ecpri_hdr
  * @ingroup xran_common_pkt
  *
  * @description
- *       Structure holds complete xran packet header
- *       3.1.1 Ethernet Encapsulation
+ *       Structure holds eCPRI transport header as per
+ *       Table 3 1 : eCPRI Transport Header Field Definitions
  *****************************************************************************/
-struct xran_pkt_hdr
+struct xran_ecpri_hdr
 {
-    struct ether_hdr eth_hdr; /**< Ethernet Header */
-    struct vlan_hdr vlan_hdr; /**< VLAN Header */
-    struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
-};
+    struct xran_ecpri_cmn_hdr cmnhdr;
+    rte_be16_t ecpri_xtc_id;            /**< 3.1.3.1.6 real time control data / IQ data transfer message series identifier */
+    struct ecpri_seq_id ecpri_seq_id;   /**< 3.1.3.1.7 message identifier */
+} __rte_packed;
+
 
 /**
  ******************************************************************************
@@ -258,4 +222,22 @@ struct compression_hdr
     */
 } __rte_packed;
 
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ *       Structure holds common xran packet header
+ *       3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct xran_pkt_comm_hdr
+{
+    struct ether_hdr eth_hdr; /**< Ethernet Header */
+    struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 0f0e1ba..28453b6 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the definition of Control Plane Messages
  *      for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
 #ifndef _XRAN_PKT_CP_H_
 #define _XRAN_PKT_CP_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 
 /**********************************************************************
  * Common structures for C/U-plane
@@ -85,7 +88,7 @@ struct xran_cp_radioapp_frameStructure {
  *      Section headers definition for C-Plane.
  *      Section type 6 and 7 are not present since those have different fields.
  */
-struct xran_cp_radioapp_section_header {    // 8bytes, need the conversion for byte order
+struct xran_cp_radioapp_section_header {    /* 8bytes, need the conversion for byte order */
     union {
         struct {
             uint32_t    reserved:16;
@@ -112,7 +115,7 @@ struct xran_cp_radioapp_section_header {    // 8bytes, need the conversion for b
             } s5;
         } u;
 
-    uint32_t    numPrbc:8;              /**< 5.4.5.6 number of contiguous PRBs per control section */
+    uint32_t    numPrbc:8;              /**< 5.4.5.6 number of contiguous PRBs per control section  0000 0000b = all PRBs */
     uint32_t    startPrbc:10;           /**< 5.4.5.4 starting PRB of control section */
     uint32_t    symInc:1;               /**< 5.4.5.3 symbol number increment command XRAN_SYMBOLNUMBER_xxxx */
     uint32_t    rb:1;                   /**< 5.4.5.2 resource block indicator, XRAN_RBIND_xxx */
@@ -120,6 +123,186 @@ struct xran_cp_radioapp_section_header {    // 8bytes, need the conversion for b
     } __attribute__((__packed__));
 
 
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      Beamforming Weights Extension Type(ExtType 1) defined in 5.4.7.1
+ *      The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext1 {
+    /* variable length, need to be careful to convert byte order
+     *   - does not need to convert first 3 bytes */
+    uint8_t     extType:7;          /**< 5.4.6.1 extension type */
+    uint8_t     ef:1;               /**< 5.4.6.2 extension flag */
+    uint8_t     extLen;             /**< 5.4.6.3 extension length, in 32bits words */
+    uint8_t     bfwCompMeth:4;      /**< 5.4.7.1.1 Beamforming weight Compression method */
+    uint8_t     bfwIqWidth:4;       /**< 5.4.7.1.1 Beamforming weight IQ bit width */
+
+    /*
+     * would be better to use bit manipulation directly to add these parameters
+     *
+     * bfwCompParam
+     * (bfwI,  bfwQ)+
+     *    ......
+     * padding for 4-byte alignment
+     */
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      Beamforming Attributes Extension Type(ExtType 2) defined in 5.4.7.2
+ *      The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext2 {
+    /* variable length, need to be careful to convert byte order
+     *   - first 4 bytes can be converted at once
+     */
+    uint32_t    bfZe3ddWidth:3;     /**< 5.4.7.2.1 beamforming zenith beamwidth parameter bitwidth, Table 5-21 */
+    uint32_t    bfAz3ddWidth:3;     /**< 5.4.7.2.1 beamforming azimuth beamwidth parameter bitwidth, Table 5-20 */
+    uint32_t    bfaCompResv1:2;
+    uint32_t    bfZePtWidth:3;      /**< 5.4.7.2.1 beamforming zenith pointing parameter bitwidth, Table 5-19 */
+    uint32_t    bfAzPtWidth:3;      /**< 5.4.7.2.1 beamforming azimuth pointing parameter bitwidth, Table 5-18 */
+    uint32_t    bfaCompResv0:2;
+    uint32_t    extLen:8;           /**< 5.4.6.3 extension length, in 32bits words */
+    uint32_t    extType:7;          /**< 5.4.6.1 extension type */
+    uint32_t    ef:1;               /**< 5.4.6.2 extension flag */
+
+    /*
+     * would be better to use bit manipulation directly to add these parameters
+     *
+     * bfAzPt: var by bfAzPtWidth
+     * bfZePt: var by bfZePtWidth
+     * bfAz3dd: var by bfAz3ddWidth
+     * bfZe3dd: var by bfZe3ddWidth
+     * bfAzSI:5 (including zero-padding for unused bits)
+     * bfZeSI:3
+     * padding for 4-byte alignment
+     *
+     */
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      DL Precoding Extension Type(ExtType 3) for first data layer.
+ *      Defined in 5.4.7.3 Table 5-22.
+ *      Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
+ *      The structure is reordered for byte order conversion. Not supported.
+ */
+struct xran_cp_radioapp_section_ext3_first {
+    /* 16 bytes, need to convert byte order for two parts
+     *   - 8 / 8 bytes
+     */
+    uint32_t    reserved1:8;
+    uint32_t    crsSymNum:4;        /**< 5.4.7.3.6 CRS symbol number indication */
+    uint32_t    reserved0:3;
+    uint32_t    crsShift:1;         /**< 5.4.7.3.7 CRS shift used for DL transmission */
+    uint32_t    crsReMask:12;       /**< 5.4.7.3.5 CRS resource element mask */
+    uint32_t    txScheme:4;         /**< 5.4.7.3.3 transmission scheme */
+    uint32_t    numLayers:4;        /**< 5.4.7.3.4 number of layers used for DL transmission */
+    uint32_t    layerId:4;          /**< 5.4.7.3.2 Layer ID for DL transmission */
+    uint32_t    codebookIndex:8;    /**< 5.4.7.3.1 precoder codebook used for transmission */
+    uint32_t    extLen:8;           /**< 5.4.6.3 extension length, in 32bits words */
+    uint32_t    extType:7;          /**< 5.4.6.1 extension type */
+    uint32_t    ef:1;               /**< 5.4.6.2 extension flag */
+
+    uint16_t    beamIdAP3;          /**< 5.4.7.3.10 beam id to be used for antenna port 3 */
+    uint16_t    beamIdAP2;          /**< 5.4.7.3.9 beam id to be used for antenna port 2 */
+    uint16_t    beamIdAP1;          /**< 5.4.7.3.8 beam id to be used for antenna port 1 */
+    uint16_t    reserved2;
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      DL Precoding Extension Type(ExtType 3) for non-first data layer.
+ *      Defined in 5.4.7.3 Table 5-23.
+ *      Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
+ *      The structure is reordered for byte order conversion. Not supported.
+ */
+struct xran_cp_radioapp_section_ext3_non_first {
+    /* 4 bytes, need to convert byte order at once */
+    uint32_t    numLayers:4;        /**< 5.4.7.3.4 number of layers used for DL transmission */
+    uint32_t    layerId:4;          /**< 5.4.7.3.2 Layer ID for DL transmission */
+    uint32_t    codebookIndex:8;    /**< 5.4.7.3.1 precoder codebook used for transmission */
+
+    uint32_t    extLen:8;           /**< 5.4.6.3 extension length, in 32bits words */
+    uint32_t    extType:7;          /**< 5.4.6.1 extension type */
+    uint32_t    ef:1;               /**< 5.4.6.2 extension flag */
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      Modulation Compression Parameter Extension Type(ExtType 4), 5.4.7.4
+ *      Only applies to section type 1 and 3.
+ *      The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext4 {
+    /* 4 bytes, need to convert byte order at once */
+    uint32_t    modCompScaler:15;   /**< 5.4.7.4.2 modulation compression scaler value */
+    uint32_t    csf:1;              /**< 5.4.7.4.1 constellation shift flag */
+
+    uint32_t    extLen:8;           /**< 5.4.6.3 extension length, in 32bits words */
+    uint32_t    extType:7;          /**< 5.4.6.1 extension type */
+    uint32_t    ef:1;               /**< 5.4.6.2 extension flag */
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      Modulation Compression Additional Parameter Extension Type(ExtType 5) for one scaler value.
+ *      Defined in 5.4.7.5 Table 5-26
+ *      Only applies to section type 1 3, and 5.
+ *      The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext5_1 {
+    /* 8 bytes, need to convert byte order at once */
+    uint32_t    reserved:20;
+    uint32_t    mcScaleOffset:15;   /**< 5.4.7.5.3 scaling value for modulation compression */
+    uint32_t    csf:1;              /**< 5.4.7.5.2 constellation shift flag */
+    uint32_t    mcScaleReMask:12;   /**< 5.4.7.5.1 modulation compression power scale RE mask */
+
+    uint32_t    extLen:8;           /**< 5.4.6.3 extension length, in 32bits words */
+    uint32_t    extType:7;          /**< 5.4.6.1 extension type */
+    uint32_t    ef:1;               /**< 5.4.6.2 extension flag */
+    } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ *      Modulation Compression Additional Parameter Extension Type(ExtType 5) for two scaler values.
+ *      Defined in 5.4.7.5 Table 5-27
+ *      Only applies to section type 1 3, and 5.
+ *      The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext5_2 {
+    /* 12 bytes, need to convert byte order for two parts respectively
+     *  - 2 and 8 bytes, reserved1 would be OK if it is zero
+     */
+    uint16_t     extLen:8;          /**< 5.4.6.3 extension length, in 32bits words */
+    uint16_t     extType:7;         /**< 5.4.6.1 extension type */
+    uint16_t     ef:1;              /**< 5.4.6.2 extension flag */
+
+    uint32_t    reserved0:8;
+    uint32_t    mcScaleOffset2:15;  /**< 5.4.7.5.3 scaling value for modulation compression */
+    uint32_t    csf2:1;             /**< 5.4.7.5.2 constellation shift flag */
+    uint32_t    mcScaleReMask2:12;  /**< 5.4.7.5.1 modulation compression power scale RE mask */
+    uint32_t    mcScaleOffset1:15;  /**< 5.4.7.5.3 scaling value for modulation compression */
+    uint32_t    csf1:1;             /**< 5.4.7.5.2 constellation shift flag */
+    uint32_t    mcScaleReMask1:12;  /**< 5.4.7.5.1 modulation compression power scale RE mask */
+
+    uint16_t    reserved1;
+    } __attribute__((__packed__));
+
 /**********************************************************
  * Scheduling and Beam-forming Commands 5.4.2
  **********************************************************/
@@ -283,5 +466,8 @@ struct xran_cp_radioapp_section7_header {
     // Payload start from here          // 5.4.5.16 ~ 5.4.5.32
     } __attribute__((__packed__));
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif  /* _XRAN_PKT_CP_H_ */
index a2399f0..588d3e1 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief Definitions and support functions to process XRAN packet
  * @file xran_pkt_up.h
 #ifndef _XRAN_PKT_UP_H_
 #define _XRAN_PKT_UP_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "xran_pkt.h"
 
 #define IQ_PAIR_NUM_IN_RB 12
@@ -72,7 +75,7 @@ struct data_section_hdr {
             uint32_t     sect_id:12;    /**< 5.4.5.1 section identifier */
         };
     }fields;
-    } __attribute__((__packed__));
+} __rte_packed;
 
 
 /*
@@ -116,7 +119,7 @@ union compression_params {
         uint8_t compShift:4;
         uint8_t compBitWidth:4;
         } uLaw;
-    } __attribute__((__packed__));
+} __rte_packed;
 
 
 /*
@@ -133,6 +136,40 @@ struct rb_map
 {
     int16_t i_sample:IQ_BITS; /**< This parameter is the In-phase sample value */
     int16_t q_sample:IQ_BITS; /**< This parameter is the Quadrature sample value */
-} __rte_packed;;
+} __rte_packed;
+
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ *       Structure holds complete xran u-plane packet header
+ *       3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct xran_up_pkt_hdr
+{
+    struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
+    struct radio_app_common_hdr app_hdr; /**< eCPRI Transport Header */
+    struct data_section_hdr data_sec_hdr;
+} __rte_packed;
+
+
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ *       Structure holds complete ethernet and xran u-plane packet header
+ *       3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct eth_xran_up_pkt_hdr
+{
+    struct ether_hdr eth_hdr;
+    struct xran_up_pkt_hdr xran_hdr;
+}__rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 2e98311..3be0dec 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides interface to synchronization related APIs (PTP/1588)
  *        for XRAN.
 #ifndef _XRAN_SYNC_API_H_
 #define _XRAN_SYNC_API_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * @brief Function checks if machine is synchronized using PTP for Linux
  *        software.
@@ -38,4 +41,8 @@
  */
 int xran_is_synchronized(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _XRAN_SYNC_API_H_ */
index d44b5e0..bb4cecd 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides interface to Timing for XRAN.
  *
 
 #ifndef _XRAN_TIMER_H
 #define _XRAN_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <time.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 long poll_next_tick(long interval_ns);
 long sleep_next_tick(long interval);
-int timing_set_debug_stop(int value);
+int timing_set_debug_stop(int value, int count);
 int timing_get_debug_stop(void);
 inline uint64_t timing_get_current_second(void);
+int timing_set_numerology(uint8_t value);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 6d69c3e..bf88759 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the definitions for Transport layer (eCPRI) API.
  *
 #ifndef _XRAN_TRANSPORT_H_
 #define _XRAN_TRANSPORT_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <rte_common.h>
 #include <rte_mbuf.h>
 
@@ -39,36 +42,37 @@ struct xran_eaxc_info {
     uint8_t bandSectorId;
     uint8_t ccId;
     uint8_t ruPortId;
-    };
+};
 
-/**
- * @brief Compose ecpriRtcid/ecpriPcid
- *
- * @param CU_Port_ID CU Port ID
- * @param BanbSector_ID Band Sector ID
- * @param CC_ID Component Carrier ID
- * @param Ant_ID RU Port ID (antenna ID)
- * @return uint16_t composed ecpriRtcid/ecpriPcid
- */
-uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID);
+struct xran_recv_packet_info {
+    int ecpri_version;
+    enum ecpri_msg_type msg_type;
+    int payload_len;
+    struct xran_eaxc_info eaxc;
+    int seq_id;
+    int subseq_id;
+    int ebit;
+};
 
-/**
- * @brief Decompose ecpriRtcid/ecpriPcid
- *
- * @param cid composed ecpriRtcid/ecpriPcid (network byte order)
- * @param result the pointer of the structure to store decomposed values
- * @return none
- */
-void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result);
 
-/**
- * @brief modify the payload size of eCPRI header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet which has eCPRI header already
- * @param size payload size to be updated
- * @return none
- */
+int xran_get_ecpri_hdr_size(void);
 void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size);
 
+uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID);
+void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result);
+
+int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
+                        uint8_t CC_ID, uint8_t Ant_ID,
+                        uint8_t seq_id,
+                        struct xran_ecpri_hdr **ecpri_hdr);
+
+int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
+                        struct xran_ecpri_hdr **ecpri_hdr,
+                        struct xran_recv_packet_info *pkt_info);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 
index 4665762..bedcce0 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the definitions for User Plane Messages APIs.
  *
 #ifndef _XRAN_UP_API_H_
 #define _XRAN_UP_API_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <rte_common.h>
 #include <rte_mbuf.h>
 
 #include "xran_pkt.h"
 #include "xran_pkt_up.h"
 
-#define XRAN_BYTE_ORDER_SWAP
-
 /*
  * structure used for storing packet parameters needed for generating
  * a data packet
@@ -102,15 +103,26 @@ int xran_extract_iq_samples(struct rte_mbuf *mbuf,
     uint8_t *subframe_id,
     uint8_t *slot_id,
     uint8_t *symb_id,
-    struct ecpri_seq_id *seq_id);
+    struct ecpri_seq_id *seq_id,
+    uint16_t *num_prbu,
+    uint16_t *start_prbu,
+    uint16_t *sym_inc,
+    uint16_t *rb,
+    uint16_t *sect_id);
 
 int xran_prepare_iq_symbol_portion_no_comp(
                         struct rte_mbuf *mbuf,
                         const void *iq_data_start,
+                        const enum xran_input_byte_order iq_buf_byte_order,
                         const uint32_t iq_data_num_bytes,
                         struct xran_up_pkt_gen_no_compression_params *params,
                         uint8_t CC_ID,
                         uint8_t Ant_ID,
-                        uint8_t seq_id);
+                        uint8_t seq_id,
+                        uint32_t do_copy);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _XRAN_UP_API_H_ */
index 3664ecc..3f919b4 100644 (file)
@@ -24,6 +24,7 @@
  * @author Intel Corporation
  **/
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
 
 #include "ethernet.h"
 #include "ethdi.h"
-#ifndef MLOG_ENABLED
-#include "../src/mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_fh_o_du.h"
+#include "xran_mlog_lnx.h"
+#include "xran_printf.h"
 
 #include "../src/xran_lib_mlog_tasks_id.h"
 
+#define BURST_RX_IO_SIZE 48
+
 struct xran_ethdi_ctx g_ethdi_ctx = { 0 };
 enum xran_if_state xran_if_current_state = XRAN_STOPPED;
 
@@ -102,13 +103,13 @@ int xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype)
     res = xran_enqueue_mbuf(mb, ctx->tx_ring[ETHDI_CP_VF]);
     return res;
 }
-
+#if 0
 void xran_ethdi_stop_tx()
 {
     struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
     rte_timer_stop_sync(&ctx->timer_tx);
 }
-
+#endif
 
 struct {
     uint16_t ethertype;
@@ -200,22 +201,124 @@ int xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time)
     return xran_handle_ether(rte_be_to_cpu_16(eth_hdr->ether_type), pkt, rx_time);
 }
 
+#if 0
+//-------------------------------------------------------------------------------------------
+/** @ingroup xran
+ *
+ *  @param[in]  port - DPDK ETH port id
+ *
+ *  @return  void
+ *
+ *  @description
+ *  Prints statistics of usage of DPDK port
+ *
+**/
+//-------------------------------------------------------------------------------------------
+void xran_ethdi_ports_stats(void)
+{
+    struct rte_eth_stats stats;
+    struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+    int32_t i = 0;
+
+    for(i = 0; i < ETHDI_VF_MAX; i++){
+        /* Get stats (extended stats includes common stats) */
+        rte_eth_stats_get(ctx->io_cfg.port[i], &stats);
+        printf("DPDK stats:\n");
+        printf("** Port %hhu **\n", ctx->io_cfg.port[i]);
+        printf("ierrors:\t%lu\n",   stats.ierrors);
+        printf("oerrors:\t%lu\n",   stats.oerrors);
+        printf("ipackets:\t%lu\n",  stats.ipackets);
+        printf("opackets:\t%lu\n",  stats.opackets);
+        printf("imissed:\t%lu\n",   stats.imissed);
+        printf("rx_nombuf:\t%lu\n", stats.rx_nombuf);
+    }
+    return ;
+}
+#endif
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void check_port_link_status(uint8_t portid)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+    uint8_t count, all_ports_up, print_flag = 0;
+    struct rte_eth_link link;
+
+    printf("\nChecking link status");
+    fflush(stdout);
+    for (count = 0; count <= MAX_CHECK_TIME; count++) {
+        all_ports_up = 1;
+        memset(&link, 0, sizeof(link));
+        rte_eth_link_get_nowait(portid, &link);
+
+        /* print link status if flag set */
+        if (print_flag == 1) {
+            if (link.link_status)
+                printf("Port %d Link Up - speed %u "
+                        "Mbps - %s\n", (uint8_t)portid,
+                        (unsigned)link.link_speed,
+                        (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+                        ("full-duplex") : ("half-duplex\n"));
+            else
+                printf("Port %d Link Down\n",
+                        (uint8_t)portid);
+        }
+        /* clear all_ports_up flag if any link down */
+        if (link.link_status == ETH_LINK_DOWN) {
+            all_ports_up = 0;
+            break;
+        }
+        /* after finally printing all link status, get out */
+        if (print_flag == 1)
+            break;
+
+        if (all_ports_up == 0) {
+            printf(".");
+            fflush(stdout);
+            rte_delay_ms(CHECK_INTERVAL);
+        }
 
+        /* set the print_flag if all ports up or timeout */
+        if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+            print_flag = 1;
+            printf(" ... done\n");
+        }
+    }
+}
 
 
 int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
     int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr,
     uint16_t cp_vlan, uint16_t up_vlan)
 {
-    uint16_t port[2] = {0, 0};
+    uint16_t port[2] = {0xffff, 0xffff};
     struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
     int i;
     char core_mask[20];
-    char *argv[] = { name, core_mask, "-m3072", "--proc-type=auto",
-        "--file-prefix", name, "-w", "0000:00:00.0" };
+    char bbdev_wdev[32] = "";
+    char bbdev_vdev[32] = "";
+
+    char *argv[] = { name, "-c ffffffff", "-n2", "--socket-mem=8192", "--proc-type=auto",
+        "--file-prefix", name, "-w", "0000:00:00.0", bbdev_wdev, bbdev_vdev};
 
     if (io_cfg == NULL)
         return 0;
+    if(io_cfg->bbdev_mode != XRAN_BBDEV_NOT_USED){
+        printf("BBDEV_FEC_ACCL_NR5G\n");
+        if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_ON){
+            // hw-accelerated bbdev
+            printf("hw-accelerated bbdev %s\n", io_cfg->bbdev_dev[0]);
+            sprintf(bbdev_wdev, "-w %s", io_cfg->bbdev_dev[0]);
+        } else if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_OFF){
+            // hw-accelerated bbdev disable
+            if(io_cfg->bbdev_dev[0]){
+                printf("hw-accelerated bbdev disable %s\n", io_cfg->bbdev_dev[0]);
+                sprintf(bbdev_wdev, "-b %s", io_cfg->bbdev_dev[0]);
+            }
+            sprintf(bbdev_wdev, "%s", "--vdev=baseband_turbo_sw");
+        } else {
+            rte_panic("Cannot init DPDK incorrect [bbdev_mode %d]\n", io_cfg->bbdev_mode);
+        }
+    }
 
     snprintf(core_mask, sizeof(core_mask), "-c%x",
             (1 << io_cfg->core) |
@@ -234,6 +337,14 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
     for (i = 0; i <= ID_BROADCAST; i++)     /* Initialize all as broadcast */
         memset(&ctx->entities[i], 0xFF, sizeof(ctx->entities[0]));
 
+    printf("%s: Calling rte_eal_init:", __FUNCTION__);
+    for (i = 0; i < RTE_DIM(argv); i++)
+    {
+        printf("%s ", argv[i]);
+    }
+    printf("\n");
+
+
     /* This will return on system_core, which is not necessarily the
      * one we're on right now. */
     if (rte_eal_init(RTE_DIM(argv), argv) < 0)
@@ -241,6 +352,7 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
 
     xran_init_mbuf_pool();
 
+
     /* Timers. */
     rte_timer_subsystem_init();
     rte_timer_init(&ctx->timer_ping);
@@ -253,10 +365,14 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
 
     if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
         for (i = 0; i < ETHDI_VF_MAX; i ++){
-            if (rte_eth_dev_attach(io_cfg->dpdk_dev[i], &port[i]) != 0 ||
-                rte_eth_dev_count_avail() == 0)
-                errx(1, "Network port doesn't exist.");
-            xran_init_port(port[i], p_lls_cu_addr);   /* we only have 1 port at this stage */
+            if(io_cfg->dpdk_dev[i]){
+                if (rte_eth_dev_attach(io_cfg->dpdk_dev[i], &port[i]) != 0 ||
+                    rte_eth_dev_count_avail() == 0)
+                    errx(1, "Network port doesn't exist.");
+                xran_init_port(port[i], p_lls_cu_addr);
+            } else {
+                printf("no DPDK port provided\n");
+            }
             if(i==0){
                 ctx->tx_ring[i] = rte_ring_create("tx_ring_up", NUM_MBUFS,
                     rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ);
@@ -272,6 +388,8 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
                 ctx->pkt_dump_ring[i] = rte_ring_create("pkt_dump_ring_cp", NUM_MBUFS,
                     rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ);
             }
+            if(io_cfg->dpdk_dev[i])
+                check_port_link_status(port[i]);
         }
     } else {
         rte_panic("ethdi_dpdk_io_loop() failed to start  with RTE_PROC_SECONDARY\n");
@@ -279,15 +397,15 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
     PANIC_ON(ctx->tx_ring == NULL, "failed to allocate tx ring");
     PANIC_ON(ctx->rx_ring == NULL, "failed to allocate rx ring");
     PANIC_ON(ctx->pkt_dump_ring == NULL, "failed to allocate pkt dumping ring");
-    for (i = 0; i < ETHDI_VF_MAX; i++)
+    for (i = 0; i < ETHDI_VF_MAX; i++){
         ctx->io_cfg.port[i] = port[i];
+        print_dbg("port_id 0x%04x\n", ctx->io_cfg.port[i]);
+    }
 
-    rte_eth_macaddr_get(port[ETHDI_UP_VF], &ctx->entities[io_cfg->id]);
-    ether_addr_copy(p_ru_addr,  &ctx->entities[ID_RU]);
-
-    /* Start the actual IO thread */
-    if (rte_eal_remote_launch(xran_ethdi_dpdk_io_loop, &ctx->io_cfg, *lcore_id))
-        rte_panic("ethdi_dpdk_io_loop() failed to start\n");
+    if(io_cfg->dpdk_dev[ETHDI_UP_VF]){
+        rte_eth_macaddr_get(port[ETHDI_UP_VF], &ctx->entities[io_cfg->id]);
+        ether_addr_copy(p_ru_addr,  &ctx->entities[ID_RU]);
+    }
 
     return 1;
 }
@@ -315,7 +433,66 @@ static inline uint16_t xran_tx_from_ring(int port, struct rte_ring *r)
     }
 }
 
+int32_t process_dpdk_io(void)
+{
+    struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+    const struct xran_io_loop_cfg *const cfg = &(xran_ethdi_get_ctx()->io_cfg);
+    const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
+    int port_id = 0;
+
+    for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++){
+        struct rte_mbuf *mbufs[BURST_RX_IO_SIZE];
+        if(port[port_id] == 0xFF);
+        /* RX */
+        const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_RX_IO_SIZE);
+        if (rxed != 0){
+            unsigned enq_n = 0;
+            long t1 = MLogTick();
+            enq_n =  rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL);
+            if(rxed - enq_n)
+                rte_panic("error enq\n");
+            MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick());
+        }
+
+        /* TX */
+        const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]);
+
+        if (XRAN_STOPPED == xran_if_current_state)
+            return -1;
+    }
+
+    if (XRAN_STOPPED == xran_if_current_state)
+            return -1;
+
+    return 0;
+}
 
+#if 0
+static inline void xran_process_rx_burst(struct rte_mbuf *mbufs[], uint16_t n_mbufs,
+        uint64_t rx_time)
+{
+        int i;
+
+        if (!n_mbufs)
+            return;
+
+        for (i = 0; i < n_mbufs; ++i)
+        {
+            if (xran_ethdi_filter_packet(mbufs[i], rx_time) == MBUF_FREE)
+                rte_pktmbuf_free(mbufs[i]);
+        }
+
+#ifdef DPDKIO_LATENCY_DEBUG
+       struct timeval tv_now, tv_diff;
+
+       gettimeofday(&tv_now, NULL);
+       if (n_mbufs > 1)
+           nlog("Warning - received %d mbufs in a row", n_mbufs);
+
+       timersub(&tv_now, &rx_time, &tv_diff);
+       nlog("rx processing took %d usec", tv_diff.tv_usec);
+#endif
+}
 
 /*
  * This is the main DPDK-IO loop.
@@ -324,53 +501,30 @@ static inline uint16_t xran_tx_from_ring(int port, struct rte_ring *r)
  */
 int xran_ethdi_dpdk_io_loop(void *io_loop_cfg)
 {
-    struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
-    const struct xran_io_loop_cfg *const cfg = io_loop_cfg;
-    const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
-    int port_id = 0;
     struct sched_param sched_param;
     int res = 0;
+    struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+    const struct xran_io_loop_cfg *const cfg = &(xran_ethdi_get_ctx()->io_cfg);
+    const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
 
     printf("%s [PORT: %d %d] [CPU %2d] [PID: %6d]\n", __FUNCTION__, port[ETHDI_UP_VF], port[ETHDI_CP_VF] , rte_lcore_id(), getpid());
 
     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
-    if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
-    {
+    if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))) {
         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
     }
 
-    for (;;) {
-        for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++){
-            struct rte_mbuf *mbufs[BURST_SIZE];
-            /* RX */
-            const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_SIZE);
-            if (rxed != 0){
-                long t1 = MLogTick();
-                rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL);
-                MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick());
-            }
-
-            /* TX */
-            const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]);
-            if (rxed | sent)
-                continue;   /* more packets might be waiting in queues */
-
-            rte_pause();    /* short pause, optimize memory access */
-            if (XRAN_STOPPED == xran_if_current_state)
-                break;
-        }
-
-        if (XRAN_STOPPED == xran_if_current_state)
-                break;
+    for (;;){
+        if(process_dpdk_io()!=0)
+            break;
     }
 
     fflush(stderr);
     fflush(stdout);
     puts("IO loop finished");
 
-    //for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++)
-      //  xran_ethdi_port_stats(port[port_id]);
-
     return 0;
 }
+#endif
+
index 3b00e15..e258ac0 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file has all definitions for the Ethernet Data Interface Layer
  * @file ethdi.h
@@ -37,6 +36,7 @@ extern "C" {
 #include <rte_timer.h>
 
 #include "ethernet.h"
+#include "xran_fh_o_du.h"
 
 #define XRAN_THREAD_DEFAULT_PRIO (98)
 
@@ -53,14 +53,6 @@ extern "C" {
 #define TX_TIMER_INTERVAL ((rte_get_timer_hz() / 1000000000L)*interval_us*1000) /* nanosec */
 #define TX_RX_LOOP_TIME rte_get_timer_hz() / 1
 
-extern enum xran_if_state xran_if_current_state;
-
-enum xran_if_state
-{
-    XRAN_RUNNING,
-    XRAN_STOPPED
-};
-
 enum xran_ping_states
 {
     PING_IDLE,
@@ -79,6 +71,8 @@ struct xran_io_loop_cfg
 {
     uint8_t id;
     char *dpdk_dev[ETHDI_VF_MAX];
+    char *bbdev_dev[1];
+    int bbdev_mode;
     int core;
     int system_core;    /* Needed as DPDK will change your starting core. */
     int pkt_proc_core;  /* Needed for packet processing thread. */
@@ -132,6 +126,7 @@ enum {
     MBUF_FREE
 };
 
+extern enum xran_if_state xran_if_current_state;
 extern uint8_t ping_dst_id;
 extern struct ether_addr entities_addrs[];
 
@@ -154,12 +149,16 @@ int xran_register_ethertype_handler(uint16_t ethertype, ethertype_handler callba
 int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
     int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr,
     uint16_t cp_vlan, uint16_t up_vlan);
-int xran_ethdi_dpdk_io_loop(void *);
 struct rte_mbuf *xran_ethdi_mbuf_alloc(void);
 int xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype);
 int xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype);
+#if 0
 void xran_ethdi_stop_tx(void);
+void xran_ethdi_ports_stats(void);
+int xran_ethdi_dpdk_io_loop(void *);
+#endif
 int xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time);
+int32_t process_dpdk_io(void);
 
 
 #ifdef __cplusplus
index ebf997c..8a298b1 100644 (file)
 #include "ethdi.h"
 
 /* Our mbuf pools. */
-struct rte_mempool *_eth_mbuf_pool;
-struct rte_mempool *_eth_mbuf_pool_rx;
-struct rte_mempool *_eth_mbuf_pool_small;
-struct rte_mempool *_eth_mbuf_pool_big;
+struct rte_mempool *_eth_mbuf_pool          = NULL;
+struct rte_mempool *_eth_mbuf_pool_inderect = NULL;
+struct rte_mempool *_eth_mbuf_pool_rx     = NULL;
+struct rte_mempool *_eth_mbuf_pool_small  = NULL;
+struct rte_mempool *_eth_mbuf_pool_big    = NULL;
+
+struct rte_mempool *socket_direct_pool    = NULL;
+struct rte_mempool *socket_indirect_pool  = NULL;
+
 
 /*
  * Make sure the ring indexes are big enough to cover buf space x2
@@ -90,12 +95,66 @@ static struct {
 #define RINGSIZE sizeof(io_ring.buf)
 #define RINGMASK (RINGSIZE - 1)
 
+int __xran_delayed_msg(const char *fmt, ...)
+{
+#if 0
+    va_list ap;
+    int msg_len;
+    char localbuf[RINGSIZE];
+    ring_idx old_head, new_head;
+    ring_idx copy_len;
+
+    /* first prep a copy of the message on the local stack */
+    va_start(ap, fmt);
+    msg_len = vsnprintf(localbuf, RINGSIZE, fmt, ap);
+    va_end(ap);
+
+    /* atomically reserve space in the ring */
+    for (;;) {
+        old_head = io_ring.head;        /* snapshot head */
+        /* free always within range of [0, RINGSIZE] - proof by induction */
+        const ring_idx free = RINGSIZE - (old_head - io_ring.tail);
+
+        copy_len = RTE_MIN(msg_len, free);
+        if (copy_len <= 0)
+            return 0;   /* vsnprintf error or ringbuff full. Drop log. */
+
+        new_head = old_head + copy_len;
+        RTE_ASSERT((ring_idx)(new_head - io_ring.tail) <= RINGSIZE);
+
+        if (likely(__atomic_compare_exchange_n(&io_ring.head, &old_head,
+                        new_head, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)))
+            break;
+    }
+
+    /* Now copy data in at ease. */
+    const int copy_start = (old_head & RINGMASK);
+    if (copy_start < (new_head & RINGMASK))     /* no wrap */
+        memcpy(io_ring.buf + copy_start, localbuf, copy_len);
+    else {                                      /* wrap-around */
+        const int chunk_len = RINGSIZE - copy_start;
+
+        memcpy(io_ring.buf + copy_start, localbuf, chunk_len);
+        memcpy(io_ring.buf, localbuf + chunk_len, copy_len - chunk_len);
+    }
+
+    /* wait for previous writes to complete before updating read_head. */
+    while (io_ring.read_head != old_head)
+        rte_pause();
+    io_ring.read_head = new_head;
+
+
+    return copy_len;
+ #endif
+    return 0;
+}
 
 /*
  * Display part of the message stored in the ring buffer.
  * Might require multiple calls to print the full message.
  * Will return 0 when nothing left to print.
  */
+#if 0 
 int xran_show_delayed_message(void)
 {
     ring_idx tail = io_ring.tail;
@@ -122,7 +181,7 @@ int xran_show_delayed_message(void)
 
     return written;     /* next invocation will print the rest if any */
 }
-
+#endif
 
 void xran_init_mbuf_pool(void)
 {
@@ -130,6 +189,10 @@ void xran_init_mbuf_pool(void)
     if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
         _eth_mbuf_pool = rte_pktmbuf_pool_create("mempool", NUM_MBUFS,
                 MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());
+#ifdef XRAN_ATTACH_MBUF
+        _eth_mbuf_pool_inderect = rte_pktmbuf_pool_create("mempool_indirect", NUM_MBUFS,
+                MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());*/
+#endif
         _eth_mbuf_pool_rx = rte_pktmbuf_pool_create("mempool_rx", NUM_MBUFS,
                 MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());
         _eth_mbuf_pool_small = rte_pktmbuf_pool_create("mempool_small",
@@ -138,25 +201,37 @@ void xran_init_mbuf_pool(void)
                 NUM_MBUFS_BIG, 0, 0, MBUF_POOL_ELM_BIG, rte_socket_id());
     } else {
         _eth_mbuf_pool = rte_mempool_lookup("mempool");
+        _eth_mbuf_pool_inderect = rte_mempool_lookup("mempool_indirect");
         _eth_mbuf_pool_rx = rte_mempool_lookup("mempool_rx");
         _eth_mbuf_pool_small = rte_mempool_lookup("mempool_small");
         _eth_mbuf_pool_big = rte_mempool_lookup("mempool_big");
     }
     if (_eth_mbuf_pool == NULL)
         rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
+#ifdef XRAN_ATTACH_MBUF
+    if (_eth_mbuf_pool_inderect == NULL)
+        rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
+#endif
     if (_eth_mbuf_pool_rx == NULL)
         rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
     if (_eth_mbuf_pool_small == NULL)
         rte_panic("Cannot create small mbuf pool: %s\n", rte_strerror(rte_errno));
     if (_eth_mbuf_pool_big == NULL)
         rte_panic("Cannot create big mbuf pool: %s\n", rte_strerror(rte_errno));
+
+    if (socket_direct_pool == NULL)
+        socket_direct_pool = _eth_mbuf_pool;
+
+    if (socket_indirect_pool == NULL)
+        socket_indirect_pool = _eth_mbuf_pool_inderect;
 }
 
 /* Init NIC port, then start the port */
 void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
 {
-    char buf[ETHER_ADDR_FMT_SIZE];
-    struct ether_addr eth_addr;
+    static uint16_t nb_rxd = BURST_SIZE;
+    static uint16_t nb_txd = BURST_SIZE;
+    struct ether_addr addr;
     struct rte_eth_rxmode rxmode =
             { .split_hdr_size = 0,
               .max_rx_pkt_len = MAX_RX_LEN,
@@ -169,8 +244,6 @@ void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
             .rxmode = rxmode,
             .txmode = txmode
             };
-    struct ether_addr pDstEthAddr;
-
     struct rte_eth_rxconf rxq_conf;
     struct rte_eth_txconf txq_conf;
 
@@ -179,35 +252,13 @@ void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
     const char *drv_name = "";
     int sock_id = rte_eth_dev_socket_id(p_id);
 
-   // ether_format_addr(buf, sizeof(buf), p_lls_cu_addr);
-   // printf("port %d set mac address %s\n", p_id, buf);
-   // rte_eth_dev_default_mac_addr_set(p_id, p_lls_cu_addr);
-
     rte_eth_dev_info_get(p_id, &dev_info);
     if (dev_info.driver_name)
         drv_name = dev_info.driver_name;
     printf("initializing port %d for TX, drv=%s\n", p_id, drv_name);
 
-    /* In order to receive packets from any server need to add broad case address
-    * for the port*/
-    pDstEthAddr.addr_bytes[0] = 0xFF;
-    pDstEthAddr.addr_bytes[1] = 0xFF;
-    pDstEthAddr.addr_bytes[2] = 0xFF;
-
-    pDstEthAddr.addr_bytes[3] = 0xFF;
-    pDstEthAddr.addr_bytes[4] = 0xFF;
-    pDstEthAddr.addr_bytes[5] = 0xFF;
-
-    rte_eth_macaddr_get(p_id, &eth_addr);
-    ether_format_addr(buf, sizeof(buf), &eth_addr);
-    printf("port %d mac address %s\n", p_id, buf);
-
-    struct ether_addr addr;
     rte_eth_macaddr_get(p_id, &addr);
 
-//    rte_eth_dev_mac_addr_add(p_id, &pDstEthAddr,1);
-   // rte_eth_dev_mac_addr_add(p_id, &addr, 1);
-
     printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
         " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
         (unsigned)p_id,
@@ -219,9 +270,18 @@ void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
     if (ret < 0)
         rte_panic("Cannot configure port %u (%d)\n", p_id, ret);
 
+    ret = rte_eth_dev_adjust_nb_rx_tx_desc(p_id, &nb_rxd,&nb_txd);
+
+    if (ret < 0) {
+        printf("\n");
+        rte_exit(EXIT_FAILURE, "Cannot adjust number of "
+            "descriptors: err=%d, port=%d\n", ret, p_id);
+    }
+    printf("Port %u: nb_rxd %d nb_txd %d\n", p_id, nb_rxd, nb_txd);
+
     /* Init RX queues */
     rxq_conf = dev_info.default_rxconf;
-    ret = rte_eth_rx_queue_setup(p_id, 0, BURST_SIZE,
+    ret = rte_eth_rx_queue_setup(p_id, 0, nb_rxd,
         sock_id, &rxq_conf, _eth_mbuf_pool_rx);
     if (ret < 0)
         rte_panic("Cannot init RX for port %u (%d)\n",
@@ -229,7 +289,7 @@ void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
 
     /* Init TX queues */
     txq_conf = dev_info.default_txconf;
-    ret = rte_eth_tx_queue_setup(p_id, 0, BURST_SIZE, sock_id, &txq_conf);
+    ret = rte_eth_tx_queue_setup(p_id, 0, nb_txd, sock_id, &txq_conf);
     if (ret < 0)
         rte_panic("Cannot init TX for port %u (%d)\n",
                 p_id, ret);
@@ -239,9 +299,10 @@ void xran_init_port(int p_id,  struct ether_addr *p_lls_cu_addr)
     if (ret < 0)
         rte_panic("Cannot start port %u (%d)\n", p_id, ret);
 
-    rte_eth_promiscuous_enable(p_id);
+//    rte_eth_promiscuous_enable(p_id);
 }
 
+#if 0
 void xran_memdump(void *addr, int len)
 {
     int i;
@@ -260,9 +321,8 @@ void xran_memdump(void *addr, int len)
 #endif
 }
 
-
 /* Prepend ethernet header, possibly vlan tag. */
-void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci)
+void xran_add_eth_hdr(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb)
 {
     /* add in the ethernet header */
     struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mb, sizeof(*h));
@@ -286,12 +346,25 @@ void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rt
     }
 #endif
 #ifdef VLAN_SUPPORT
-    mb->vlan_tci = vlan_tci;
-    dlog("Inserting vlan tag of %d", vlan_tci);
+    mb->vlan_tci = FLEXRAN_UP_VLAN_TAG;
+    dlog("Inserting vlan tag of %d", FLEXRAN_UP_VLAN_TAG);
     rte_vlan_insert(&mb);
 #endif
 }
 
+int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb)
+{
+    xran_add_eth_hdr(dst, ETHER_TYPE_ETHDI, mb);
+
+    if (rte_eth_tx_burst(mb->port, 0, &mb, 1) == 1)
+        return 1;
+
+    elog("packet sending failed on port %d", mb->port);
+    rte_pktmbuf_free(mb);
+
+    return 0;   /* fail */
+}
+
 int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len)
 {
     struct rte_mbuf *mbufs[BURST_SIZE];
@@ -355,3 +428,38 @@ int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len)
 
     return 1;
 }
+
+#endif
+
+/* Prepend ethernet header, possibly vlan tag. */
+void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci)
+{
+    /* add in the ethernet header */
+    struct ether_hdr *h = (struct ether_hdr *)rte_pktmbuf_mtod(mb, struct ether_hdr*);
+
+    PANIC_ON(h == NULL, "mbuf prepend of ether_hdr failed");
+
+    /* Fill in the ethernet header. */
+    rte_eth_macaddr_get(mb->port, &h->s_addr);          /* set source addr */
+    h->d_addr = *dst;                                   /* set dst addr */
+    h->ether_type = rte_cpu_to_be_16(ethertype);        /* ethertype too */
+
+#if defined(DPDKIO_DEBUG) && DPDKIO_DEBUG > 1
+    {
+        char dst[ETHER_ADDR_FMT_SIZE] = "(empty)";
+        char src[ETHER_ADDR_FMT_SIZE] = "(empty)";
+
+        nlog("*** packet for TX below (len %d) ***", rte_pktmbuf_pkt_len(mb));
+        ether_format_addr(src, sizeof(src), &h->s_addr);
+        ether_format_addr(dst, sizeof(dst), &h->d_addr);
+        nlog("src: %s dst: %s ethertype: %.4X", src, dst, ethertype);
+    }
+#endif
+#ifdef VLAN_SUPPORT
+    mb->vlan_tci = vlan_tci;
+    dlog("Inserting vlan tag of %d", vlan_tci);
+    rte_vlan_insert(&mb);
+#endif
+}
+
+
index b22aed8..f3efe7b 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file has all definitions for the Ethernet Data Interface Layer
  * @file ethernet.h
@@ -35,7 +34,7 @@ extern "C" {
 #include <rte_ether.h>
 #include <rte_mbuf.h>
 
-#define BURST_SIZE 64
+#define BURST_SIZE 4096
 
 //#define VLAN_SUPPORT
 #define FLEXRAN_UP_VLAN_TAG 2
@@ -44,7 +43,7 @@ extern "C" {
 #define ETHER_TYPE_SYNC 0xBEFE
 #define ETHER_TYPE_START_TX 0xCEFE
 
-#define NUM_MBUFS 262144
+#define NUM_MBUFS 65536
 #define MBUF_CACHE 256
 
 #define MBUF_POOL_ELM_SMALL 1500 /* regular ethernet MTU, most compatible */
@@ -64,6 +63,8 @@ extern "C" {
 extern struct rte_mempool *_eth_mbuf_pool;
 extern struct rte_mempool *_eth_mbuf_pool_small;
 extern struct rte_mempool *_eth_mbuf_pool_big;
+extern struct rte_mempool *socket_direct_pool;
+extern struct rte_mempool *socket_indirect_pool;
 
 /* Do NOT change the order of this enum and below
  * - need to be in sync with the table of handlers in testue.c */
@@ -121,23 +122,25 @@ void xran_init_mbuf_pool(void);
 void xran_init_port(int port, struct ether_addr *p_lls_cu_addr);
 
 void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci);
-int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb);
-
-int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len);
 
+#if 0
 void xran_memdump(void *addr, int len);
-
+void xran_add_eth_hdr(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *);
+int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb);
+int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len);
+int xran_show_delayed_message(void);
+#endif
 /*
  * Print a message after all critical processing done.
  * Mt-safe. 4 variants - normal, warning, error and debug log.
  */
-
-#define nlog(m, ...) 
-#define delayed_message     /* this is the old alias for this function */
-#define wlog(m, ...) 
-#define elog(m, ...) 
+int __xran_delayed_msg(const char *fmt, ...);
+#define nlog(m, ...) __xran_delayed_msg("%s(): " m "\n", __FUNCTION__, ##__VA_ARGS__)
+#define delayed_message nlog    /* this is the old alias for this function */
+#define wlog(m, ...) nlog("WARNING: " m, ##__VA_ARGS__)
+#define elog(m, ...) nlog("ERROR: " m, ##__VA_ARGS__)
 #ifdef DEBUG
-# define dlog(m, ...) 
+# define dlog(m, ...) nlog("DEBUG: " m, ##__VA_ARGS__)
 #else
 # define dlog(m, ...)
 #endif
diff --git a/fhi_lib/lib/src/xran_app_frag.c b/fhi_lib/lib/src/xran_app_frag.c
new file mode 100644 (file)
index 0000000..5b1dc47
--- /dev/null
@@ -0,0 +1,259 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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 application frgamentation for U-plane packets
+ *
+ * @file xran_app_frag.c
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_mempool.h>
+#include <rte_debug.h>
+
+#include "xran_app_frag.h"
+#include "xran_cp_api.h"
+#include "xran_pkt_up.h"
+#include "xran_printf.h"
+#include "xran_common.h"
+
+/* Fragment alignment */
+#define    XRAN_PAYLOAD_RB_ALIGN  (N_SC_PER_PRB*(IQ_BITS/8)*2) /**< at least 12*4=48 bytes per one RB */
+
+static inline void __fill_xranhdr_frag(struct xran_up_pkt_hdr *dst,
+        const struct xran_up_pkt_hdr *src, uint16_t rblen_bytes,
+        uint16_t rboff_bytes, struct xran_section_info *sectinfo, uint32_t mf, uint8_t *seqid)
+{
+    struct data_section_hdr loc_data_sec_hdr;
+    struct xran_ecpri_hdr loc_ecpri_hdr;
+
+    rte_memcpy(dst, src, sizeof(*dst));
+
+    if(dst->ecpri_hdr.ecpri_seq_id.seq_id != *seqid - 1){
+        /* not first fragment, incease seq id */
+        dst->ecpri_hdr.ecpri_seq_id.seq_id = *seqid++;
+    }
+
+    loc_data_sec_hdr.fields.all_bits = rte_be_to_cpu_32(dst->data_sec_hdr.fields.all_bits);
+
+    /* update RBs */
+    loc_data_sec_hdr.fields.start_prbu = sectinfo->startPrbc + rboff_bytes/(N_SC_PER_PRB*(IQ_BITS/8*2));
+    loc_data_sec_hdr.fields.num_prbu   = rblen_bytes/(N_SC_PER_PRB*(IQ_BITS/8*2));
+
+    print_dbg("sec [%d %d] pkt [%d %d] rboff_bytes %d rblen_bytes %d\n",sectinfo->startPrbc, sectinfo->numPrbc, loc_data_sec_hdr.fields.start_prbu, loc_data_sec_hdr.fields.num_prbu,
+        rboff_bytes, rblen_bytes);
+
+    dst->data_sec_hdr.fields.all_bits = rte_cpu_to_be_32(loc_data_sec_hdr.fields.all_bits);
+
+    /* update length */
+    dst->ecpri_hdr.cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
+                sizeof(struct data_section_hdr) + rblen_bytes + xran_get_ecpri_hdr_size());
+}
+
+
+static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
+{
+    uint32_t i;
+    for (i = 0; i != num; i++)
+        rte_pktmbuf_free(mb[i]);
+}
+
+/**
+ * XRAN fragmentation.
+ *
+ * This function implements the application fragmentation of XRAN packets.
+ *
+ * @param pkt_in
+ *   The input packet.
+ * @param pkts_out
+ *   Array storing the output fragments.
+ * @param mtu_size
+ *   Size in bytes of the Maximum Transfer Unit (MTU) for the outgoing XRAN
+ *   datagrams. This value includes the size of the XRAN headers.
+ * @param pool_direct
+ *   MBUF pool used for allocating direct buffers for the output fragments.
+ * @param pool_indirect
+ *   MBUF pool used for allocating indirect buffers for the output fragments.
+ * @return
+ *   Upon successful completion - number of output fragments placed
+ *   in the pkts_out array.
+ *   Otherwise - (-1) * <errno>.
+ */
+int32_t
+xran_app_fragment_packet(struct rte_mbuf *pkt_in, /* eth hdr is prepended */
+    struct rte_mbuf **pkts_out,
+    uint16_t nb_pkts_out,
+    uint16_t mtu_size,
+    struct rte_mempool *pool_direct,
+    struct rte_mempool *pool_indirect,
+    struct xran_section_info *sectinfo,
+    uint8_t *seqid)
+{
+    struct rte_mbuf *in_seg = NULL;
+    uint32_t out_pkt_pos =  0, in_seg_data_pos = 0;
+    uint32_t more_in_segs;
+    uint16_t fragment_offset, frag_size;
+    uint16_t frag_bytes_remaining;
+    struct eth_xran_up_pkt_hdr *in_hdr;
+    struct xran_up_pkt_hdr *in_hdr_xran;
+
+    /*
+     * Ensure the XRAN payload length of all fragments is aligned to a
+     * multiple of 48 bytes (1 RB with IQ of 16 bits each)
+     */
+    frag_size = ((mtu_size - sizeof(struct eth_xran_up_pkt_hdr) - RTE_PKTMBUF_HEADROOM)/XRAN_PAYLOAD_RB_ALIGN)*XRAN_PAYLOAD_RB_ALIGN;
+
+
+    print_dbg("frag_size %d\n",frag_size);
+
+    in_hdr = rte_pktmbuf_mtod(pkt_in, struct eth_xran_up_pkt_hdr *);
+
+    in_hdr_xran = &in_hdr->xran_hdr;
+
+    /* Check that pkts_out is big enough to hold all fragments */
+    if (unlikely(frag_size * nb_pkts_out <
+        (uint16_t)(pkt_in->pkt_len - sizeof (struct xran_up_pkt_hdr)))){
+        print_err("-EINVAL\n");
+        return -EINVAL;
+    }
+
+    in_seg = pkt_in;
+    in_seg_data_pos = sizeof(struct eth_xran_up_pkt_hdr);
+    out_pkt_pos = 0;
+    fragment_offset = 0;
+
+    more_in_segs = 1;
+    while (likely(more_in_segs)) {
+        struct rte_mbuf *out_pkt = NULL, *out_seg_prev = NULL;
+        uint32_t more_out_segs;
+        struct xran_up_pkt_hdr *out_hdr;
+
+        /* Allocate direct buffer */
+        out_pkt = rte_pktmbuf_alloc(pool_direct);
+        if (unlikely(out_pkt == NULL)) {
+            print_err("pool_direct -ENOMEM\n");
+            __free_fragments(pkts_out, out_pkt_pos);
+            return -ENOMEM;
+        }
+
+        print_dbg("[%d] out_pkt %p\n",more_in_segs, out_pkt);
+
+        /* Reserve space for the XRAN header that will be built later */
+        //out_pkt->data_len = sizeof(struct xran_up_pkt_hdr);
+         //out_pkt->pkt_len = sizeof(struct xran_up_pkt_hdr);
+        if(rte_pktmbuf_append(out_pkt, sizeof(struct xran_up_pkt_hdr)) ==NULL){
+            rte_panic("sizeof(struct xran_up_pkt_hdr)");
+        }
+        frag_bytes_remaining = frag_size;
+
+        out_seg_prev = out_pkt;
+        more_out_segs = 1;
+        while (likely(more_out_segs && more_in_segs)) {
+            uint32_t len;
+#ifdef XRAN_ATTACH_MBUF
+            struct rte_mbuf *out_seg = NULL;
+
+            /* Allocate indirect buffer */
+            print_dbg("Allocate indirect buffer \n");
+            out_seg = rte_pktmbuf_alloc(pool_indirect);
+            if (unlikely(out_seg == NULL)) {
+                print_err("pool_indirect -ENOMEM\n");
+                rte_pktmbuf_free(out_pkt);
+                __free_fragments(pkts_out, out_pkt_pos);
+                return -ENOMEM;
+            }
+
+            print_dbg("[%d %d] out_seg %p\n",more_out_segs, more_in_segs, out_seg);
+            out_seg_prev->next = out_seg;
+            out_seg_prev = out_seg;
+
+            /* Prepare indirect buffer */
+            rte_pktmbuf_attach(out_seg, in_seg);
+#endif
+            len = frag_bytes_remaining;
+            if (len > (in_seg->data_len - in_seg_data_pos)) {
+                len = in_seg->data_len - in_seg_data_pos;
+            }
+#ifdef XRAN_ATTACH_MBUF
+            out_seg->data_off = in_seg->data_off + in_seg_data_pos;
+            out_seg->data_len = (uint16_t)len;
+            out_pkt->pkt_len = (uint16_t)(len +
+                out_pkt->pkt_len);
+            out_pkt->nb_segs += 1;
+#else
+{
+            char* pChar   = rte_pktmbuf_mtod(in_seg, char*);
+            void *iq_src  = (pChar + in_seg_data_pos);
+            void *iq_dst  = rte_pktmbuf_append(out_pkt, len);
+
+            print_dbg("rte_pktmbuf_attach\n");
+            if(iq_src && iq_dst)
+                rte_memcpy(iq_dst, iq_src, len);
+            else
+                print_err("iq_src %p iq_dst %p\n len %d room %d\n", iq_src, iq_dst, len, rte_pktmbuf_tailroom(out_pkt));
+}
+#endif
+            in_seg_data_pos += len;
+            frag_bytes_remaining -= len;
+
+            /* Current output packet (i.e. fragment) done ? */
+            if (unlikely(frag_bytes_remaining == 0))
+                more_out_segs = 0;
+
+            /* Current input segment done ? */
+            if (unlikely(in_seg_data_pos == in_seg->data_len)) {
+                in_seg = in_seg->next;
+                in_seg_data_pos = 0;
+
+                if (unlikely(in_seg == NULL))
+                    more_in_segs = 0;
+            }
+        }
+
+        /* Build the XRAN header */
+        print_dbg("Build the XRAN header\n");
+        out_hdr = rte_pktmbuf_mtod(out_pkt, struct xran_up_pkt_hdr *);
+
+        __fill_xranhdr_frag(out_hdr, in_hdr_xran,
+            (uint16_t)out_pkt->pkt_len - sizeof(struct xran_up_pkt_hdr),
+            fragment_offset, sectinfo, more_in_segs, seqid);
+
+        fragment_offset = (uint16_t)(fragment_offset +
+            out_pkt->pkt_len - sizeof(struct xran_up_pkt_hdr));
+
+        //out_pkt->l3_len = sizeof(struct xran_up_pkt_hdr);
+
+        /* Write the fragment to the output list */
+        pkts_out[out_pkt_pos] = out_pkt;
+        print_dbg("out_pkt_pos %d data_len %d pkt_len %d\n", out_pkt_pos, out_pkt->data_len, out_pkt->pkt_len);
+        out_pkt_pos ++;
+        //rte_pktmbuf_dump(stdout, out_pkt, 96);
+    }
+
+    return out_pkt_pos;
+}
+
+
diff --git a/fhi_lib/lib/src/xran_app_frag.h b/fhi_lib/lib/src/xran_app_frag.h
new file mode 100644 (file)
index 0000000..399f630
--- /dev/null
@@ -0,0 +1,61 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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 Header file for functions to perform application level fragmentation
+ *
+ * @file xran_app_frag.h
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#ifndef _XRAN_APP_FRAG_
+#define _XRAN_APP_FRAG_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <rte_config.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_byteorder.h>
+
+#include "xran_fh_o_du.h"
+#include "xran_cp_api.h"
+
+int32_t xran_app_fragment_packet(struct rte_mbuf *pkt_in, /* eth hdr is prepended */
+                                    struct rte_mbuf **pkts_out,
+                                    uint16_t nb_pkts_out,
+                                    uint16_t mtu_size,
+                                    struct rte_mempool *pool_direct,
+                                    struct rte_mempool *pool_indirect,
+                                    struct xran_section_info *sectinfo,
+                                    uint8_t *seqid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XRAN_APP_FRAG_ */
+
index 67079e2..d72f27a 100644 (file)
@@ -16,9 +16,6 @@
 *
 *******************************************************************************/
 
-#ifndef _XRAN_COMMON_
-#define _XRAN_COMMON_
-
 /**
  * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
  *    U-plane
 #include "ethdi.h"
 #include "xran_pkt.h"
 #include "xran_pkt_up.h"
-#include "xran_cp_api.h"
 #include "xran_up_api.h"
+#include "xran_lib_mlog_tasks_id.h"
+
 #include "../src/xran_printf.h"
+#include <rte_mbuf.h>
+#include "xran_mlog_lnx.h"
 
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#define MBUFS_CNT 16
 
-#define MBUFS_CNT 256
+extern long interval_us;
 
 extern int xran_process_rx_sym(void *arg,
+                        struct rte_mbuf *mbuf,
+                        void *iq_data_start,
+                        uint16_t size,
+                        uint8_t CC_ID,
+                        uint8_t Ant_ID,
+                        uint8_t frame_id,
+                        uint8_t subframe_id,
+                        uint8_t slot_id,
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id,
+                        uint32_t *mb_free);
+
+
+extern int xran_process_prach_sym(void *arg,
+                        struct rte_mbuf *mbuf,
+                        void *iq_data_start,
+                        uint16_t size,
+                        uint8_t CC_ID,
+                        uint8_t Ant_ID,
+                        uint8_t frame_id,
+                        uint8_t subframe_id,
+                        uint8_t slot_id,
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id);
+
+extern int32_t xran_pkt_validate(void *arg,
+                        struct rte_mbuf *mbuf,
                         void *iq_data_start,
                         uint16_t size,
                         uint8_t CC_ID,
@@ -57,8 +88,16 @@ extern int xran_process_rx_sym(void *arg,
                         uint8_t frame_id,
                         uint8_t subframe_id,
                         uint8_t slot_id,
-                        uint8_t symb_id);
+                        uint8_t symb_id,
+                        struct ecpri_seq_id *seq_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id);
 
+long rx_counter = 0;
+long tx_counter = 0;
 
 int process_mbuf(struct rte_mbuf *pkt)
 {
@@ -66,7 +105,8 @@ int process_mbuf(struct rte_mbuf *pkt)
     struct ecpri_seq_id seq;
     static int symbol_total_bytes = 0;
     int num_bytes = 0;
-    struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
+    struct xran_device_ctx * p_x_ctx = xran_dev_get_ctx();
+
     uint8_t CC_ID = 0;
     uint8_t Ant_ID = 0;
     uint8_t frame_id = 0;
@@ -74,6 +114,21 @@ int process_mbuf(struct rte_mbuf *pkt)
     uint8_t slot_id = 0;
     uint8_t symb_id = 0;
 
+    uint16_t num_prbu;
+    uint16_t start_prbu;
+    uint16_t sym_inc;
+    uint16_t rb;
+    uint16_t sect_id;
+    void *pHandle = NULL;
+    uint8_t num_eAxc = xran_get_num_eAxc(pHandle);
+    int ret = MBUF_FREE;
+    uint32_t mb_free = 0;
+    int32_t valid_res = 0;
+
+
+    if(p_x_ctx->xran2phy_mem_ready == 0)
+        return MBUF_FREE;
+
     num_bytes = xran_extract_iq_samples(pkt,
                                         &iq_samp_buf,
                                         &CC_ID,
@@ -82,30 +137,104 @@ int process_mbuf(struct rte_mbuf *pkt)
                                         &subframe_id,
                                         &slot_id,
                                         &symb_id,
-                                        &seq);
-    if (num_bytes <= 0)
-        return -1;
+                                        &seq,
+                                        &num_prbu,
+                                        &start_prbu,
+                                        &sym_inc,
+                                        &rb,
+                                        &sect_id);
+
+    if (num_bytes <= 0){
+        print_err("num_bytes is wrong [%d]\n", num_bytes);
+        return MBUF_FREE;
+    }
 
-    symbol_total_bytes += num_bytes;
-
-    if (seq.e_bit == 1) {
-        print_dbg("Completed receiving symbol %d, size=%d bytes\n",
-            symb_id, symbol_total_bytes);
-
-        if (symbol_total_bytes)
-            xran_process_rx_sym(NULL,
-                            iq_samp_buf,
-                            symbol_total_bytes,
-                            CC_ID,
-                            Ant_ID,
-                            frame_id,
-                            subframe_id,
-                            slot_id,
-                            symb_id);
-        symbol_total_bytes = 0;
+    valid_res = xran_pkt_validate(NULL,
+                                pkt,
+                                iq_samp_buf,
+                                num_bytes,
+                                CC_ID,
+                                Ant_ID,
+                                frame_id,
+                                subframe_id,
+                                slot_id,
+                                symb_id,
+                                &seq,
+                                num_prbu,
+                                start_prbu,
+                                sym_inc,
+                                rb,
+                                sect_id);
+
+    if(valid_res != 0) {
+        print_err("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes);
+        return MBUF_FREE;
     }
 
-    return 0;
+    if (Ant_ID >= num_eAxc && p_x_ctx->fh_init.prachEnable) // PRACH packet has ruportid = num_eAxc + ant_id
+    {
+        Ant_ID -= num_eAxc;
+        if (seq.e_bit == 1) {
+
+            print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",
+                symb_id, num_bytes);
+
+                xran_process_prach_sym(NULL,
+                                pkt,
+                                iq_samp_buf,
+                                num_bytes,
+                                CC_ID,
+                                Ant_ID,
+                                frame_id,
+                                subframe_id,
+                                slot_id,
+                                symb_id,
+                                num_prbu,
+                                start_prbu,
+                                sym_inc,
+                                rb,
+                                sect_id);
+        }
+        else {
+            print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
+        }
+    } else {
+        symbol_total_bytes += num_bytes;
+
+        if (seq.e_bit == 1) {
+            print_dbg("Completed receiving symbol %d, size=%d bytes\n",
+                symb_id, symbol_total_bytes);
+
+            if (symbol_total_bytes){
+                int res = xran_process_rx_sym(NULL,
+                                pkt,
+                                iq_samp_buf,
+                                symbol_total_bytes,
+                                CC_ID,
+                                Ant_ID,
+                                frame_id,
+                                subframe_id,
+                                slot_id,
+                                symb_id,
+                                num_prbu,
+                                start_prbu,
+                                sym_inc,
+                                rb,
+                                sect_id,
+                                &mb_free);
+                if(res == symbol_total_bytes)
+                    ret  = mb_free;
+                else
+                    print_err("res != symbol_total_bytes\n");
+            }
+            symbol_total_bytes = 0;
+        }
+        else {
+            print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
+        }
+    }
+
+    return ret;
 }
 
 static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compression_hdr *compr_hdr)
@@ -120,9 +249,11 @@ static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compressio
 }
 
 /* Send a single 5G symbol over multiple packets */
-int send_symbol_ex(enum xran_pkt_dir direction,
+int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
                 uint16_t section_id,
+                struct rte_mbuf *mb,
                 struct rb_map *data,
+                const enum xran_input_byte_order iq_buf_byte_order,
                 uint8_t frame_id,
                 uint8_t subframe_id,
                 uint8_t slot_id,
@@ -131,13 +262,20 @@ int send_symbol_ex(enum xran_pkt_dir direction,
                 int prb_num,
                 uint8_t CC_ID,
                 uint8_t RU_Port_ID,
-                uint8_t seq_id)
+                uint8_t seq_id,
+                uint32_t do_copy)
 {
-    const int n_bytes = prb_num * N_SC_PER_PRB * sizeof(struct rb_map);
-    int sent;
+    int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+
+    int32_t prep_bytes;
+
+    int16_t nPktSize = sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) +
+            sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes;
     uint32_t off;
     struct xran_up_pkt_gen_no_compression_params xp = { 0 };
 
+    n_bytes = RTE_MIN(n_bytes, XRAN_MAX_MBUF_LEN);
+
     /* radio app header */
     xp.app_params.data_direction = direction;
     xp.app_params.payl_ver       = 1;
@@ -159,24 +297,98 @@ int send_symbol_ex(enum xran_pkt_dir direction,
     /* network byte order */
     xp.sec_hdr.fields.all_bits  = rte_cpu_to_be_32(xp.sec_hdr.fields.all_bits);
 
-    struct rte_mbuf *mb = xran_ethdi_mbuf_alloc();
-
     if (mb == NULL){
         MLogPrint(NULL);
         errx(1, "out of mbufs after %d packets", 1);
     }
 
-    sent = xran_prepare_iq_symbol_portion_no_comp(mb,
+    prep_bytes = xran_prepare_iq_symbol_portion_no_comp(mb,
                                                   data,
+                                                  iq_buf_byte_order,
                                                   n_bytes,
                                                   &xp,
                                                   CC_ID,
                                                   RU_Port_ID,
-                                                  seq_id);
-    if (sent <= 0)
+                                                  seq_id,
+                                                  do_copy);
+    if (prep_bytes <= 0)
         errx(1, "failed preparing symbol");
 
-    xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
+    rte_pktmbuf_pkt_len(mb)  = nPktSize;
+    rte_pktmbuf_data_len(mb) = nPktSize;
+
+#ifdef DEBUG
+    printf("Symbol %2d prep_bytes (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
+#endif
+
+    return prep_bytes;
+}
+
+/* Send a single 5G symbol over multiple packets */
+int send_symbol_ex(enum xran_pkt_dir direction,
+                uint16_t section_id,
+                struct rte_mbuf *mb,
+                struct rb_map *data,
+                const enum xran_input_byte_order iq_buf_byte_order,
+                uint8_t frame_id,
+                uint8_t subframe_id,
+                uint8_t slot_id,
+                uint8_t symbol_no,
+                int prb_start,
+                int prb_num,
+                uint8_t CC_ID,
+                uint8_t RU_Port_ID,
+                uint8_t seq_id)
+{
+    uint32_t do_copy = 0;
+    int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+
+    if (mb == NULL){
+        char * pChar = NULL;
+        mb = xran_ethdi_mbuf_alloc(); /* will be freede by ETH */
+        if(mb ==  NULL){
+            MLogPrint(NULL);
+            errx(1, "out of mbufs after %d packets", 1);
+        }
+        pChar = rte_pktmbuf_append(mb, sizeof(struct xran_ecpri_hdr)+ sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes);
+        if(pChar == NULL){
+                MLogPrint(NULL);
+                errx(1, "incorrect mbuf size %d packets", 1);
+        }
+        pChar = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
+        if(pChar == NULL){
+                MLogPrint(NULL);
+                errx(1, "incorrect mbuf size %d packets", 1);
+        }
+        do_copy = 1; /* new mbuf hence copy of IQs  */
+    }else {
+        rte_pktmbuf_refcnt_update(mb, 1); /* make sure eth won't free our mbuf */
+    }
+
+    int32_t sent = prepare_symbol_ex(direction,
+                         section_id,
+                         mb,
+                         data,
+                         iq_buf_byte_order,
+                         frame_id,
+                         subframe_id,
+                         slot_id,
+                         symbol_no,
+                         prb_start,
+                         prb_num,
+                         CC_ID,
+                         RU_Port_ID,
+                         seq_id,
+                         do_copy);
+
+    if(sent){
+        tx_counter++;
+        xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
+    } else {
+
+    }
+
+
 
 #ifdef DEBUG
     printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
@@ -185,82 +397,97 @@ int send_symbol_ex(enum xran_pkt_dir direction,
     return sent;
 }
 
-int send_cpmsg_dlul(void *pHandle, enum xran_pkt_dir dir,
-                uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
-                uint8_t startsym, uint8_t numsym, int prb_num,
-                uint16_t beam_id,
-                uint8_t cc_id, uint8_t ru_port_id,
-                uint8_t seq_id)
+int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
+                struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)
 {
-  struct xran_cp_gen_params params;
-  struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
-  struct rte_mbuf *mbuf;
-  int ret, nsection, i;
-
-
-    params.dir                  = dir;
-    params.sectionType          = XRAN_CP_SECTIONTYPE_1;     // Most DL/UL Radio Channels
-    params.hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;
-    params.hdr.frameId          = frame_id;
-    params.hdr.subframeId       = subframe_id;
-    params.hdr.slotId           = slot_id;
-    params.hdr.startSymId       = startsym;                 // start Symbol ID
-    params.hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);
-    params.hdr.compMeth         = xran_get_conf_compmethod(pHandle);
+    int ret = 0, nsection, i;
+    uint8_t frame_id = params->hdr.frameId;
+    uint8_t subframe_id = params->hdr.subframeId;
+    uint8_t slot_id = params->hdr.slotId;
+    uint8_t dir = params->dir;
+
+    nsection = params->numSections;
+
+    /* add in the ethernet header */
+    struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+    xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
+    tx_counter++;
+    for(i=0; i<nsection; i++)
+        xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id,
+                (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
+                &sect_geninfo[i].info);
+
+    return (ret);
+}
+
+int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
+    enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+    uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,
+    uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t seq_id, uint8_t symInc)
+{
+    int ret = 0, nsection, i;
+
+
+    params->dir                  = dir;
+    params->sectionType          = XRAN_CP_SECTIONTYPE_1;        // Most DL/UL Radio Channels
+    params->hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;
+    params->hdr.frameId          = frame_id;
+    params->hdr.subframeId       = subframe_id;
+    params->hdr.slotId           = slot_id;
+    params->hdr.startSymId       = startsym;                     // start Symbol ID
+    params->hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);
+    params->hdr.compMeth         = comp_method;
 
     nsection = 0;
-    sect_geninfo[nsection].info.type        = params.sectionType;
+    sect_geninfo[nsection].info.type        = params->sectionType;       // for database
+    sect_geninfo[nsection].info.startSymId  = params->hdr.startSymId;    // for database
+    sect_geninfo[nsection].info.iqWidth     = params->hdr.iqWidth;       // for database
+    sect_geninfo[nsection].info.compMeth    = params->hdr.compMeth;      // for database
     sect_geninfo[nsection].info.id          = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
     sect_geninfo[nsection].info.rb          = XRAN_RBIND_EVERY;
-    sect_geninfo[nsection].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
-    sect_geninfo[nsection].info.startPrbc   = 0;
-    sect_geninfo[nsection].info.numPrbc     = NUM_OF_PRB_IN_FULL_BAND,
+    sect_geninfo[nsection].info.symInc      = symInc;
+    sect_geninfo[nsection].info.startPrbc   = prb_start;
+    sect_geninfo[nsection].info.numPrbc     = prb_num;
     sect_geninfo[nsection].info.numSymbol   = numsym;
     sect_geninfo[nsection].info.reMask      = 0xfff;
     sect_geninfo[nsection].info.beamId      = beam_id;
 
-    sect_geninfo[nsection].info.ef          = 0;      // no extension
+    sect_geninfo[nsection].info.ef          = 0;
     sect_geninfo[nsection].exDataSize       = 0;
-    sect_geninfo[nsection].exData           = NULL;
+//    sect_geninfo[nsection].exData           = NULL;
     nsection++;
 
-    params.numSections          = nsection;
-    params.sections             = sect_geninfo;
+    params->numSections          = nsection;
+    params->sections             = sect_geninfo;
 
-    mbuf = xran_ethdi_mbuf_alloc();
     if(unlikely(mbuf == NULL)) {
         print_err("Alloc fail!\n");
         return (-1);
-        }
+    }
 
-    ret = xran_prepare_ctrl_pkt(mbuf, &params, cc_id, ru_port_id, seq_id);
-    if(ret < 0) {
+    ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, ru_port_id, seq_id);
+    if(ret < 0){
         print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
                     frame_id, subframe_id, slot_id, dir);
-        }
-    else {
-        xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
-        for(i=0; i<nsection; i++)
-            xran_cp_add_section_info(pHandle,
-                    dir, cc_id, ru_port_id, subframe_id, slot_id,
-                    &sect_geninfo[i].info);
-        }
+        rte_pktmbuf_free(mbuf);
+    }
 
     return (ret);
 }
 
-int send_cpmsg_prach(void *pHandle,
+int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx,
                 uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
-                uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id,
-                uint8_t seq_id)
+                uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id)
 {
-    struct xran_cp_gen_params params;
-    struct xran_section_gen_info sect_geninfo[8];
-    struct rte_mbuf *mbuf;
     int i, nsection, ret;
-    struct xran_lib_ctx *pxran_lib_ctx = xran_lib_get_ctx();
     xRANPrachCPConfigStruct *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
+    uint16_t timeOffset;
+    uint16_t nNumerology = pxran_lib_ctx->fh_cfg.frame_conf.nNumerology;
 
+    if(unlikely(mbuf == NULL)) {
+        print_err("Alloc fail!\n");
+        return (-1);
+    }
 #if 0
     printf("%d:%d:%d:%d - filter=%d, startSym=%d[%d:%d], numSym=%d, occasions=%d, freqOff=%d\n",
                 frame_id, subframe_id, slot_id, prach_port_id,
@@ -272,62 +499,60 @@ int send_cpmsg_prach(void *pHandle,
                 pPrachCPConfig->occassionsInPrachSlot,
                 pPrachCPConfig->freqOffset);
 #endif
-
-    params.dir                  = XRAN_DIR_UL;
-    params.sectionType          = XRAN_CP_SECTIONTYPE_3;
-    params.hdr.filterIdx        = pPrachCPConfig->filterIdx;
-    params.hdr.frameId          = frame_id;
-    params.hdr.subframeId       = subframe_id;
-    params.hdr.slotId           = slot_id;
-    params.hdr.startSymId       = pPrachCPConfig->startSymId;
-    params.hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);
-    params.hdr.compMeth         = xran_get_conf_compmethod(pHandle);
+    timeOffset = pPrachCPConfig->timeOffset; //this is the CP value per 38.211 tab 6.3.3.1-1&2
+    timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
+    if (pPrachCPConfig->startSymId > 0)
+    {
+        timeOffset += (pPrachCPConfig->startSymId * 2048) >> nNumerology;
+        if ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME >> 1)))
+            timeOffset += 16;
+    }
+    params->dir                  = XRAN_DIR_UL;
+    params->sectionType          = XRAN_CP_SECTIONTYPE_3;
+    params->hdr.filterIdx        = pPrachCPConfig->filterIdx;
+    params->hdr.frameId          = frame_id;
+    params->hdr.subframeId       = subframe_id;
+    params->hdr.slotId           = slot_id;
+    params->hdr.startSymId       = pPrachCPConfig->startSymId;
+    params->hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);
+    params->hdr.compMeth         = xran_get_conf_compmethod(pHandle);
         /* use timeOffset field for the CP length value for prach sequence */
-    params.hdr.timeOffset       = pPrachCPConfig->timeOffset;
-    params.hdr.fftSize          = xran_get_conf_fftsize(pHandle);
-    params.hdr.scs              = xran_get_conf_prach_scs(pHandle);
-    params.hdr.cpLength         = 0;
+    params->hdr.timeOffset       = timeOffset;
+    params->hdr.fftSize          = xran_get_conf_fftsize(pHandle);
+    params->hdr.scs              = xran_get_conf_prach_scs(pHandle);
+    params->hdr.cpLength         = 0;
 
     nsection = 0;
-    sect_geninfo[nsection].info.type      = params.sectionType;
-    sect_geninfo[nsection].info.id        = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
-    sect_geninfo[nsection].info.rb        = XRAN_RBIND_EVERY;
-    sect_geninfo[nsection].info.symInc    = XRAN_SYMBOLNUMBER_NOTINC;
-    sect_geninfo[nsection].info.startPrbc = pPrachCPConfig->startPrbc;
-    sect_geninfo[nsection].info.numPrbc   = pPrachCPConfig->numPrbc,
-    sect_geninfo[nsection].info.numSymbol = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;
-    sect_geninfo[nsection].info.reMask    = 0xfff;
-    sect_geninfo[nsection].info.beamId    = beam_id;
-    sect_geninfo[nsection].info.freqOffset= pPrachCPConfig->freqOffset;
-
-    sect_geninfo[nsection].info.ef        = 0;      // no extension
-    sect_geninfo[nsection].exDataSize     = 0;
-    sect_geninfo[nsection].exData         = NULL;
-    nsection++;
+    sect_geninfo[nsection].info.type        = params->sectionType;       // for database
+    sect_geninfo[nsection].info.startSymId  = params->hdr.startSymId;    // for database
+    sect_geninfo[nsection].info.iqWidth     = params->hdr.iqWidth;       // for database
+    sect_geninfo[nsection].info.compMeth    = params->hdr.compMeth;      // for database
+    sect_geninfo[nsection].info.id          = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
+    sect_geninfo[nsection].info.rb          = XRAN_RBIND_EVERY;
+    sect_geninfo[nsection].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
+    sect_geninfo[nsection].info.startPrbc   = pPrachCPConfig->startPrbc;
+    sect_geninfo[nsection].info.numPrbc     = pPrachCPConfig->numPrbc,
+    sect_geninfo[nsection].info.numSymbol   = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;
+    sect_geninfo[nsection].info.reMask      = 0xfff;
+    sect_geninfo[nsection].info.beamId      = beam_id;
+    sect_geninfo[nsection].info.freqOffset  = pPrachCPConfig->freqOffset;
 
-    params.numSections          = nsection;
-    params.sections             = sect_geninfo;
+    pxran_lib_ctx->prach_last_symbol[cc_id] = sect_geninfo[nsection].info.startSymId + sect_geninfo[nsection].info.numSymbol - 1;
 
-    mbuf = xran_ethdi_mbuf_alloc();
-    if(unlikely(mbuf == NULL)) {
-        print_err("Alloc fail!\n");
-        return (-1);
-        }
+    sect_geninfo[nsection].info.ef          = 0;
+    sect_geninfo[nsection].exDataSize       = 0;
+//    sect_geninfo[nsection].exData           = NULL;
+    nsection++;
 
-    ret = xran_prepare_ctrl_pkt(mbuf, &params, cc_id, prach_port_id, seq_id);
-    if(ret < 0) {
-        print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
-        return (ret);
-        }
-    else {
-        xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
-        for(i=0; i < nsection; i++)
-            xran_cp_add_section_info(pHandle,
-                    XRAN_DIR_UL, cc_id, prach_port_id, subframe_id, slot_id,
-                    &sect_geninfo[i].info);
-        }
+    params->numSections          = nsection;
+    params->sections             = sect_geninfo;
 
-    return (ret);
+    ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, prach_port_id, seq_id);
+    if(ret < 0){
+        print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
+        rte_pktmbuf_free(mbuf);
+    }
+    return ret;
 }
 
 
@@ -338,60 +563,65 @@ int process_ring(struct rte_ring *r)
     struct rte_mbuf *mbufs[MBUFS_CNT];
     int i;
     uint32_t remaining;
+    uint64_t t1;
     const uint16_t dequeued = rte_ring_dequeue_burst(r, (void **)mbufs,
         RTE_DIM(mbufs), &remaining);
 
     if (!dequeued)
         return 0;
+
+    t1 = MLogTick();
     for (i = 0; i < dequeued; ++i) {
         if (xran_ethdi_filter_packet(mbufs[i], 0) == MBUF_FREE)
             rte_pktmbuf_free(mbufs[i]);
     }
+    MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
 
     return remaining;
 }
 
-int ring_processing_thread(void *args)
+int32_t ring_processing_func(void)
 {
-    struct timespec tv = {0};
-    int64_t prev_nsec = 0;
-    uint8_t is_timer_set = 0;
     struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
+    struct xran_device_ctx *const pxran_lib_ctx = xran_dev_get_ctx();
+
+    rte_timer_manage();
+
+    /* UP first */
+    if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
+        return 0;
+    /* CP next */
+    if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
+        return 0;
+
+    if (pxran_lib_ctx->bbdev_dec)
+        pxran_lib_ctx->bbdev_dec();
+
+    if (pxran_lib_ctx->bbdev_enc)
+        pxran_lib_ctx->bbdev_enc();
+
+    if (XRAN_STOPPED == xran_if_current_state)
+        return -1;
+
+    return 0;
+}
+
+int ring_processing_thread(void *args)
+{
     struct sched_param sched_param;
     int res = 0;
 
     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
-    if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
-    {
+    if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){
         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
     }
-    for (;;) {
-        if (!is_timer_set) {
-            if (clock_gettime(CLOCK_REALTIME, &tv) != 0)
-                err(1, "gettimeofday() failed");
-            if (tv.tv_nsec % 125000 < prev_nsec % 125000) { /* crossed an 125ms boundary */
-                rte_timer_manage();     /* timers only run on IO core */
-                is_timer_set = 1;
-            }
-            prev_nsec = tv.tv_nsec;
-        } else {
-            rte_timer_manage();
-        }
 
-        /* UP first */
-        if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
-            continue;
-        /* CP next */
-        if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
-            continue;
-
-        if (XRAN_STOPPED == xran_if_current_state)
+    for (;;)
+        if(ring_processing_func() != 0)
             break;
-    }
 
     puts("Pkt processing thread finished.");
     return 0;
 }
 
-#endif /* _XRAN_COMMON_ */
index ad17c1e..07be798 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
  *    U-plane
 #ifndef _XRAN_COMMON_H_
 #define _XRAN_COMMON_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/param.h>
+
 
 #include <rte_common.h>
 #include <rte_mbuf.h>
 #include <rte_timer.h>
 
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
 #include "xran_pkt_up.h"
+#include "xran_cp_api.h"
+
+#define O_DU 0
+#define O_RU 1
 
-#define APP_LLS_CU 0
-#define APP_RU     1
-#define NUM_OF_PRB_IN_FULL_BAND (66)
 #define N_SC_PER_PRB 12
+#define MAX_N_FULLBAND_SC 273
 #define N_SYM_PER_SLOT 14
-#define N_FULLBAND_SC (NUM_OF_PRB_IN_FULL_BAND*N_SC_PER_PRB)
-#define MAX_ANT_CARRIER_SUPPORTED 16
-/* 0.125, just for testing */
-#define SLOTNUM_PER_SUBFRAME      8
+#define SUBFRAME_DURATION_US 1000
+#define SLOTNUM_PER_SUBFRAME       (SUBFRAME_DURATION_US/interval_us)
 #define SUBFRAMES_PER_SYSTEMFRAME  10
 #define SLOTS_PER_SYSTEMFRAME (SLOTNUM_PER_SUBFRAME*SUBFRAMES_PER_SYSTEMFRAME)
-#define PDSCH_PAYLOAD_SIZE (N_FULLBAND_SC*4)
-#define NUM_OF_SLOT_IN_TDD_LOOP         (80)
-#define IQ_PLAYBACK_BUFFER_BYTES (NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*N_FULLBAND_SC*4L)
 
-/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples. The payload length is 3356 octets.*/
-#define PRACH_PLAYBACK_BUFFER_BYTES (10*839*4L)
+/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples for long sequence or 144*14 (max) for short sequence. The payload length is 3356 octets.*/
+#define PRACH_PLAYBACK_BUFFER_BYTES (144*14*4L)
 
-#define XRAN_MAX_NUM_SECTIONS       (NUM_OF_PRB_IN_FULL_BAND)     // TODO: need to decide proper value
+#define XRAN_MAX_NUM_SECTIONS       (N_SYM_PER_SLOT*2)    /* just an example, no special meaning on this number */
+                                                          /*  and this is the configuration of M-plane */
 
-#define XRAN_MAX_MBUF_LEN 9600 /**< jummbo frame */
-#define NSEC_PER_SEC 1000000000
+#define XRAN_MAX_MBUF_LEN 9600 /**< jumbo frame */
+#define NSEC_PER_SEC 1000000000L
 #define TIMER_RESOLUTION_CYCLES 1596*1 /* 1us */
 #define XRAN_RING_SIZE  512 /*4*14*8 pow of 2 */
 #define XRAN_NAME_MAX_LEN      (64)
 #define XRAN_RING_NUM       (3)
 
-#define MAX_NUM_OF_XRAN_CTX       (2)
-#define XranIncrementCtx(ctx)                             ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
-#define XranDecrementCtx(ctx)                             ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
-
 #define XranDiffSymIdx(prevSymIdx, currSymIdx, numTotalSymIdx)  ((prevSymIdx > currSymIdx) ? ((currSymIdx + numTotalSymIdx) - prevSymIdx) : (currSymIdx - prevSymIdx))
 
-#define XRAN_SYM_JOB_SIZE 512
-
-struct send_symbol_cb_args
-{
-    struct rb_map *samp_buf;
-    uint8_t *symb_id;
-};
-
-struct pkt_dump
-{
-    int num_samp;
-    int num_bytes;
-    uint8_t symb;
-    struct ecpri_seq_id seq;
-} __rte_packed;
+#define XRAN_MLOG_VAR 0 /**< enable debug variables to mlog */
 
 /* PRACH configuration table defines */
 #define XRAN_PRACH_CANDIDATE_PREAMBLE    (2)
@@ -144,27 +129,30 @@ typedef struct
     uint8_t    numSymbol;
     uint16_t   timeOffset;
     int32_t    freqOffset;
+    uint8_t    nrofPrachInSlot;
     uint8_t    occassionsInPrachSlot;
     uint8_t    x;
     uint8_t    y[XRAN_PRACH_CANDIDATE_Y];
     uint8_t    isPRACHslot[XRAN_PRACH_CANDIDATE_SLOT];
 }xRANPrachCPConfigStruct;
 
+#define XRAN_MAX_POOLS_PER_SECTOR_NR 3 /**< TX_OUT, RX_IN, PRACH_IN */
 
-typedef struct DeviceHandleInfo
+typedef struct sectorHandleInfo
 {
     /**< Structure that contains the information to describe the
      * instance i.e service type, virtual function, package Id etc..*/
     uint16_t nIndex;
+    uint16_t nXranPort;
     /* Unique ID of an handle shared between phy layer and library */
     /**< number of antennas supported per link*/
     uint32_t nBufferPoolIndex;
     /**< Buffer poolIndex*/
-    struct rte_mempool * p_bufferPool[XRAN_MAX_SECTOR_NR];
-    uint32_t bufferPoolElmSz[XRAN_MAX_SECTOR_NR];
-    uint32_t bufferPoolNumElm[XRAN_MAX_SECTOR_NR];
+    struct rte_mempool * p_bufferPool[XRAN_MAX_POOLS_PER_SECTOR_NR];
+    uint32_t bufferPoolElmSz[XRAN_MAX_POOLS_PER_SECTOR_NR];
+    uint32_t bufferPoolNumElm[XRAN_MAX_POOLS_PER_SECTOR_NR];
 
-}XranLibHandleInfoStruct;
+}XranSectorHandleInfo, *PXranSectorHandleInfo;
 
 typedef void (*XranSymCallbackFn)(struct rte_timer *tim, void* arg);
 
@@ -184,7 +172,7 @@ typedef struct {
                        // -1 means that DL packet to be transmitted is not ready in BS
     int32_t nSegTransferred; // number of data segments has been transmitted or received
     struct rte_mbuf *pData[XRAN_N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
-    XRANBufferListStruct sBufferList;
+    struct xran_buffer_list sBufferList;
 } BbuIoBufCtrlStruct;
 
 struct xran_sym_job {
@@ -194,37 +182,45 @@ struct xran_sym_job {
 
 #define XranIncrementJob(i)                  ((i >= (XRAN_SYM_JOB_SIZE-1)) ? 0 : (i+1))
 
-struct xran_lib_ctx
+#define XRAN_MAX_PKT_BURST_PER_SYM 32
+#define XRAN_MAX_PACKET_FRAG 9
+
+#define MBUF_TABLE_SIZE  (2 * MAX(XRAN_MAX_PKT_BURST_PER_SYM, XRAN_MAX_PACKET_FRAG))
+
+struct mbuf_table {
+       uint16_t len;
+       struct rte_mbuf *m_table[MBUF_TABLE_SIZE];
+};
+
+struct xran_device_ctx
 {
-    uint8_t llscu_id;
     uint8_t sector_id;
-    XRANEAXCIDCONFIG eAxc_id_cfg;
-    XRANFHINIT   xran_init_cfg;
-    XRANFHCONFIG xran_fh_cfg;
-    XranLibHandleInfoStruct* pDevHandle;
+    uint8_t xran_port_id;
+    struct xran_eaxcid_config eAxc_id_cfg;
+    struct xran_fh_init   fh_init;
+    struct xran_fh_config fh_cfg;
+    uint32_t enablePrach;
     xRANPrachCPConfigStruct PrachCPConfig;
     uint32_t enableCP;
-    char ring_name[XRAN_RING_NUM][XRAN_MAX_SECTOR_NR][RTE_RING_NAMESIZE];
-    struct rte_ring *dl_sym_idx_ring[XRAN_MAX_SECTOR_NR];
-    struct rte_ring *xran2phy_ring[XRAN_MAX_SECTOR_NR];
-    struct rte_ring *xran2prach_ring[XRAN_MAX_SECTOR_NR];
-
-    struct xran_sym_job sym_job[XRAN_SYM_JOB_SIZE];
-    uint32_t sym_job_idx;
+    int32_t DynamicSectionEna;
 
     BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
     BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+    BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
     BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
 
     /* buffers lists */
-    XRANFlatBufferStruct sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
-    XRANFlatBufferStruct sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
-    XRANFlatBufferStruct sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
 
-    XranTransportBlockCallbackFn pCallback[XRAN_MAX_SECTOR_NR];
+    xran_transport_callback_fn pCallback[XRAN_MAX_SECTOR_NR];
     void *pCallbackTag[XRAN_MAX_SECTOR_NR];
 
-    XranTransportBlockCallbackFn pPrachCallback[XRAN_MAX_SECTOR_NR];
+    xran_transport_callback_fn pPrachCallback[XRAN_MAX_SECTOR_NR];
     void *pPrachCallbackTag[XRAN_MAX_SECTOR_NR];
 
     XranSymCallbackFn pSymCallback[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
@@ -233,21 +229,38 @@ struct xran_lib_ctx
     int32_t sym_up; /**< when we start sym 0 of up with respect to OTA time as measured in symbols */
     int32_t sym_up_ul;
 
-    XRANFHTTIPROCCB ttiCb[XRAN_CB_MAX];
+    xran_fh_tti_callback_fn ttiCb[XRAN_CB_MAX];
     void *TtiCbParam[XRAN_CB_MAX];
     uint32_t SkipTti[XRAN_CB_MAX];
 
     int xran2phy_mem_ready;
 
     int rx_packet_symb_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+    int rx_packet_prach_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
     int rx_packet_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
+    int rx_packet_prach_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
+    int prach_start_symbol[XRAN_MAX_SECTOR_NR];
+    int prach_last_symbol[XRAN_MAX_SECTOR_NR];
+
     int phy_tti_cb_done;
+
+    struct rte_mempool *direct_pool;
+    struct rte_mempool *indirect_pool;
+    struct mbuf_table  tx_mbufs[RTE_MAX_ETHPORTS];
+
+    struct xran_common_counters fh_counters;
+
+    phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
+    phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
 };
 
+extern long rx_counter;
+extern long tx_counter;
+
 extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_fdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
 extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_tdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
 extern const xRANPrachConfigTableStruct gxranPrachDataTable_mmw[XRAN_PRACH_CONFIG_TABLE_SIZE];
-extern const xRANPrachPreambleLRAStruct gxranPreambleforLRA[XRAN_PRACH_PREAMBLE_FORMAT_OF_ABC];
+extern const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13];
 
 int process_mbuf(struct rte_mbuf *pkt);
 int process_ring(struct rte_ring *r);
@@ -256,7 +269,9 @@ int packets_dump_thread(void *args);
 
 int send_symbol_ex(enum xran_pkt_dir direction,
                 uint16_t section_id,
+                struct rte_mbuf *mb,
                 struct rb_map *data,
+                const enum xran_input_byte_order iq_buf_byte_order,
                 uint8_t frame_id,
                 uint8_t subframe_id,
                 uint8_t slot_id,
@@ -267,20 +282,35 @@ int send_symbol_ex(enum xran_pkt_dir direction,
                 uint8_t RU_Port_ID,
                 uint8_t seq_id);
 
-int send_cpmsg_dlul(void *pHandle, enum xran_pkt_dir dir,
-                uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
-                uint8_t startsym, uint8_t numsym, int prb_num,
-                uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id,
-                uint8_t seq_id);
+int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
+                uint16_t section_id,
+                struct rte_mbuf *mb,
+                struct rb_map *data,
+                const enum xran_input_byte_order iq_buf_byte_order,
+                uint8_t frame_id,
+                uint8_t subframe_id,
+                uint8_t slot_id,
+                uint8_t symbol_no,
+                int prb_start,
+                int prb_num,
+                uint8_t CC_ID,
+                uint8_t RU_Port_ID,
+                uint8_t seq_id,
+                uint32_t do_copy);
 
-int send_cpmsg_prach(void *pHandle,
-                uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
-                uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id,
-                uint8_t seq_id);
+int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
+                struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id);
 
-uint8_t xran_get_max_sections(void *pHandle);
+int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
+    enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+    uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,
+    uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t seq_id, uint8_t symInc);
 
-XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle);
+int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx,
+                uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+                uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id);
+
+struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle);
 uint8_t xran_get_conf_prach_scs(void *pHandle);
 uint8_t xran_get_conf_fftsize(void *pHandle);
 uint8_t xran_get_conf_numerology(void *pHandle);
@@ -289,12 +319,16 @@ uint8_t xran_get_conf_compmethod(void *pHandle);
 
 uint8_t xran_get_num_cc(void *pHandle);
 uint8_t xran_get_num_eAxc(void *pHandle);
-uint8_t xran_get_llscuid(void *pHandle);
-uint8_t xran_get_sectorid(void *pHandle);
-struct xran_lib_ctx *xran_lib_get_ctx(void);
+struct xran_device_ctx *xran_dev_get_ctx(void);
 
 uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
 uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
+int32_t ring_processing_func(void);
+int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
 
diff --git a/fhi_lib/lib/src/xran_compression.cpp b/fhi_lib/lib/src/xran_compression.cpp
new file mode 100644 (file)
index 0000000..8730a20
--- /dev/null
@@ -0,0 +1,185 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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.
+*
+*******************************************************************************/
+
+#include "xran_compression.hpp"
+#include <complex>
+#include <algorithm>
+#include <immintrin.h>
+
+void
+BlockFloatCompander::BlockFloatCompress_AVX512(const ExpandedData& dataIn, CompressedData* dataOut)
+{
+  __m512i maxAbs = __m512i();
+
+  /// Load data and find max(abs(RB))
+  const __m512i* rawData = reinterpret_cast<const __m512i*>(dataIn.dataExpanded);
+  static constexpr int k_numInputLoopIts = BlockFloatCompander::k_numRB / 4;
+
+#pragma unroll(k_numInputLoopIts)
+  for (int n = 0; n < k_numInputLoopIts; ++n)
+  {
+    /// Re-order the next 4RB in input data into 3 registers
+    /// Input SIMD vectors are:
+    ///   [A A A A A A A A A A A A B B B B]
+    ///   [B B B B B B B B C C C C C C C C]
+    ///   [C C C C D D D D D D D D D D D D]
+    /// Re-ordered SIMD vectors are:
+    ///   [A A A A B B B B C C C C D D D D]
+    ///   [A A A A B B B B C C C C D D D D]
+    ///   [A A A A B B B B C C C C D D D D]
+    static constexpr uint8_t k_msk1 = 0b11111100; // Copy first lane of src
+    static constexpr int k_shuff1 = 0x41;
+    const auto z_w1 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 0], k_msk1, rawData[3 * n + 1], rawData[3 * n + 2], k_shuff1);
+
+    static constexpr uint8_t k_msk2 = 0b11000011; // Copy middle two lanes of src
+    static constexpr int k_shuff2 = 0xB1;
+    const auto z_w2 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 1], k_msk2, rawData[3 * n + 0], rawData[3 * n + 2], k_shuff2);
+
+    static constexpr uint8_t k_msk3 = 0b00111111; // Copy last lane of src
+    static constexpr int k_shuff3 = 0xBE;
+    const auto z_w3 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 2], k_msk3, rawData[3 * n + 0], rawData[3 * n + 1], k_shuff3);
+
+    /// Perform max abs on these 3 registers
+    const auto abs16_1 = _mm512_abs_epi16(z_w1);
+    const auto abs16_2 = _mm512_abs_epi16(z_w2);
+    const auto abs16_3 = _mm512_abs_epi16(z_w3);
+    const auto maxAbs_12 = _mm512_max_epi16(abs16_1, abs16_2);
+    const auto maxAbs_123 = _mm512_max_epi16(maxAbs_12, abs16_3);
+
+    /// Perform horizontal max over each lane
+    /// Swap 64b in each lane and compute max
+    static const auto k_perm64b = _mm512_set_epi64(6, 7, 4, 5, 2, 3, 0, 1);
+    auto maxAbsPerm = _mm512_permutexvar_epi64(k_perm64b, maxAbs_123);
+    auto maxAbsHorz = _mm512_max_epi16(maxAbs_123, maxAbsPerm);
+
+    /// Swap each pair of 32b in each lane and compute max
+    static const auto k_perm32b = _mm512_set_epi32(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+    maxAbsPerm = _mm512_permutexvar_epi32(k_perm32b, maxAbsHorz);
+    maxAbsHorz = _mm512_max_epi16(maxAbsHorz, maxAbsPerm);
+
+    /// Swap each IQ pair in each lane (via 32b rotation) and compute max
+    maxAbsPerm = _mm512_rol_epi32(maxAbsHorz, BlockFloatCompander::k_numBitsIQ);
+    maxAbsHorz = _mm512_max_epi16(maxAbsHorz, maxAbsPerm);
+
+    /// Insert values into maxAbs
+    /// Use sliding mask to insert wanted values into maxAbs
+    /// Pairs of values will be inserted and corrected outside of loop
+    static const auto k_select4RB = _mm512_set_epi32(28, 24, 20, 16, 28, 24, 20, 16,
+                                                     28, 24, 20, 16, 28, 24, 20, 16);
+    static constexpr uint16_t k_expMsk[k_numInputLoopIts] = { 0x000F, 0x00F0, 0x0F00, 0xF000 };
+    maxAbs = _mm512_mask_permutex2var_epi32(maxAbs, k_expMsk[n], k_select4RB, maxAbsHorz);
+  }
+
+  /// Convert to 32b by removing repeated values in maxAbs
+  static const auto k_upperWordMask = _mm512_set_epi64(0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+                                                       0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+                                                       0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+                                                       0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF);
+  maxAbs = _mm512_and_epi64(maxAbs, k_upperWordMask);
+
+  /// Compute exponent and store for later use
+  static constexpr int k_expTotShiftBits = 32 - BlockFloatCompander::k_iqWidth + 1;
+  const auto totShiftBits = _mm512_set1_epi32(k_expTotShiftBits);
+  const auto lzCount = _mm512_lzcnt_epi32(maxAbs);
+  const auto exponent = _mm512_sub_epi32(totShiftBits, lzCount);
+  int8_t storedExp[BlockFloatCompander::k_numRB] = {};
+  static constexpr uint16_t k_expWriteMask = 0xFFFF;
+  _mm512_mask_cvtepi32_storeu_epi8(storedExp, k_expWriteMask, exponent);
+
+  /// Shift 1RB by corresponding exponent and write exponent and data to output
+  /// Output data is packed exponent first followed by corresponding compressed RB
+#pragma unroll(BlockFloatCompander::k_numRB)
+  for (int n = 0; n < BlockFloatCompander::k_numRB; ++n)
+  {
+    const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(dataIn.dataExpanded + n * BlockFloatCompander::k_numREReal);
+    auto compData = _mm512_srai_epi16(*rawDataIn, storedExp[n]);
+
+    dataOut->dataCompressed[n * (BlockFloatCompander::k_numREReal + 1)] = storedExp[n];
+    static constexpr uint32_t k_rbMask = 0x00FFFFFF; // Write mask for 1RB (24 values)
+    _mm512_mask_cvtepi16_storeu_epi8(dataOut->dataCompressed + n * (BlockFloatCompander::k_numREReal + 1) + 1, k_rbMask, compData);
+  }
+}
+
+
+void
+BlockFloatCompander::BlockFloatExpand_AVX512(const CompressedData& dataIn, ExpandedData* dataOut)
+{
+#pragma unroll(BlockFloatCompander::k_numRB)
+  for (int n = 0; n < BlockFloatCompander::k_numRB; ++n)
+  {
+    /// Expand 1RB of data
+    const __m256i* rawDataIn = reinterpret_cast<const __m256i*>(dataIn.dataCompressed + n * (BlockFloatCompander::k_numREReal + 1) + 1);
+    const auto compData16 = _mm512_cvtepi8_epi16(*rawDataIn);
+    const auto expData = _mm512_slli_epi16(compData16, *(dataIn.dataCompressed + n * (BlockFloatCompander::k_numREReal + 1)));
+
+    /// Write expanded data to output
+    static constexpr uint8_t k_rbMask64 = 0b00111111; // 64b write mask for 1RB (24 int16 values)
+    _mm512_mask_storeu_epi64(dataOut->dataExpanded + n * BlockFloatCompander::k_numREReal, k_rbMask64, expData);
+  }
+}
+
+
+void
+BlockFloatCompander::BlockFloatCompress_Basic(const ExpandedData& dataIn, CompressedData* dataOut)
+{
+  int16_t maxAbs[BlockFloatCompander::k_numRB];
+  for (int rb = 0; rb < BlockFloatCompander::k_numRB; ++rb)
+  {
+    // Find max abs value for this RB
+    maxAbs[rb] = 0;
+    for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+    {
+      auto dataIdx = rb * BlockFloatCompander::k_numREReal + re;
+      int16_t dataAbs = (int16_t)std::abs(dataIn.dataExpanded[dataIdx]);
+      maxAbs[rb] = std::max(maxAbs[rb], dataAbs);
+    }
+
+    // Find exponent
+    static constexpr int k_expTotShiftBits16 = 16 - BlockFloatCompander::k_iqWidth + 1;
+    auto thisExp = (int8_t)(k_expTotShiftBits16 - __lzcnt16(maxAbs[rb]));
+    auto expIdx = rb * (BlockFloatCompander::k_numREReal + 1);
+    dataOut->dataCompressed[expIdx] = thisExp;
+
+    // ARS data by exponent
+    for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+    {
+      auto dataIdxIn = rb * BlockFloatCompander::k_numREReal + re;
+      auto dataIdxOut = (expIdx + 1) + re;
+      dataOut->dataCompressed[dataIdxOut] = (int8_t)(dataIn.dataExpanded[dataIdxIn] >> thisExp);
+    }
+  }
+}
+
+
+void
+BlockFloatCompander::BlockFloatExpand_Basic(const CompressedData& dataIn, ExpandedData* dataOut)
+{
+  // Expand data
+  for (int rb = 0; rb < BlockFloatCompander::k_numRB; ++rb)
+  {
+    for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+    {
+      auto dataIdxOut = rb * BlockFloatCompander::k_numREReal + re;
+      auto expIdx = rb * (BlockFloatCompander::k_numREReal + 1);
+      auto dataIdxIn = (expIdx + 1) + re;
+      auto thisData = (int16_t)dataIn.dataCompressed[dataIdxIn];
+      auto thisExp = (int16_t)dataIn.dataCompressed[expIdx];
+      dataOut->dataExpanded[dataIdxOut] = (int16_t)(thisData << thisExp);
+    }
+  }
+}
index d42b22b..03becc9 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the API functions to build Control Plane Messages
  *      for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
 #include "xran_common.h"
 #include "xran_transport.h"
 #include "xran_cp_api.h"
-#include "xran_hash.h"
 #include "xran_printf.h"
 
 
+/**
+ * This structure to store the section information of C-Plane
+ * in order to generate and parse corresponding U-Plane */
 struct xran_sectioninfo_db {
-    uint32_t    max_num;
-    uint32_t    cur_index;
-#if defined(XRAN_CP_USES_HASHTABLE)
-    struct rte_hash *hash;
-#endif
-    struct xran_section_info *list;
+    uint32_t    cur_index;  /**< Current index to store fro this eAXC */
+    struct xran_section_info list[XRAN_MAX_NUM_SECTIONS]; /**< The array of section information */
     };
 
+static struct xran_sectioninfo_db sectiondb[XRAN_MAX_SECTIONDB_CTX][XRAN_DIR_MAX][XRAN_COMPONENT_CARRIERS_MAX][XRAN_MAX_ANTENNA_NR*2];
 
-static struct xran_sectioninfo_db *sectiondb[XRAN_DIR_MAX];
 
+/**
+ * @brief Initialize section database.
+ *   Allocate required memory space to store section information.
+ *   Each eAxC allocates dedicated storage and the entry size is the maximum number of sections.
+ *   Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
+ */
 int xran_cp_init_sectiondb(void *pHandle)
 {
-  int i, j, k;
-  uint32_t size;
-  uint16_t cid;
-  struct xran_sectioninfo_db *ptr;
-  uint8_t num_eAxc;
+  int ctx, dir, cc, ant;
 
+    for(ctx=0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++)
+        for(dir=0; dir < XRAN_DIR_MAX; dir++)
+            for(cc=0; cc < XRAN_COMPONENT_CARRIERS_MAX; cc++)
+                for(ant=0; ant < XRAN_MAX_ANTENNA_NR*2; ant++)
+                    sectiondb[ctx][dir][cc][ant].cur_index = 0;
 
-#if !defined(PRACH_USES_SHARED_PORT)
-    num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
-    num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
-    for(i=0; i < XRAN_DIR_MAX; i++) {
-        size = (xran_get_num_cc(pHandle) * num_eAxc * sizeof(struct xran_sectioninfo_db));
-        print_log("Allocation Size for Section DB : %d (%dx%dx%ld)", size
-                    , xran_get_num_cc(pHandle)
-                    , num_eAxc
-                    , sizeof(struct xran_sectioninfo_db));
-        sectiondb[i] = malloc(size);
-
-        if(sectiondb[i] == NULL) {
-            print_err("Allocation Failed for Section DB!");
-            return (-XRAN_ERRCODE_OUTOFMEMORY);
-            }
-
-        for(j=0; j < xran_get_num_cc(pHandle); j++) {         // CC
-            for(k=0; k < num_eAxc; k++) {   // antenna
-                ptr = sectiondb[i] + num_eAxc*j + k;
-
-                ptr->max_num = xran_get_max_sections(pHandle);
-                ptr->cur_index = 0;
-
-                // allicate array to store section information
-                size = sizeof(struct xran_section_info)*xran_get_max_sections(pHandle);
-                print_log("Allocation Size for list : %d (%ldx%d)", size,
-                            sizeof(struct xran_section_info),
-                            xran_get_max_sections(pHandle));
-                ptr->list = malloc(size);
-                if(ptr-> list  == NULL) {
-                    print_err("Allocation Failed for Section DB!");
-                    return (-XRAN_ERRCODE_OUTOFMEMORY);
-                    }
-
-#if defined(XRAN_CP_USES_HASHTABLE)
-                // Create hash table for section information
-                cid = rte_be_to_cpu_16(xran_compose_cid(xran_get_llscuid(pHandle), xran_get_sectorid(pHandle), j, k));
-                print_log("Creating hash for %04X", cid);
-                ptr->hash = xran_section_init_hash(i, cid, xran_get_max_sections(pHandle));
-#endif
-                }
-            }
-        }
-
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
+/**
+ * @brief Release and free section database
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ */
 int xran_cp_free_sectiondb(void *pHandle)
 {
-  int i, j, k;
-  uint32_t size;
-  struct xran_sectioninfo_db *ptr;
-  uint8_t num_eAxc;
-
-#if !defined(PRACH_USES_SHARED_PORT)
-    num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
-    num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
-    for(i=0; i < XRAN_DIR_MAX; i++) {
-        for(j=0; j < xran_get_num_cc(pHandle); j++) {         // CC
-            for(k=0; k < num_eAxc; k++) {   // antenna
-                ptr = sectiondb[i] + num_eAxc*j + k;
-
-#if defined(XRAN_CP_USES_HASHTABLE)
-                xran_section_free_hash(ptr->hash);
-#endif
-                if(ptr->list != NULL)
-                    free(ptr->list);
-                else print_err("list is NULL");
-                }
-            }
-        if(sectiondb[i] != NULL)
-            free(sectiondb[i]);
-        else print_err("sectiondb[%d] is NULL", i);
-        }
-
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
-static struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
-        uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+static inline struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
+        uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
 {
   struct xran_sectioninfo_db *ptr;
-  uint8_t num_eAxc;
 
-    if(unlikely(dir>=XRAN_DIR_MAX)) {
+
+    if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
+        print_err("Invalid Context id - %d", ctx_id);
+        return (NULL);
+        }
+
+    if(unlikely(dir >= XRAN_DIR_MAX)) {
         print_err("Invalid direction - %d", dir);
         return (NULL);
         }
 
-    if(unlikely(cc_id >= xran_get_num_cc(pHandle))) {
+    if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
         print_err("Invalid CC id - %d", cc_id);
         return (NULL);
         }
 
-#if !defined(PRACH_USES_SHARED_PORT)
-    num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
-    num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
-    if(unlikely(ruport_id >= num_eAxc)) {
+    if(unlikely(ruport_id >= XRAN_MAX_ANTENNA_NR*2)) {
         print_err("Invalid eAxC id - %d", ruport_id);
         return (NULL);
         }
 
-    ptr = sectiondb[dir] + xran_get_num_eAxc(pHandle)*cc_id + ruport_id;
+    ptr = &sectiondb[ctx_id][dir][cc_id][ruport_id];
 
     return(ptr);
 }
 
-static struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
+static inline struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
 {
     if(unlikely(ptr == NULL))
         return (NULL);
 
-    if(unlikely(ptr->max_num < index)) {
+    if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
         print_err("Index is out of range - %d", index);
         return (NULL);
         }
@@ -186,196 +131,650 @@ static struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_d
     return(&(ptr->list[index]));
 }
 
+/**
+ * @brief Add a section information of C-Plane to dabase.
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @param dir
+ *  Direction of C-Plane message for the section to store
+ * @param cc_id
+ *  CC ID of C-Plane message for the section to store
+ * @param ruport_id
+ *  RU port ID of C-Plane message for the section to store
+ * @param ctx_id
+ *  Context index for the section database
+ * @param info
+ *  The information of this section to store
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARAM, if direction, CC ID or RU port ID is incorrect
+ *  XRAN_STATUS_RESOURCE, if no more space to add on database
+ */
 int xran_cp_add_section_info(void *pHandle,
-        uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id,
+        uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
         struct xran_section_info *info)
 {
   struct xran_sectioninfo_db *ptr;
   struct xran_section_info *list;
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL)) {
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 
-    if(unlikely(ptr->cur_index >= ptr->max_num)) {
+    if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
         print_err("No more space to add section information!");
-        return (-XRAN_ERRCODE_OUTOFMEMORY);
+        return (XRAN_STATUS_RESOURCE);
         }
 
     list = xran_get_section_info(ptr, ptr->cur_index);
 
     rte_memcpy(list, info, sizeof(struct xran_section_info));
-#if defined(XRAN_CP_USES_HASHTABLE)
-    xran_section_add_hash(ptr->hash, info->id, ptr->cur_index);
-#endif
 
     ptr->cur_index++;
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 int xran_cp_add_multisection_info(void *pHandle,
-        uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id,
-        uint8_t num_sections, struct xran_section_gen_info *gen_info)
+        uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
+        struct xran_cp_gen_params *gen_info)
 {
   int i;
+  uint8_t dir, num_sections;
   struct xran_sectioninfo_db *ptr;
   struct xran_section_info *list;
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+
+    dir             = gen_info->dir;
+    num_sections    = gen_info->numSections;
+
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL)) {
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 
-    if(unlikely(ptr->cur_index >= (ptr->max_num+num_sections))) {
+    if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
         print_err("No more space to add section information!");
-        return (-XRAN_ERRCODE_OUTOFMEMORY);
+        return (XRAN_STATUS_RESOURCE);
         }
 
     list = xran_get_section_info(ptr, ptr->cur_index);
 
     for(i=0; i<num_sections; i++) {
-        rte_memcpy(&list[i], &gen_info[i].info, sizeof(struct xran_section_info));
-#if defined(XRAN_CP_USES_HASHTABLE)
-        xran_section_add_hash(ptr->hash, gen_info[i].info.id, ptr->cur_index);
-#endif
+        rte_memcpy(&list[i], &gen_info->sections[i].info, sizeof(struct xran_section_info));
         ptr->cur_index++;
         }
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
+/**
+ * @brief Find a section information of C-Plane from dabase
+ *   by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @param dir
+ *  The direction of the section to find
+ * @param cc_id
+ *  The CC ID of the section to find
+ * @param ruport_id
+ *  RU port ID of the section to find
+ * @param ctx_id
+ *  Context index for the section database
+ * @param section_id
+ *  The ID of section to find
+ * @return
+ *  The pointer of section information if matched section is found
+ *  NULL if failed to find matched section
+ */
 struct xran_section_info *xran_cp_find_section_info(void *pHandle,
         uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id,
-        uint16_t section_id)
+        uint8_t ctx_id, uint16_t section_id)
 {
-  int index;
+  int index, num_index;
   struct xran_sectioninfo_db *ptr;
 
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL))
         return (NULL);
 
-#if defined(XRAN_CP_USES_HASHTABLE)
-    index = xran_section_lookup(ptr->hash, section_id);
-    if(unlikely(index > ptr->max_num)) {
-        print_err("Invalid index - %d", index);
-        return (NULL);
-        }
-
-    if(index < 0) {
-        print_dbg("No section ID in the list - %d", section_id);
-        return (NULL);
-        }
+    if(ptr->cur_index > XRAN_MAX_NUM_SECTIONS)
+        num_index = XRAN_MAX_NUM_SECTIONS;
+    else
+        num_index = ptr->cur_index;
 
-    return (xran_get_section_info(ptr, index));
-#else
-    for(index=0; index<ptr->cur_index; index++) {
+    for(index=0; index < num_index; index++) {
         if(ptr->list[index].id == section_id) {
-            print_dbg("Found section info %04X", section_id);
             return (xran_get_section_info(ptr, index));
             }
         }
 
     print_dbg("No section ID in the list - %d", section_id);
     return (NULL);
-#endif
-
 }
 
+/**
+ * @brief Iterate each section information of C-Plane
+ *  from the database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @param dir
+ *  The direction of the section to find
+ * @param cc_id
+ *  The CC ID of the section to find
+ * @param ruport_id
+ *  RU port ID of the section to find
+ * @param ctx_id
+ *  Context index for the section database
+ * @param next
+ *  The pointer to store the position of next entry
+ * @return
+ *  The pointer of section information in the list
+ *  NULL if reached at the end of the list
+ */
 struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
         uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
-        uint8_t subframe_id, uint8_t slot_id, uint32_t *next)
+        uint8_t ctx_id, uint32_t *next)
 {
   int index;
   struct xran_sectioninfo_db *ptr;
 
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL))
         return (NULL);
 
-#if defined(XRAN_CP_USES_HASHTABLE)
-    index = xran_section_iterate(ptr->hash, next);
-    if(unlikely(index > ptr->max_num)) {
-        print_err("Invalid index - %d", index);
-        return (NULL);
-        }
-
-    if(index < 0) {
-        print_dbg("No section ID in the list - %d", section_id);
-        return (NULL);
-        }
-
-    return (xran_get_section_info(ptr, index));
-#else
     index = *next;
     if(*next < ptr->cur_index) {
         (*next)++;
         return (xran_get_section_info(ptr, index));
         }
-    else 
+    else {
         print_dbg("No more sections in the list");
-
-    return (NULL);
-#endif
+        return (NULL);
+        }
 }
 
-int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+/**
+ * @brief Get the size of stored entries
+ *  for the database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @param dir
+ *  The direction of the section to find
+ * @param cc_id
+ *  The CC ID of the section to find
+ * @param ruport_id
+ *  RU port ID of the section to find
+ * @param ctx_id
+ *  Context index for the section database
+ * @return
+ *  The size of stored entries
+ *  -1 if failed to find matched database
+ */
+int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
 {
   int i, index;
   struct xran_sectioninfo_db *ptr;
 
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL))
         return (-1);
 
     return (ptr->cur_index);
 }
 
-int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+/**
+ * @brief Reset a database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ *  handle for xRAN interface, currently not being used
+ * @param dir
+ *  The direction of the section to find
+ * @param cc_id
+ *  The CC ID of the section to find
+ * @param ruport_id
+ *  RU port ID of the section to find
+ * @param ctx_id
+ *  Context index for the section database
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if failed to find matched database
+ */
+int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
 {
   struct xran_sectioninfo_db *ptr;
 
-    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+    ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
     if(unlikely(ptr == NULL)) {
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 
     ptr->cur_index = 0;
-#if defined(XRAN_CP_USES_HASHTABLE)
-    xran_section_reset_hash(ptr->hash);
-#endif
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
+
 int xran_dump_sectiondb(void)
 {
     // TODO:
     return (0);
 }
 
-
 // Cyclic Prefix Length 5.4.4.14
-// CP_length = cpLength * Ts * 2^u,  Ts = 1/30.72MHz, if u is N/A, it shall be zero
+//   CP_length = cpLength * Ts,  Ts = 1/30.72MHz
+//    i.e cpLength = CP_length / Ts ?
 #define CPLEN_TS           (30720000)
-inline uint16_t xran_get_cplength(int cpLength, int uval)    // uval = -1 for N/A
+inline uint16_t xran_get_cplength(int CP_length)
 {
-    return ((cpLength * ((uval<0)?0:(2<<uval))) / (CPLEN_TS));
+    return (CP_length);
 }
 
 // Frequency offset 5.4.5.11
-// frequency_offset = freqOffset * SCS * 0.5
-inline int32_t xran_get_freqoffset(int freqOffset, int scs)
+//   frequency_offset = freqOffset * SCS * 0.5
+//    i.e freqOffset = (frequency_offset *2 )/ SCS ?
+inline int32_t xran_get_freqoffset(int32_t freqOffset, int32_t scs)
 {
-    return ((freqOffset * scs)>>1);
+    return (freqOffset);
+}
+
+
+static int xran_prepare_sectionext_1(struct rte_mbuf *mbuf,
+                struct xran_sectionext1_info *params, int last_flag)
+{
+  struct xran_cp_radioapp_section_ext1 *ext1;
+  uint8_t *data;
+  int parm_size, iq_size;
+  int total_len;
+  static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
+
+
+    total_len = 0;
+
+    parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
+    ext1 = (struct xran_cp_radioapp_section_ext1 *)rte_pktmbuf_append(mbuf, parm_size);
+    if(ext1 == NULL) {
+        print_err("Fail to allocate the space for section extension 1");
+        return (XRAN_STATUS_RESOURCE);
+        }
+
+    total_len += parm_size;
+
+    ext1->extType       = XRAN_CP_SECTIONEXTCMD_1;
+    ext1->ef            = last_flag;
+    ext1->bfwCompMeth   = params->bfwCompMeth;
+    ext1->bfwIqWidth    = XRAN_CONVERT_BFWIQWIDTH(params->bfwiqWidth);
+
+    switch(params->bfwCompMeth) {
+        case XRAN_BFWCOMPMETHOD_BLKFLOAT:
+            parm_size = 1;
+            data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+            if(data == NULL) {
+                print_err("Fail to allocate the space for section extension 1");
+                return (XRAN_STATUS_RESOURCE);
+                }
+            total_len += parm_size;
+            *data = (params->bfwCompParam.exponent & 0x0f);
+            break;
+
+        case XRAN_BFWCOMPMETHOD_BLKSCALE:
+            parm_size = 1;
+            data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+            if(data == NULL) {
+                print_err("Fail to allocate the space for section extension 1");
+                return (XRAN_STATUS_RESOURCE);
+                }
+            total_len += parm_size;
+            *data = params->bfwCompParam.blockScaler;
+            break;
+
+        case XRAN_BFWCOMPMETHOD_ULAW:
+            parm_size = 1;
+            data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+            if(data == NULL) {
+                print_err("Fail to allocate the space for section extension 1");
+                return (XRAN_STATUS_RESOURCE);
+                }
+            total_len += parm_size;
+            *data = params->bfwCompParam.compBitWidthShift;
+            break;
+
+        case XRAN_BFWCOMPMETHOD_BEAMSPACE:
+#if 0
+            parm_size = ceil(params->bfwNumber/8)*8;
+#else
+            parm_size = params->bfwNumber>>3;
+            if(params->bfwNumber%8) parm_size++;
+            parm_size *= 8;
+#endif
+            data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+            if(data == NULL) {
+                print_err("Fail to allocate the space for section extension 1");
+                return (XRAN_STATUS_RESOURCE);
+                }
+            rte_memcpy(data, params->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
+            total_len += parm_size;
+            break;
+
+        case XRAN_BFWCOMPMETHOD_NONE:
+        default:
+            parm_size = 0;
+        }
+
+    iq_size = params->bfwNumber * params->bfwiqWidth * 2;
+#if 0
+    parm_size = ceil(iq_size/8);
+#else
+    parm_size = iq_size>>3;
+    if(iq_size%8) parm_size++;
+#endif
+
+    data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+    if(data == NULL) {
+        print_err("Fail to allocate the space for section extension 1");
+        return (XRAN_STATUS_RESOURCE);
+        }
+    rte_memcpy(data, params->bfwIQ, parm_size);
+
+    total_len += parm_size;
+    parm_size = total_len % XRAN_SECTIONEXT_ALIGN;
+    if(parm_size) {
+        parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
+        data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+        if(data == NULL) {
+            print_err("Fail to allocate the space for section extension 1");
+            return (XRAN_STATUS_RESOURCE);
+            }
+        rte_memcpy(data, zeropad, parm_size);
+        total_len += parm_size;
+        }
+
+    ext1->extLen        = total_len / XRAN_SECTIONEXT_ALIGN;
+
+    return (total_len);
+}
+
+static int xran_prepare_sectionext_2(struct rte_mbuf *mbuf,
+                struct xran_sectionext2_info *params, int last_flag)
+{
+  struct xran_cp_radioapp_section_ext2 *ext2;
+  uint8_t *data;
+  int total_len;
+  int parm_size;
+  uint32_t val, shift_val;
+  int val_size;
+
+
+    total_len = 0;
+
+    parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
+    ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
+    if(ext2 == NULL) {
+        print_err("Fail to allocate the space for section extension 2");
+        return (XRAN_STATUS_RESOURCE);
+        }
+    total_len += parm_size;
+
+    ext2->extType           = XRAN_CP_SECTIONEXTCMD_2;
+    ext2->ef                = last_flag;
+    ext2->bfZe3ddWidth      = params->bfZe3ddWidth;
+    ext2->bfAz3ddWidth      = params->bfAz3ddWidth;
+    ext2->bfZePtWidth       = params->bfZePtWidth;
+    ext2->bfAzPtWidth       = params->bfAzPtWidth;
+    ext2->bfaCompResv0      = 0;
+    ext2->bfaCompResv1      = 0;
+
+    val = 0;
+    shift_val = 0;
+    if(params->bfAzPtWidth) {
+        val += params->bfAzPt;
+        shift_val += 8 - (params->bfAzPtWidth+1);
+        }
+    else
+        shift_val += 8;
+
+    if(params->bfZePtWidth) {
+        val = val << (params->bfZePtWidth+1);
+        val += params->bfZePt;
+        shift_val += 8 - (params->bfZePtWidth+1);
+        }
+    else
+        shift_val += 8;
+
+    if(params->bfAz3ddWidth) {
+        val = val << (params->bfAz3ddWidth+1);
+        val += params->bfAz3dd;
+        shift_val += 8 - (params->bfAz3ddWidth+1);
+        }
+    else
+        shift_val += 8;
+
+    if(params->bfZe3ddWidth) {
+        val = val << (params->bfZe3ddWidth+1);
+        val += params->bfZe3dd;
+        shift_val += 8 - (params->bfZe3ddWidth+1);
+        }
+    else
+        shift_val += 8;
+
+    if(val) {
+        val = val << shift_val;
+        val = rte_cpu_to_be_32(val);
+        }
+
+    val_size = 4 - (shift_val/8);   /* ceil(total bit/8) */
+    parm_size = val_size + 1;       /* additional 1 byte for bfxxSI */
+
+    data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+    if(data == NULL) {
+        print_err("Fail to allocate the space for section extension 2");
+        return (XRAN_STATUS_RESOURCE);
+        }
+    total_len += parm_size;
+
+    rte_memcpy(data, &val, val_size);
+    data += val_size;
+    *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
+
+    ext2->extLen            = total_len / XRAN_SECTIONEXT_ALIGN;
+    *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
+
+    return (total_len);
+}
+
+static int xran_prepare_sectionext_4(struct rte_mbuf *mbuf,
+                struct xran_sectionext4_info *params, int last_flag)
+{
+  struct xran_cp_radioapp_section_ext4 *ext4;
+  int parm_size;
+  int total_len;
+  int ret;
+
+
+    total_len = 0;
+
+    parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
+    ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
+    if(ext4 == NULL) {
+        print_err("Fail to allocate the space for section extension 4");
+        return(XRAN_STATUS_RESOURCE);
+        }
+    else {
+        total_len += parm_size;
+
+        ext4->extType       = XRAN_CP_SECTIONEXTCMD_4;
+        ext4->ef            = last_flag;
+        ext4->modCompScaler = params->modCompScaler;
+        ext4->csf           = params->csf?1:0;
+        ext4->extLen        = 1;
+
+        *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
+        }
+
+    return (total_len);
+}
+
+static int xran_prepare_sectionext_5(struct rte_mbuf *mbuf,
+                struct xran_sectionext5_info *params, int last_flag)
+{
+  struct xran_cp_radioapp_section_ext5_1 *ext5_1;
+  struct xran_cp_radioapp_section_ext5_2 *ext5_2;
+  int parm_size;
+  int total_len;
+  uint32_t *data;
+
+
+    total_len = 0;
+
+    if(params->num_sets == 1) {
+        parm_size = sizeof(struct xran_cp_radioapp_section_ext5_1);
+        ext5_1 = (struct xran_cp_radioapp_section_ext5_1 *)rte_pktmbuf_append(mbuf, parm_size);
+        if(ext5_1 == NULL) {
+            print_err("Fail to allocate the space for section extension 5-1");
+            return (XRAN_STATUS_RESOURCE);
+            }
+        else {
+            total_len += parm_size;
+
+            ext5_1->extType         = XRAN_CP_SECTIONEXTCMD_5;
+            ext5_1->ef              = last_flag;
+
+            ext5_1->mcScaleOffset   = params->mc[0].mcScaleOffset;
+            ext5_1->csf             = params->mc[0].csf;
+            ext5_1->mcScaleReMask   = params->mc[0].mcScaleReMask;
+            ext5_1->reserved        = 0;
+
+            ext5_1->extLen          = 2;
+
+            *(uint64_t *)ext5_1 = rte_cpu_to_be_64(*(uint64_t *)ext5_1);
+            }
+        }
+    else if(params->num_sets == 2) {
+        parm_size = sizeof(struct xran_cp_radioapp_section_ext5_2);
+        ext5_2 = (struct xran_cp_radioapp_section_ext5_2 *)rte_pktmbuf_append(mbuf, parm_size);
+        if(ext5_2 == NULL) {
+            print_err("Fail to allocate the space for section extension 5-2");
+            return (XRAN_STATUS_RESOURCE);
+            }
+        else {
+            total_len += parm_size;
+
+            ext5_2->extType         = XRAN_CP_SECTIONEXTCMD_5;
+            ext5_2->ef              = last_flag;
+
+            ext5_2->mcScaleOffset1  = params->mc[0].mcScaleOffset;
+            ext5_2->csf1            = params->mc[0].csf;
+            ext5_2->mcScaleReMask1  = params->mc[0].mcScaleReMask;
+            ext5_2->mcScaleOffset2  = params->mc[1].mcScaleOffset;
+            ext5_2->csf2            = params->mc[1].csf;
+            ext5_2->mcScaleReMask2  = params->mc[1].mcScaleReMask;
+
+            ext5_2->reserved0       = 0;
+            ext5_2->reserved1       = 0;
+
+            ext5_2->extLen          = 3;
+
+            *(uint64_t *)ext5_2 = rte_cpu_to_be_64(*(uint64_t *)ext5_2);
+            data = (uint32_t *)((uint8_t *)ext5_2 + 8);
+            *data = rte_cpu_to_be_32(*data);
+            }
+        }
+    else {
+        print_err("Invalid number of scalar values - %d", params->num_sets);
+        return (XRAN_STATUS_INVALID_PARAM);
+        }
+
+    return (total_len);
+}
+
+/**
+ * @brief add section extension to C-Plane packet
+ *
+ * @param mbuf
+ *  A pointer to the packet buffer
+ * @param params
+ *  A porinter to the information to generate a C-Plane packet
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM
+ *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
+{
+  int i, ret;
+  uint32_t totalen;
+  int last_flag;
+  int ext_size;
+
+
+    if(unlikely(params->exDataSize >= XRAN_MAX_NUM_EXTENSIONS)) {
+        print_err("Invalid total number of extensions - %d", params->exDataSize);
+        return (XRAN_STATUS_INVALID_PARAM);
+        }
+
+    totalen = 0;
+
+
+    ret = XRAN_STATUS_SUCCESS;
+
+    for(i=0; i < params->exDataSize; i++) {
+        if(params->exData[i].data == NULL) {
+            print_err("Invalid parameter - extension data %d is NULL", i);
+            ret = XRAN_STATUS_INVALID_PARAM;
+            continue;
+            }
+
+//    params->exData[].len
+        last_flag = ((params->exDataSize - i)==1)?0:1;
+        switch(params->exData[i].type) {
+            case XRAN_CP_SECTIONEXTCMD_1:
+                ext_size = xran_prepare_sectionext_1(mbuf, params->exData[i].data, last_flag);
+                break;
+            case XRAN_CP_SECTIONEXTCMD_2:
+                ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
+                break;
+            case XRAN_CP_SECTIONEXTCMD_4:
+                ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
+                break;
+            case XRAN_CP_SECTIONEXTCMD_5:
+                ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
+                break;
+
+            case XRAN_CP_SECTIONEXTCMD_0:
+            case XRAN_CP_SECTIONEXTCMD_3:
+            default:
+                print_err("Extension Type %d is not supported!", params->exData[i].type);
+                ret = XRAN_STATUS_INVALID_PARAM;
+                ext_size = 0;
+            }
+
+        if(ext_size == XRAN_STATUS_RESOURCE) {
+            break;
+            }
+
+        totalen += ext_size;
+        }
+
+    return (totalen);
 }
 
 
@@ -387,7 +786,8 @@ inline int32_t xran_get_freqoffset(int freqOffset, int scs)
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
  */
 static int xran_prepare_section0(
                 struct xran_cp_radioapp_section0 *section,
@@ -396,15 +796,15 @@ static int xran_prepare_section0(
 #if (XRAN_STRICT_PARM_CHECK)
     if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
         print_err("Invalid number of Symbols - %d", params->info.numSymbol);
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 #endif
 
-    section->hdr.sectionId  = params->info.id;
-    section->hdr.rb         = params->info.rb;
-    section->hdr.symInc     = params->info.symInc;
-    section->hdr.startPrbc  = params->info.startPrbc;
-    section->hdr.numPrbc    = params->info.numPrbc;
+    section->hdr.sectionId      = params->info.id;
+    section->hdr.rb             = params->info.rb;
+    section->hdr.symInc         = params->info.symInc;
+    section->hdr.startPrbc      = params->info.startPrbc;
+    section->hdr.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
 
     section->hdr.u.s0.reMask    = params->info.reMask;
     section->hdr.u.s0.numSymbol = params->info.numSymbol;
@@ -413,7 +813,7 @@ static int xran_prepare_section0(
     // for network byte order
     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 /**
  * @brief Fill the section header of type 0 in C-Plane packet
@@ -423,7 +823,7 @@ static int xran_prepare_section0(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS always
  */
 static int xran_prepare_section0_hdr(
                 struct xran_cp_radioapp_section0_header *s0hdr,
@@ -436,7 +836,7 @@ static int xran_prepare_section0_hdr(
     s0hdr->cpLength                 = rte_cpu_to_be_16(params->hdr.cpLength);
     s0hdr->reserved                 = 0;
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 /**
@@ -448,7 +848,8 @@ static int xran_prepare_section0_hdr(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
  */
 static int xran_prepare_section1(
                 struct xran_cp_radioapp_section1 *section,
@@ -457,7 +858,7 @@ static int xran_prepare_section1(
 #if (XRAN_STRICT_PARM_CHECK)
     if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
         print_err("Invalid number of Symbols - %d", params->info.numSymbol);
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 #endif
 
@@ -465,25 +866,18 @@ static int xran_prepare_section1(
     section->hdr.rb             = params->info.rb;
     section->hdr.symInc         = params->info.symInc;
     section->hdr.startPrbc      = params->info.startPrbc;
-    section->hdr.numPrbc        = params->info.numPrbc;
+    section->hdr.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
 
     section->hdr.u.s1.reMask    = params->info.reMask;
     section->hdr.u.s1.numSymbol = params->info.numSymbol;
     section->hdr.u.s1.beamId    = params->info.beamId;
 
-    if(params->info.ef) {
-        // TODO: need to handle extension
-        print_err("Extension is not supported!");
-        section->hdr.u.s1.ef         = 0;
-//        section->hdr.u.s1.ef         = params->info.ef;
-        }
-    else
-        section->hdr.u.s1.ef         = 0;
+    section->hdr.u.s1.ef        = params->info.ef;
 
     // for network byte order
     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 /**
  * @brief Fill the section header of type 1 in C-Plane packet
@@ -493,7 +887,7 @@ static int xran_prepare_section1(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS always
  */
 static int xran_prepare_section1_hdr(
                 struct xran_cp_radioapp_section1_header *s1hdr,
@@ -503,7 +897,7 @@ static int xran_prepare_section1_hdr(
     s1hdr->udComp.udCompMeth        = params->hdr.compMeth;
     s1hdr->reserved                 = 0;
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 /**
@@ -515,7 +909,8 @@ static int xran_prepare_section1_hdr(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
  */
 static int xran_prepare_section3(
                 struct xran_cp_radioapp_section3 *section,
@@ -524,7 +919,7 @@ static int xran_prepare_section3(
 #if (XRAN_STRICT_PARM_CHECK)
     if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
         print_err("Invalid number of Symbols - %d", params->info.numSymbol);
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 #endif
 
@@ -532,7 +927,7 @@ static int xran_prepare_section3(
     section->hdr.rb             = params->info.rb;
     section->hdr.symInc         = params->info.symInc;
     section->hdr.startPrbc      = params->info.startPrbc;
-    section->hdr.numPrbc        = params->info.numPrbc;
+    section->hdr.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
 
     section->hdr.u.s3.reMask    = params->info.reMask;
     section->hdr.u.s3.numSymbol = params->info.numSymbol;
@@ -541,19 +936,12 @@ static int xran_prepare_section3(
     section->freqOffset         = rte_cpu_to_be_32(params->info.freqOffset)>>8;
     section->reserved           = 0;
 
-    if(params->info.ef) {
-        // TODO: need to handle extension
-        print_err("Extension is not supported!");
-        section->hdr.u.s3.ef         = 0;
-//        section->hdr.u.s3.ef         = params->info.ef;
-        }
-    else
-        section->hdr.u.s3.ef         = 0;
+    section->hdr.u.s3.ef        = params->info.ef;
 
     // for network byte order (header, 8 bytes)
     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 /**
  * @brief Fill the section header of type 3 in C-Plane packet
@@ -563,7 +951,7 @@ static int xran_prepare_section3(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS always
  */
 static int xran_prepare_section3_hdr(
                 struct xran_cp_radioapp_section3_header *s3hdr,
@@ -577,7 +965,7 @@ static int xran_prepare_section3_hdr(
     s3hdr->udComp.udIqWidth         = params->hdr.iqWidth;
     s3hdr->udComp.udCompMeth        = params->hdr.compMeth;
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 /**
@@ -589,11 +977,13 @@ static int xran_prepare_section3_hdr(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
+ *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
  */
 int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
 {
-  int i, ret;
+  int i, ret, ext_flag;
   uint32_t totalen;
   void *section;
   int section_size;
@@ -624,27 +1014,33 @@ int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params
             section_size                = 0;
             xran_prepare_section_func   = NULL;
             print_err("Section Type %d is not supported!", params->sectionType);
-            return (-XRAN_ERRCODE_INVALIDPARAM);
+            return (XRAN_STATUS_INVALID_PARAM);
         }
 
     if(unlikely(xran_prepare_section_func == NULL)) {
        print_err("Section Type %d is not supported!", params->sectionType);
-       return (-XRAN_ERRCODE_INVALIDPARAM);
+       return (XRAN_STATUS_INVALID_PARAM);
        }
 
     for(i=0; i<params->numSections; i++) {
         section = rte_pktmbuf_append(mbuf, section_size);
         if(section == NULL) {
             print_err("Fail to allocate the space for section[%d]!", i);
-            return (-XRAN_ERRCODE_OUTOFMEMORY);
-            }
-
-        if(unlikely(xran_prepare_section_func((void *)section,
-                            (void *)&params->sections[i]) < 0)) {
-            return (-XRAN_ERRCODE_INVALIDPARAM);
+            return (XRAN_STATUS_RESOURCE);
             }
 
+        ret = xran_prepare_section_func((void *)section,
+                            (void *)&params->sections[i]);
+        if(ret < 0)
+            return (ret);
         totalen += section_size;
+
+        if(params->sections[i].info.ef) {
+            ret = xran_append_section_extensions(mbuf, &params->sections[i]);
+            if(ret < 0)
+                return (ret);
+            totalen += ret;
+            }
         }
 
     return (totalen);
@@ -658,7 +1054,8 @@ int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
  */
 static inline int xran_prepare_radioapp_common_header(
                 struct xran_cp_radioapp_common_header *apphdr,
@@ -668,15 +1065,15 @@ static inline int xran_prepare_radioapp_common_header(
 #if (XRAN_STRICT_PARM_CHECK)
     if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
         print_err("Invalid direction!");
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
     if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
         print_err("Invalid Slot ID!");
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
     if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
         print_err("Invalid Symbol ID!");
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 #endif
 
@@ -690,10 +1087,10 @@ static inline int xran_prepare_radioapp_common_header(
     apphdr->numOfSections   = params->numSections;
     apphdr->sectionType     = params->sectionType;
 
-    // radio app header has common parts of 4bytes for all section types
+    /* radio app header has common parts of 4bytes for all section types */
     *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 /**
@@ -704,7 +1101,9 @@ static inline int xran_prepare_radioapp_common_header(
  * @param params
  *  A porinter to the information to generate a C-Plane packet
  * @return
- *  0 on success; non zero on failure
+ *  The length of added section (>0) on success
+ *  XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
+ *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
  */
 int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
 {
@@ -717,40 +1116,40 @@ int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params
 #if (XRAN_STRICT_PARM_CHECK)
     if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
         print_err("Invalid Section Type - %d", params->sectionType);
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 #endif
 
     switch(params->sectionType) {
-        case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
+        case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
             xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section0_hdr;
             totalen = sizeof(struct xran_cp_radioapp_section0_header);
             break;
 
-        case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
+        case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
             xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section1_hdr;
             totalen = sizeof(struct xran_cp_radioapp_section1_header);
             break;
 
-        case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
+        case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
             xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section3_hdr;
             totalen = sizeof(struct xran_cp_radioapp_section3_header);
             break;
 
-        case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
-        case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
-        case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
+        case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
+        case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
+        case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
         default:
             print_err("Section Type %d is not supported!", params->sectionType);
             xran_prepare_radioapp_section_hdr_func = NULL;
             totalen = 0;
-            return (-XRAN_ERRCODE_INVALIDPARAM);
+            return (XRAN_STATUS_INVALID_PARAM);
         }
 
     apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
     if(unlikely(apphdr == NULL)) {
         print_err("Fail to reserve the space for radio application header!");
-        return (-XRAN_ERRCODE_OUTOFMEMORY);
+        return (XRAN_STATUS_RESOURCE);
         }
 
     ret = xran_prepare_radioapp_common_header(apphdr, params);
@@ -759,11 +1158,11 @@ int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params
         }
 
     if(likely(xran_prepare_radioapp_section_hdr_func)) {
-        xran_prepare_radioapp_section_hdr_func(apphdr, params);
+        totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
         }
     else {
         print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
-        return (-XRAN_ERRCODE_INVALIDPARAM);
+        return (XRAN_STATUS_INVALID_PARAM);
         }
 
     return (totalen);
@@ -786,7 +1185,9 @@ int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params
  * @param seq_id
  *  Sequence ID for this C-Plane message
  * @return
- *  0 on success; non zero on failure
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ *  XRAN_STATUS_INVALID_PARM if section type is invalid
  */
 int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
                         struct xran_cp_gen_params *params,
@@ -798,24 +1199,7 @@ int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
   struct xran_ecpri_hdr *ecpri_hdr;
 
 
-    ecpri_hdr = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
-    if(unlikely(ecpri_hdr == NULL)) {
-        print_err("Fail to allocate the space for eCPRI hedaer!");
-        return (-XRAN_ERRCODE_OUTOFMEMORY);
-        }
-
-    ecpri_hdr->ecpri_ver            = XRAN_ECPRI_VER;
-    ecpri_hdr->ecpri_resv           = 0;     // should be zero
-    ecpri_hdr->ecpri_concat         = 0;
-    ecpri_hdr->ecpri_mesg_type      = ECPRI_RT_CONTROL_DATA;
-    ecpri_hdr->ecpri_xtc_id         = xran_compose_cid(0, 0, CC_ID, Ant_ID);
-    ecpri_hdr->ecpri_seq_id.seq_id  = seq_id;
-
-    /* TODO: Transport layer fragmentation is not supported */
-    ecpri_hdr->ecpri_seq_id.sub_seq_id  = 0;
-    ecpri_hdr->ecpri_seq_id.e_bit       = 1;
-
-    payloadlen = 0;
+    payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
 
     ret = xran_append_radioapp_header(mbuf, params);
     if(ret < 0) {
@@ -829,15 +1213,34 @@ int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
         }
     payloadlen += ret;
 
-//    printf("Total Payload length = %d\n", payloadlen);
-    ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
+    /* set payload length */
+    ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
 
-    return (XRAN_ERRCODE_OK);
+    return (XRAN_STATUS_SUCCESS);
 }
 
+
 ///////////////////////////////////////
-// for Debug
-int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
+// for RU emulation
+/**
+ * @brief Parse a C-Plane packet (for RU emulation)
+ *  Transport layer fragmentation is not supported.
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param mbuf
+ *  The pointer of the packet buffer to be parsed
+ * @param params
+ *  The pointer of structure to store the information of parsed packet
+ * @param eaxc
+ *  The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PACKET if failed to parse the packet
+ */
+int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
+                    struct xran_cp_gen_params *result,
+                    struct xran_recv_packet_info *pkt_info)
 {
   struct xran_ecpri_hdr *ecpri_hdr;
   struct xran_cp_radioapp_common_header *apphdr;
@@ -845,48 +1248,22 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
   int extlen;
 
 
-    ret = 0;
-    ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
-    if(ecpri_hdr == NULL) {
-        print_err("Invalid packet - eCPRI hedaer!");
-        return (-XRAN_ERRCODE_INVALIDPACKET);
-        }
-
-    /* Process eCPRI header. */
-    if(ecpri_hdr->ecpri_ver != XRAN_ECPRI_VER) {
-        print_err("Invalid eCPRI version - %d", ecpri_hdr->ecpri_ver);
-        ret = -XRAN_ERRCODE_INVALIDPACKET;
-        }
-
-    if(ecpri_hdr->ecpri_resv != 0) {
-        print_err("Invalid reserved field - %d", ecpri_hdr->ecpri_resv);
-        ret = -XRAN_ERRCODE_INVALIDPACKET;
-        }
-
-    if(ecpri_hdr->ecpri_mesg_type != ECPRI_RT_CONTROL_DATA) {
-        print_err("Not C-Plane Message - %d", ecpri_hdr->ecpri_mesg_type);
-        ret = -XRAN_ERRCODE_INVALIDPACKET;
-        }
-#if 0
-    printf("[CPlane] [%04X:%03d-%3d-%d] len=%5d\n",
-            rte_be_to_cpu_16(ecpri_hdr->ecpri_xtc_id),
-            ecpri_hdr->ecpri_seq_id.seq_id, ecpri_hdr->ecpri_seq_id.sub_seq_id,
-            ecpri_hdr->ecpri_seq_id.e_bit,
-            rte_be_to_cpu_16(ecpri_hdr->ecpri_payl_size));
-#endif
+    ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
+    if(ret < 0 && ecpri_hdr == NULL)
+        return (XRAN_STATUS_INVALID_PACKET);
 
     /* Process radio header. */
     apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
     if(apphdr == NULL) {
         print_err("Invalid packet - radio app hedaer!");
-        return (-XRAN_ERRCODE_INVALIDPACKET);
+        return (XRAN_STATUS_INVALID_PACKET);
         }
 
     *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
 
     if(apphdr->payloadVer != XRAN_PAYLOAD_VER) {
         print_err("Invalid Payload version - %d", apphdr->payloadVer);
-        ret = -XRAN_ERRCODE_INVALIDPACKET;
+        ret = XRAN_STATUS_INVALID_PACKET;
         }
 
     result->dir             = apphdr->dataDirection;
@@ -898,6 +1275,19 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
     result->sectionType     = apphdr->sectionType;
     result->numSections     = apphdr->numOfSections;
 
+#if 0
+    printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
+        pkt_info->payload_len,
+        pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
+        pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
+        result->dir?"DL":"UL",
+        pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
+        result->sectionType, result->numSections,
+        result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
+        result->hdr.startSymId
+        );
+#endif
+
     switch(apphdr->sectionType) {
         case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
             {
@@ -911,11 +1301,11 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                 result->hdr.timeOffset  = hdr->frameStructure.uScs;
                 result->hdr.cpLength    = rte_be_to_cpu_16(hdr->cpLength);
                 //hdr->reserved;    /* should be zero */
-                
+
                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
                 if(section == NULL) {
                     print_err("Invalid packet 0 - radio app hedaer!");
-                    return (-XRAN_ERRCODE_INVALIDPACKET);
+                    return (XRAN_STATUS_INVALID_PACKET);
                     }
                 for(i=0; i<result->numSections; i++) {
                     *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
@@ -935,7 +1325,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                         print_err("Invalid packet 0 - number of section [%d:%d]!",
                                     result->numSections, i);
                         result->numSections = i;
-                        ret = (-XRAN_ERRCODE_INVALIDPACKET);
+                        ret = XRAN_STATUS_INVALID_PACKET;
                         break;
                         }
                     }
@@ -955,7 +1345,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
                 if(section == NULL) {
                     print_err("Invalid packet 1 - radio app hedaer!");
-                    return (-XRAN_ERRCODE_INVALIDPACKET);
+                    return (XRAN_STATUS_INVALID_PACKET);
                     }
 
                 for(i=0; i<result->numSections; i++) {
@@ -984,7 +1374,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                         print_err("Invalid packet 1 - number of section [%d:%d]!",
                                     result->numSections, i);
                         result->numSections = i;
-                        ret = (-XRAN_ERRCODE_INVALIDPACKET);
+                        ret = XRAN_STATUS_INVALID_PACKET;
                         break;
                         }
                     }
@@ -1008,7 +1398,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
                 if(section == NULL) {
                     print_err("Invalid packet 3 - radio app hedaer!");
-                    return (-XRAN_ERRCODE_INVALIDPACKET);
+                    return (XRAN_STATUS_INVALID_PACKET);
                     }
 
                 for(i=0; i<result->numSections; i++) {
@@ -1028,7 +1418,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
 
                     if(section->reserved) {
                         print_err("Invalid packet 3 - section[%d:%d]", i, section->reserved);
-                        ret = -XRAN_ERRCODE_INVALIDPACKET;
+                        ret = XRAN_STATUS_INVALID_PACKET;
                         }
 
                     if(section->hdr.u.s3.ef) {
@@ -1043,7 +1433,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
                         print_err("Invalid packet 3 - number of section [%d:%d]!",
                                     result->numSections, i);
                         result->numSections = i;
-                        ret = (-XRAN_ERRCODE_INVALIDPACKET);
+                        ret = XRAN_STATUS_INVALID_PACKET;
                         break;
                         }
                     }
@@ -1054,7 +1444,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
         case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
         case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
         default:
-            ret = -XRAN_ERRCODE_INVALIDPARAM;
+            ret = XRAN_STATUS_INVALID_PARAM;
             print_err("Non-supported Section Type - %d", apphdr->sectionType);
         }
 
@@ -1068,7 +1458,7 @@ int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
             result->hdr.iqWidth, result->hdr.compMeth);
 
     for(i=0; i<result->numSections; i++) {
-        printf("  >> %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02X numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
+        printf("  >> %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
             i, result->sections[i].info.id,
             result->sections[i].info.rb,
             result->sections[i].info.symInc, result->sections[i].info.numSymbol,
diff --git a/fhi_lib/lib/src/xran_frame_struct.c b/fhi_lib/lib/src/xran_frame_struct.c
new file mode 100644 (file)
index 0000000..9dd4781
--- /dev/null
@@ -0,0 +1,509 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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 layer common functionality for both lls-CU and RU as well as C-plane and
+ *    U-plane
+ * @file xran_common.c
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#include <assert.h>
+#include <err.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "xran_frame_struct.h"
+#include "xran_printf.h"
+
+enum nXranChBwOptions
+{
+    XRAN_BW_5_0_MHZ  = 5,  XRAN_BW_10_0_MHZ = 10, XRAN_BW_15_0_MHZ = 15, XRAN_BW_20_0_MHZ = 20, XRAN_BW_25_0_MHZ = 25,
+    XRAN_BW_30_0_MHZ = 30, XRAN_BW_40_0_MHZ = 40, XRAN_BW_50_0_MHZ = 50, XRAN_BW_60_0_MHZ = 60, XRAN_BW_70_0_MHZ = 70,
+    XRAN_BW_80_0_MHZ = 80, XRAN_BW_90_0_MHZ = 90, XRAN_BW_100_0_MHZ = 100, XRAN_BW_200_0_MHZ = 200, XRAN_BW_400_0_MHZ = 400
+};
+
+// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+static uint16_t nNumRbsPerSymF1[3][13] =
+{
+    //  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
+        {25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0},         // Numerology 0 (15KHz)
+        {11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273},         // Numerology 1 (30KHz)
+        {0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135}          // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+static uint16_t nNumRbsPerSymF2[2][4] =
+{
+    //  50Mhz  100MHz  200MHz   400MHz
+        {66,    132,    264,     0},        // Numerology 2 (60KHz)
+        {32,    66,     132,     264}       // Numerology 3 (120KHz)
+};
+
+// 38.211 - Table 4.2.1
+static uint16_t nSubCarrierSpacing[5] =
+{
+    15,     // mu = 0
+    30,     // mu = 1
+    60,     // mu = 2
+    120,    // mu = 3
+    240     // mu = 4
+};
+
+// TTI interval in us (slot duration)
+static uint16_t nTtiInterval[4] =
+{
+    1000,    // mu = 0
+    500,     // mu = 1
+    250,     // mu = 2
+    125,     // mu = 3
+};
+
+// F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
+static uint16_t nCpSizeF1[3][13][2] =
+{
+    //    5MHz      10MHz      15MHz       20 MHz      25 MHz     30 MHz      40 MHz       50MHz       60 MHz      70 MHz     80 MHz     90 MHz     100 MHz
+        {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288},     {0, 0},     {0, 0},     {0, 0},     {0, 0},     {0, 0}},        // Numerology 0 (15KHz)
+        {{22, 18}, {44, 36},   {66, 54},   {88, 72},   {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}},       // Numerology 1 (30KHz)
+        {  {0, 0}, {26, 18},   {39, 27},   {52, 36},   {52, 36},   {78, 54},  {104, 72},  {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}},       // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
+static int16_t nCpSizeF2[2][4][2] =
+{
+    //    50Mhz    100MHz      200MHz     400MHz
+        {  {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
+        {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
+};
+
+static uint32_t xran_fs_max_slot_num = 8000;
+static uint16_t xran_fs_num_slot_tdd_loop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
+static uint16_t xran_fs_num_dl_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint16_t xran_fs_num_ul_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint8_t xran_fs_slot_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
+static uint8_t xran_fs_slot_symb_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP][XRAN_NUM_OF_SYMBOL_PER_SLOT] = {{{XRAN_SLOT_TYPE_INVALID}}};
+static float xran_fs_ul_rate[XRAN_MAX_SECTOR_NR] = {0.0};
+static float xran_fs_dl_rate[XRAN_MAX_SECTOR_NR] = {0.0};
+
+uint32_t xran_fs_get_tti_interval(uint8_t nMu)
+{
+    if (nMu < 4)
+    {
+        return nTtiInterval[nMu];
+    }
+    else
+    {
+        printf("ERROR: %s Mu[%d] is not valid, setting to 0\n",__FUNCTION__, nMu);
+        return nTtiInterval[0];
+    }
+}
+
+uint32_t xran_fs_get_scs(uint8_t nMu)
+{
+    if (nMu <= 3)
+    {
+        return nSubCarrierSpacing[nMu];
+    }
+    else
+    {
+        printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+    }
+
+    return 0;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ *  @param[in]   nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz,  1: 30khz,  2: 60khz 3: 120khz, 4: 240khz
+ *  @param[in]   nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ *  @param[in]   nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ *  @return  Number of RBs in cell
+ *
+ *  @description
+ *  Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
+{
+    uint32_t error = 1;
+    uint16_t numRBs = 0;
+
+    if (nAbsFrePointA <= 6000000)
+    {
+        // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+        if (nNumerology < 3)
+        {
+            switch(nBandwidth)
+            {
+                case XRAN_BW_5_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][0];
+                    error = 0;
+                break;
+                case XRAN_BW_10_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][1];
+                    error = 0;
+                break;
+                case XRAN_BW_15_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][2];
+                    error = 0;
+                break;
+                case XRAN_BW_20_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][3];
+                    error = 0;
+                break;
+                case XRAN_BW_25_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][4];
+                    error = 0;
+                break;
+                case XRAN_BW_30_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][5];
+                    error = 0;
+                break;
+                case XRAN_BW_40_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][6];
+                    error = 0;
+                break;
+                case XRAN_BW_50_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][7];
+                    error = 0;
+                break;
+                case XRAN_BW_60_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][8];
+                    error = 0;
+                break;
+                case XRAN_BW_70_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][9];
+                    error = 0;
+                break;
+                case XRAN_BW_80_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][10];
+                    error = 0;
+                break;
+                case XRAN_BW_90_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][11];
+                    error = 0;
+                break;
+                case XRAN_BW_100_0_MHZ:
+                    numRBs = nNumRbsPerSymF1[nNumerology][12];
+                    error = 0;
+                break;
+                default:
+                    error = 1;
+                break;
+            }
+        }
+    }
+    else
+    {
+        if ((nNumerology >= 2) && (nNumerology <= 3))
+        {
+            // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+            switch(nBandwidth)
+            {
+                case XRAN_BW_50_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][0];
+                    error = 0;
+                break;
+                case XRAN_BW_100_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][1];
+                    error = 0;
+                break;
+                case XRAN_BW_200_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][2];
+                    error = 0;
+                break;
+                case XRAN_BW_400_0_MHZ:
+                    numRBs = nNumRbsPerSymF2[nNumerology-2][3];
+                    error = 0;
+                break;
+                default:
+                    error = 1;
+                break;
+            }
+        }
+    }
+
+
+    if (error)
+    {
+        printf("ERROR: %s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA);
+    }
+    else
+    {
+        printf("%s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA, numRBs);
+    }
+
+    return numRBs;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ *  @param[in]   center frequency
+ *
+ *  @return  NR-ARFCN
+ *
+ *  @description
+ *  This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq)
+{
+    uint32_t nDeltaFglobal,nFoffs,nNoffs;
+    uint32_t nNRARFCN = 0;
+
+    if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
+    {
+        nDeltaFglobal = 5;
+        nFoffs = 0;
+        nNoffs = 0;
+    }
+    else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
+    {
+        nDeltaFglobal = 15;
+        nFoffs = 3000*1000;
+        nNoffs = 600000;
+    }
+    else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
+    {
+        nDeltaFglobal = 60;
+        nFoffs = 24250080;
+        nNoffs = 2016667;
+    }
+    else
+    {
+         printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
+         return (0);
+    }
+
+    nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
+
+    printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
+    return (nNRARFCN);
+}
+
+uint32_t  xran_fs_slot_limit_init(int32_t tti_interval_us)
+{
+    xran_fs_max_slot_num = (1000/tti_interval_us)*1000;
+    return xran_fs_max_slot_num;
+}
+
+uint32_t xran_fs_get_max_slot(void)
+{
+    return xran_fs_max_slot_num;
+}
+
+int32_t xran_fs_slot_limit(int32_t nSfIdx)
+{
+    while (nSfIdx < 0) {
+        nSfIdx += xran_fs_max_slot_num;
+    }
+
+    while (nSfIdx >= xran_fs_max_slot_num) {
+        nSfIdx -= xran_fs_max_slot_num;
+    }
+
+    return nSfIdx;
+}
+
+void xran_fs_clear_slot_type(uint32_t nPhyInstanceId)
+{
+    xran_fs_ul_rate[nPhyInstanceId] = 0.0;
+    xran_fs_dl_rate[nPhyInstanceId] = 0.0;
+    xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
+}
+
+int32_t xran_fs_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig)
+{
+    uint32_t nSlotNum, nSymNum, nVal, i, j;
+    uint32_t numDlSym, numUlSym, numGuardSym;
+    uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
+    char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
+
+    // nPhyInstanceId    Carrier ID
+    // nFrameDuplexType  0 = FDD 1 = TDD
+    // nTddPeriod        Tdd Periodicity
+    // psSlotConfig[80]  Slot Config Structure for nTddPeriod Slots
+
+    xran_fs_ul_rate[nPhyInstanceId] = 0.0;
+    xran_fs_dl_rate[nPhyInstanceId] = 0.0;
+    xran_fs_num_slot_tdd_loop[nPhyInstanceId] = nTddPeriod;
+
+    for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+    {
+        xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
+        xran_fs_num_dl_sym_sp[nPhyInstanceId][i] = 0;
+        xran_fs_num_ul_sym_sp[nPhyInstanceId][i] = 0;
+    }
+
+    if (nFrameDuplexType == XRAN_FDD)
+    {
+        for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+        {
+            xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
+            for(j = 0; j < XRAN_NUM_OF_SYMBOL_PER_SLOT; j++)
+              xran_fs_slot_symb_type[nPhyInstanceId][i][j] = XRAN_SYMBOL_TYPE_FDD;
+        }
+        xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
+        xran_fs_dl_rate[nPhyInstanceId] = 1.0;
+        xran_fs_ul_rate[nPhyInstanceId] = 1.0;
+    }
+    else
+    {
+        for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
+        {
+            numDlSym = 0;
+            numUlSym = 0;
+            numGuardSym = 0;
+            for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
+            {
+                switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
+                {
+                    case XRAN_SYMBOL_TYPE_DL:
+                        numDlSym++;
+                        xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_DL;
+                    break;
+                    case XRAN_SYMBOL_TYPE_GUARD:
+                        xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_GUARD;
+                        numGuardSym++;
+                    break;
+                    default:
+                        xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_UL;
+                        numUlSym++;
+                    break;
+                }
+            }
+
+            print_dbg("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d] ", nSlotNum, numDlSym, numGuardSym, numUlSym);
+
+            if ((numUlSym == 0) && (numGuardSym == 0))
+            {
+                xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
+                numDlSlots++;
+                print_dbg("XRAN_SLOT_TYPE_DL\n");
+            }
+            else if ((numDlSym == 0) && (numGuardSym == 0))
+            {
+                xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
+                numUlSlots++;
+                print_dbg("XRAN_SLOT_TYPE_UL\n");
+            }
+            else
+            {
+                xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
+                numSpSlots++;
+                print_dbg("XRAN_SLOT_TYPE_SP\n");
+
+                if (numDlSym)
+                {
+                    numSpDlSlots++;
+                    xran_fs_num_dl_sym_sp[nPhyInstanceId][nSlotNum] = numDlSym;
+                }
+                if (numUlSym)
+                {
+                    numSpUlSlots++;
+                    xran_fs_num_ul_sym_sp[nPhyInstanceId][nSlotNum] = numUlSym;
+                }
+            }
+            print_dbg("            numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
+        }
+
+        xran_fs_dl_rate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
+        xran_fs_ul_rate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
+    }
+
+    print_dbg("%s: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
+        __FUNCTION__, nPhyInstanceId, nFrameDuplexType, nTddPeriod);
+
+    print_dbg("DLRate[%f] ULRate[%f]\n", xran_fs_dl_rate[nPhyInstanceId], xran_fs_ul_rate[nPhyInstanceId]);
+
+    nVal = (xran_fs_num_slot_tdd_loop[nPhyInstanceId] < 10) ? xran_fs_num_slot_tdd_loop[nPhyInstanceId] : 10;
+
+    print_dbg("SlotPattern:\n");
+    print_dbg("Slot:   ");
+    for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
+    {
+        print_dbg("%d    ", nSlotNum);
+    }
+    print_dbg("\n");
+
+    print_dbg("  %3d   ", 0);
+    for (nSlotNum = 0, i = 0; nSlotNum < xran_fs_num_slot_tdd_loop[nPhyInstanceId]; nSlotNum++)
+    {
+        print_dbg("%s   ", sSlotPattern[xran_fs_slot_type[nPhyInstanceId][nSlotNum]]);
+        i++;
+        if ((i == 10) && ((nSlotNum+1) < xran_fs_num_slot_tdd_loop[nPhyInstanceId]))
+        {
+            print_dbg("\n");
+            print_dbg("  %3d   ", nSlotNum);
+            i = 0;
+        }
+    }
+    print_dbg("\n\n");
+
+    return 0;
+}
+
+int32_t xran_fs_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
+{
+    int32_t nSfIdxMod, nSfType, ret = 0;
+
+    nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
+    nSfType = xran_fs_slot_type[nCellIdx][nSfIdxMod];
+
+    if (nSfType == nType)
+    {
+        ret = 1;
+    }
+    else if (nSfType == XRAN_SLOT_TYPE_SP)
+    {
+        if ((nType == XRAN_SLOT_TYPE_DL) && xran_fs_num_dl_sym_sp[nCellIdx][nSfIdxMod])
+        {
+            ret = 1;
+        }
+
+        if ((nType == XRAN_SLOT_TYPE_UL) && xran_fs_num_ul_sym_sp[nCellIdx][nSfIdxMod])
+        {
+            ret = 1;
+        }
+    }
+    else if (nSfType == XRAN_SLOT_TYPE_FDD)
+    {
+        ret = 1;
+    }
+
+    return ret;
+}
+
+int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx,  int32_t nSymbIdx)
+{
+    int32_t nSfIdxMod, nSfType, ret = 0;
+
+    nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
+
+    return xran_fs_slot_symb_type[nCellIdx][nSfIdxMod][nSymbIdx];
+}
+
+
diff --git a/fhi_lib/lib/src/xran_frame_struct.h b/fhi_lib/lib/src/xran_frame_struct.h
new file mode 100644 (file)
index 0000000..c8794b6
--- /dev/null
@@ -0,0 +1,83 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 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 Header file for function to work with 5G NR frame structure and related
+ *        routines
+ * @file xran_frame_struct.h
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#ifndef _XRAN_FRAME_STRUCT_
+#define _XRAN_FRAME_STRUCT_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "xran_fh_o_du.h"
+
+uint32_t xran_fs_get_tti_interval(uint8_t nMu);
+uint32_t xran_fs_get_scs(uint8_t nMu);
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ *  @param[in]   nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz,  1: 30khz,  2: 60khz 3: 120khz, 4: 240khz
+ *  @param[in]   nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ *  @param[in]   nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ *  @return  Number of RBs in cell
+ *
+ *  @description
+ *  Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ *  @param[in]   center frequency
+ *
+ *  @return  NR-ARFCN
+ *
+ *  @description
+ *  This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq);
+int32_t xran_fs_slot_limit(int32_t nSlotIdx);
+void xran_fs_clear_slot_type(uint32_t nCcId);
+int32_t xran_fs_set_slot_type(uint32_t nCcId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig);
+int32_t xran_fs_get_slot_type(int32_t nCcId, int32_t nSlotIdx, int32_t nType);
+uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us);
+uint32_t xran_fs_get_max_slot(void);
+int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx,  int32_t nSymbIdx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XRAN_FRAME_STRUCT_ */
+
diff --git a/fhi_lib/lib/src/xran_hash.h b/fhi_lib/lib/src/xran_hash.h
deleted file mode 100644 (file)
index b06c694..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/******************************************************************************
-*
-*   Copyright (c) 2019 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 Definitions and support functions to process XRAN packet
- * @file xran_hash.h
- * @ingroup group_source_xran
- * @author Intel Corporation
- **/
-
-#ifndef _XRAN_HASH_H
-#define _XRAN_HASH_H
-
-#include <rte_common.h>
-#include <rte_hash.h>
-#include <rte_hash_crc.h>
-
-#define DEFAULT_HASH_FUNC       rte_hash_crc
-
-
-struct rte_hash *xran_section_init_hash(uint16_t dir, uint16_t cid, int max_num_sections);
-void xran_section_free_hash(struct rte_hash *hash);
-
-void xran_section_reset_hash(struct rte_hash *hash);
-int xran_section_add_hash(const struct rte_hash *hash, uint16_t section_id, int index);
-int xran_section_lookup(const struct rte_hash *hash, uint16_t section_id);
-int xran_section_iterate(const struct rte_hash *hash, uint32_t *next);
-
-#endif
index 2c99c19..46f264b 100644 (file)
 #ifndef _XRAN_TASK_ID_H_
 #define _XRAN_TASK_ID_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define RESOURCE_CORE_0                             0
 #define RESOURCE_CORE_1                             1
 #define RESOURCE_CORE_2                             2
 #define PID_PROCESS_CP_PKT                      2700
 
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _XRAN_TASK_ID_H_ */
 
index 94751f6..256457d 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief XRAN main functionality module
  * @file xran_main.c
@@ -34,6 +33,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <pthread.h>
+#include <malloc.h>
 
 #include <rte_eal.h>
 #include <rte_errno.h>
 #include <rte_cycles.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
+#include <rte_mbuf.h>
 #include <rte_ring.h>
 
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
 
 #include "ethdi.h"
 #include "xran_pkt.h"
 #include "xran_lib_mlog_tasks_id.h"
 #include "xran_timer.h"
 #include "xran_common.h"
+#include "xran_frame_struct.h"
 #include "xran_printf.h"
+#include "xran_app_frag.h"
 
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_mlog_lnx.h"
 
 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
 
                                     (((int32_t)otaSym - (int32_t)offSym) - numSymTotal) : \
                                     ((int32_t)otaSym - (int32_t)offSym))
 
-#define MAX_NUM_OF_XRAN_CTX       (2)
+#define MAX_NUM_OF_XRAN_CTX          (2)
 #define XranIncrementCtx(ctx)                             ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
 #define XranDecrementCtx(ctx)                             ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
 
+#define MAX_NUM_OF_DPDK_TIMERS       (10)
+#define DpdkTiemerIncrementCtx(ctx)          ((ctx >= (MAX_NUM_OF_DPDK_TIMERS-1)) ? 0 : (ctx+1))
+#define DpdkTiemerDecrementCtx(ctx)          ((ctx == 0) ? (MAX_NUM_OF_DPDK_TIMERS-1) : (ctx-1))
+
+
+//#define XRAN_CREATE_RBMAP /**< generate slot map base on symbols */
+
+
 struct xran_timer_ctx {
     uint32_t    tti_to_process;
 };
 
-static XranLibHandleInfoStruct DevHandle;
-static struct xran_lib_ctx g_xran_lib_ctx = { 0 };
+static xran_cc_handle_t pLibInstanceHandles[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR] = {NULL};
+static struct xran_device_ctx g_xran_dev_ctx[XRAN_PORTS_NUM] = { 0 };
 
 struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX];
 
 static struct rte_timer tti_to_phy_timer[10];
-static struct rte_timer tti_timer;
 static struct rte_timer sym_timer;
-static struct rte_timer tx_cp_dl_timer;
-static struct rte_timer tx_cp_ul_timer;
-static struct rte_timer tx_up_timer;
+static struct rte_timer dpdk_timer[MAX_NUM_OF_DPDK_TIMERS];
 
-static long interval_us = 125;
+long interval_us = 1000;
 
-uint32_t xran_lib_ota_tti        = 0; /* [0:7999] */
-uint32_t xran_lib_ota_sym        = 0; /* [0:7] */
-uint32_t xran_lib_ota_sym_idx    = 0; /* [0 : 14*8*1000-1] */
+uint32_t xran_lib_ota_tti        = 0; /* [0:(1000000/TTI-1)] */
+uint32_t xran_lib_ota_sym        = 0; /* [0:1000/TTI-1] */
+uint32_t xran_lib_ota_sym_idx    = 0; /* [0 : 14*(1000000/TTI)-1]
+                                                where TTI is TTI interval in microseconds */
 
-uint64_t xran_lib_gps_second = 0;
+static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR * 2]; //XRAN_MAX_ANTENNA_NR * 2 for PUSCH and PRACH
+static uint8_t xran_updl_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
+static uint8_t xran_upul_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
 
-static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR];
-static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
-static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
+static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
+static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
 
 void xran_timer_arm(struct rte_timer *tim, void* arg);
+
 int xran_process_tx_sym(void *arg);
 
 int xran_process_rx_sym(void *arg,
+                        struct rte_mbuf *mbuf,
                         void *iq_data_start,
                         uint16_t size,
                         uint8_t CC_ID,
@@ -112,27 +120,91 @@ int xran_process_rx_sym(void *arg,
                         uint8_t frame_id,
                         uint8_t subframe_id,
                         uint8_t slot_id,
-                        uint8_t symb_id);
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id,
+                        uint32_t *mb_free);
+
+int xran_process_prach_sym(void *arg,
+                        struct rte_mbuf *mbuf,
+                        void *iq_data_start,
+                        uint16_t size,
+                        uint8_t CC_ID,
+                        uint8_t Ant_ID,
+                        uint8_t frame_id,
+                        uint8_t subframe_id,
+                        uint8_t slot_id,
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id);
 
 void tti_ota_cb(struct rte_timer *tim, void *arg);
 void tti_to_phy_cb(struct rte_timer *tim, void *arg);
 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore);
 
-struct xran_lib_ctx *xran_lib_get_ctx(void)
+struct xran_device_ctx *xran_dev_get_ctx(void)
 {
-    return &g_xran_lib_ctx;
+    return &g_xran_dev_ctx[0];
 }
 
-static inline XRANFHCONFIG *xran_lib_get_ctx_fhcfg(void)
+static inline struct xran_fh_config *xran_lib_get_ctx_fhcfg(void)
 {
-    return (&(xran_lib_get_ctx()->xran_fh_cfg));
+    return (&(xran_dev_get_ctx()->fh_cfg));
 }
 
-inline uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
+uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
 {
     return (0);     // NO BEAMFORMING
 }
 
+enum xran_if_state xran_get_if_state(void) 
+{
+    return xran_if_current_state;
+}
+
+int xran_isPRACHSlot(uint32_t subframe_id, uint32_t slot_id)
+{
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
+    int isPRACHslot = 0;
+
+    if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology < 2){
+        //for FR1, in 38.211 tab 6.3.3.2-2&3 it is subframe index
+        if (pPrachCPConfig->isPRACHslot[subframe_id] == 1){
+            if (pPrachCPConfig->nrofPrachInSlot != 1)
+                isPRACHslot = 1;
+            else{
+                if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 0)
+                    isPRACHslot = 1;
+                else if (slot_id == 1)
+                    isPRACHslot = 1;
+            }
+        }
+    }
+    else if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 3){
+        //for FR2, 38.211 tab 6.3.3.4 it is slot index of 60kHz slot
+        uint32_t slotidx;
+        slotidx = subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
+        if (pPrachCPConfig->nrofPrachInSlot == 2){
+            if (pPrachCPConfig->isPRACHslot[slotidx>>1] == 1)
+                isPRACHslot = 1;
+        }
+        else{
+            if ((pPrachCPConfig->isPRACHslot[slotidx>>1] == 1) && (slotidx % 2 == 1))
+                isPRACHslot = 1;
+        }
+    }
+    else
+        print_err("Numerology %d not supported", p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology);
+    return isPRACHslot;
+}
+
 int xran_init_sectionid(void *pHandle)
 {
   int cell, dir, ant;
@@ -147,19 +219,72 @@ int xran_init_sectionid(void *pHandle)
     return (0);
 }
 
-int xran_init_seqid(void *pHandle)
+int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx)
 {
-  int cell, dir, ant;
+    int32_t i;
+    uint8_t slotNr;
+    struct xran_prach_config* pPRACHConfig = &(pConf->prach_conf);
+    const xRANPrachConfigTableStruct *pxRANPrachConfigTable;
+    uint8_t nNumerology = pConf->frame_conf.nNumerology;
+    uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
+    xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
 
-    for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
-        for(dir=0; dir < XRAN_DIR_MAX; dir++) {
-            for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) {
-                xran_cp_seq_id_num[cell][dir][ant] = 0;
-                }
-            }
+    if (nNumerology > 2)
+        pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
+    else if (pConf->frame_conf.nFrameDuplexType == 1)
+        pxRANPrachConfigTable = &gxranPrachDataTable_sub6_tdd[nPrachConfIdx];
+    else
+        pxRANPrachConfigTable = &gxranPrachDataTable_sub6_fdd[nPrachConfIdx];
+
+    uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
+    const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt];
+    memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct));
+    if(pConf->log_level)
+        printf("xRAN open PRACH config: Numerology %u ConfIdx %u, preambleFmrt %u startsymb %u, numSymbol %u, occassionsInPrachSlot %u\n", nNumerology, nPrachConfIdx, preambleFmrt, pxRANPrachConfigTable->startingSym, pxRANPrachConfigTable->duration, pxRANPrachConfigTable->occassionsInPrachSlot);
+
+    pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC;         // 3, PRACH preamble format A1~3, B1~4, C0, C2
+    pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
+    pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
+    pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
+    pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
+    pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
+    pPrachCPConfig->x = pxRANPrachConfigTable->x;
+    pPrachCPConfig->nrofPrachInSlot = pxRANPrachConfigTable->nrofPrachInSlot;
+    pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
+    pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
+    if (preambleFmrt >= FORMAT_A1)
+    {
+        pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
+        pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
+    }
+    else
+    {
+        pPrachCPConfig->numSymbol = 1;
+        pPrachCPConfig->occassionsInPrachSlot = 1;
+    }
+
+    if(pConf->log_level)
+        printf("PRACH: x %u y[0] %u, y[1] %u prach slot: %u ..", pPrachCPConfig->x, pPrachCPConfig->y[0], pPrachCPConfig->y[1], pxRANPrachConfigTable->slotNr[0]);
+    pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
+    for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
+    {
+        slotNr = pxRANPrachConfigTable->slotNr[i];
+        if (slotNr > 0){
+            pPrachCPConfig->isPRACHslot[slotNr] = 1;
+            if(pConf->log_level)
+                printf(" %u ..", slotNr);
         }
+    }
+    printf("\n");
+    for (i = 0; i < XRAN_MAX_SECTOR_NR; i++){
+        p_xran_dev_ctx->prach_start_symbol[i] = pPrachCPConfig->startSymId;
+        p_xran_dev_ctx->prach_last_symbol[i] = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol * pPrachCPConfig->occassionsInPrachSlot - 1;
+    }
+    if(pConf->log_level){
+        printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]);
+    }
 
-    return (0);
+    return (XRAN_STATUS_SUCCESS);
 }
 
 inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
@@ -168,22 +293,40 @@ inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id,
         print_err("Invalid CC ID - %d", cc_id);
         return (0);
         }
-    if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {  //for PRACH, ant_id starts from num_ant
         print_err("Invalid antenna ID - %d", ant_id);
         return (0);
-        }
+    }
 
     /* if new slot has been started,
      * then initializes section id again for new start */
     if(xran_section_id_curslot[cc_id][ant_id] != slot_id) {
         xran_section_id[cc_id][ant_id] = 0;
         xran_section_id_curslot[cc_id][ant_id] = slot_id;
-        }
-  
+    }
+
     return(xran_section_id[cc_id][ant_id]++);
 }
 
-inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
+int xran_init_seqid(void *pHandle)
+{
+    int cell, dir, ant;
+
+    for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
+        for(dir=0; dir < XRAN_DIR_MAX; dir++) {
+            for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++)
+                xran_cp_seq_id_num[cell][dir][ant] = 0;
+            }
+        for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++)
+                xran_updl_seq_id_num[cell][ant] = 0;
+        for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++)
+                xran_upul_seq_id_num[cell][ant] = 0;
+        }
+
+    return (0);
+}
+
+static inline uint8_t xran_get_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id)
 {
     if(dir >= XRAN_DIR_MAX) {
         print_err("Invalid direction - %d", dir);
@@ -193,64 +336,185 @@ inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t
         print_err("Invalid CC ID - %d", cc_id);
         return (0);
         }
-    if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
         print_err("Invalid antenna ID - %d", ant_id);
         return (0);
         }
 
     return(xran_cp_seq_id_num[cc_id][dir][ant_id]++);
 }
+static inline uint8_t xran_get_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (0);
+        }
+    if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (0);
+        }
 
-inline int xran_update_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+    /* Only U-Plane DL needs to get sequence ID in O-DU */
+    return(xran_updl_seq_id_num[cc_id][ant_id]++);
+}
+static inline uint8_t *xran_get_updl_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
 {
-    return (0);
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (0);
+        }
+    if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (0);
+        }
+
+    /* Only U-Plane DL needs to get sequence ID in O-DU */
+    return(&xran_updl_seq_id_num[cc_id][ant_id]);
+}
+static inline int8_t xran_check_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+{
+
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (-1);
+    }
+
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (-1);
+    }
+
+    /* O-DU needs to check the sequence ID of U-Plane UL from O-RU */
+    xran_upul_seq_id_num[cc_id][ant_id]++;
+    if(xran_upul_seq_id_num[cc_id][ant_id] == seq_id) { /* expected sequence */
+        return (XRAN_STATUS_SUCCESS);
+    } else {
+        print_err("expected seqid %u received %u, slot %u, ant %u cc %u", xran_upul_seq_id_num[cc_id][ant_id], seq_id, slot_id, ant_id, cc_id);
+        xran_upul_seq_id_num[cc_id][ant_id] = seq_id; // for next
+        return (-1);
+    }
 }
 
 //////////////////////////////////////////
 // For RU emulation
-static struct xran_section_gen_info cpSections[255];
+static inline uint8_t xran_get_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (0);
+        }
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (0);
+        }
+
+    return(xran_upul_seq_id_num[cc_id][ant_id]++);
+}
+static inline uint8_t *xran_get_upul_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (0);
+        }
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (0);
+        }
+
+    return(&xran_upul_seq_id_num[cc_id][ant_id]);
+}
+static inline int8_t xran_check_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t seq_id)
+{
+    if(dir >= XRAN_DIR_MAX) {
+        print_err("Invalid direction - %d", dir);
+        return (-1);
+        }
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (-1);
+        }
+    if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (-1);
+        }
+
+    xran_cp_seq_id_num[cc_id][dir][ant_id]++;
+    if(xran_cp_seq_id_num[cc_id][dir][ant_id] == seq_id) { /* expected sequence */
+        return (0);
+        }
+    else {
+        xran_cp_seq_id_num[cc_id][dir][ant_id] = seq_id;
+        return (-1);
+        }
+}
+static inline int8_t xran_check_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+{
+    if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+        print_err("Invalid CC ID - %d", cc_id);
+        return (-1);
+    }
+
+    if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+        print_err("Invalid antenna ID - %d", ant_id);
+        return (-1);
+    }
+
+    /* O-RU needs to check the sequence ID of U-Plane DL from O-DU */
+    xran_updl_seq_id_num[cc_id][ant_id]++;
+    if(xran_updl_seq_id_num[cc_id][ant_id] == seq_id) {
+        /* expected sequence */
+        return (0);
+    } else {
+        xran_updl_seq_id_num[cc_id][ant_id] = seq_id;
+        return (-1);
+    }
+}
+
+
+static struct xran_section_gen_info cpSections[XRAN_MAX_NUM_SECTIONS];
 static struct xran_cp_gen_params cpInfo;
 int process_cplane(struct rte_mbuf *pkt)
 {
-  int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result);
+  struct xran_recv_packet_info recv;
 
     cpInfo.sections = cpSections;
-    xran_parse_cp_pkt(pkt, &cpInfo);
+    xran_parse_cp_pkt(pkt, &cpInfo, &recv);
 
-    return (0);
+    return (MBUF_FREE);
 }
 //////////////////////////////////////////
 
 void sym_ota_cb(struct rte_timer *tim, void *arg)
 {
-    uint8_t offset = 0;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
     long t1 = MLogTick();
+    static int32_t ctx = 0;
 
     if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 0){
         tti_ota_cb(NULL, arg);
     }
 
-    if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 1){
-        if(p_xran_lib_ctx->phy_tti_cb_done == 0){
-            uint64_t t3 = MLogTick();
+    if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 3){
+        if(p_xran_dev_ctx->phy_tti_cb_done == 0){
             /* rearm timer to deliver TTI event to PHY */
-            p_xran_lib_ctx->phy_tti_cb_done = 0;
-            xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core);
-            MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
+            p_xran_dev_ctx->phy_tti_cb_done = 0;
+            xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core);
         }
     }
 
     xran_process_tx_sym(timer_ctx);
     /* check if there is call back to do something else on this symbol */
-    if(p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym])
-        p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym](&tx_cp_dl_timer, p_xran_lib_ctx->pSymCallbackTag[0][xran_lib_ota_sym]);
+    if(p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym]){
+        p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym](&dpdk_timer[ctx], p_xran_dev_ctx->pSymCallbackTag[0][xran_lib_ota_sym]);
+        ctx = DpdkTiemerIncrementCtx(ctx);
+    }
 
     xran_lib_ota_sym++;
     if(xran_lib_ota_sym >= N_SYM_PER_SLOT){
         xran_lib_ota_sym=0;
     }
+
     MLogTask(PID_SYM_OTA_CB, t1, MLogTick());
 }
 
@@ -267,13 +531,13 @@ void tti_ota_cb(struct rte_timer *tim, void *arg)
     uint64_t t3 = 0;
     uint32_t reg_tti  = 0;
     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
     MLogTask(PID_TTI_TIMER, t1, MLogTick());
 
     /* To match TTbox */
     if(xran_lib_ota_tti == 0)
-        reg_tti = 8000-1;
+        reg_tti = xran_fs_get_max_slot() - 1;
     else
         reg_tti = xran_lib_ota_tti -1;
     MLogIncrementCounter();
@@ -298,38 +562,33 @@ void tti_ota_cb(struct rte_timer *tim, void *arg)
     mlogVar[mlogVarCnt++] = 0;
     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
 
-    if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU)
+    if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU)
         next_tti = xran_lib_ota_tti + 1;
     else
         next_tti = xran_lib_ota_tti;
 
-    if(next_tti>= SLOTNUM_PER_SUBFRAME*1000){
+    if(next_tti>= xran_fs_get_max_slot()){
         print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
         next_tti=0;
     }
-    /* [0 - 7] */
+
     slot_id     = XranGetSlotNum(next_tti, SLOTNUM_PER_SUBFRAME);
-    /* sf [0 - 9] */
     subframe_id = XranGetSubFrameNum(next_tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
-    /* frame [0 - 99] for now */
     frame_id    = XranGetFrameNum(next_tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
 
     print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
 
-    if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU){
+    if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU){
         pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = next_tti;
     } else {
         pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = pTCtx[(xran_lib_ota_tti & 1)^1].tti_to_process;
     }
 
-    t3 = MLogTick();
-    p_xran_lib_ctx->phy_tti_cb_done = 0;
-    xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core);
-    MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
+    p_xran_dev_ctx->phy_tti_cb_done = 0;
+    xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core);
 
     xran_lib_ota_tti++;
-    /* within 1 sec we have 8000 TTIs as 1000ms/0.125ms where TTI is 125us*/
-    if(xran_lib_ota_tti >= SLOTNUM_PER_SUBFRAME*1000){
+    if(xran_lib_ota_tti >= xran_fs_get_max_slot()){
         print_dbg("[%d]SFN %d sf %d slot %d\n",xran_lib_ota_tti, frame_id, subframe_id, slot_id);
         xran_lib_ota_tti=0;
     }
@@ -338,87 +597,309 @@ void tti_ota_cb(struct rte_timer *tim, void *arg)
 
 void xran_timer_arm(struct rte_timer *tim, void* arg)
 {
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    uint64_t t3 = MLogTick();
+
     if (xran_if_current_state == XRAN_RUNNING){
         rte_timer_cb_t fct = (rte_timer_cb_t)arg;
-        rte_timer_reset_sync(tim, 0, SINGLE, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core, fct, timer_ctx);
+        rte_timer_init(tim);
+        rte_timer_reset_sync(tim, 0, SINGLE, p_xran_dev_ctx->fh_init.io_cfg.timing_core, fct, &timer_ctx[0]);
     }
+    MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
 }
 
 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore)
 {
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    uint64_t t3 = MLogTick();
+
     if (xran_if_current_state == XRAN_RUNNING){
         rte_timer_cb_t fct = (rte_timer_cb_t)CbFct;
         rte_timer_init(tim);
         rte_timer_reset_sync(tim, 0, SINGLE, tim_lcore, fct, CbArg);
     }
+    MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
 }
 
+int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id,
+        struct xran_prb_map *prbMapElem)
+{
+    struct xran_cp_gen_params params;
+    struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
+    struct rte_mbuf *mbuf;
+    int ret = 0;
+    uint32_t i;
+    uint32_t nsection = prbMapElem->nPrbElm;
+    struct xran_prb_elm *pPrbMapElem = &prbMapElem->prbMap[0];
+    struct xran_prb_elm *pPrbMapElemPrev;
+    uint32_t slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
+    uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
+    uint32_t frame_id    = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+    uint8_t seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id);
+
+    params.dir                  = dir;
+    params.sectionType          = XRAN_CP_SECTIONTYPE_1;        // Most DL/UL Radio Channels
+    params.hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;
+    params.hdr.frameId          = frame_id;
+    params.hdr.subframeId       = subframe_id;
+    params.hdr.slotId           = slot_id;
+    params.hdr.startSymId       = pPrbMapElem->nStartSymb;
+    params.hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);
+    params.hdr.compMeth         = pPrbMapElem->compMethod;
+
+    for (i=0; i<nsection; i++)
+    {
+        pPrbMapElem = &prbMapElem->prbMap[i];
+        sect_geninfo[i].info.type        = params.sectionType;       // for database
+        sect_geninfo[i].info.startSymId  = params.hdr.startSymId;    // for database
+        sect_geninfo[i].info.iqWidth     = params.hdr.iqWidth;       // for database
+        sect_geninfo[i].info.compMeth    = params.hdr.compMeth;      // for database
+        sect_geninfo[i].info.id          = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
+        sect_geninfo[i].info.rb          = XRAN_RBIND_EVERY;
+        sect_geninfo[i].info.startPrbc   = pPrbMapElem->nRBStart;
+        sect_geninfo[i].info.numPrbc     = pPrbMapElem->nRBSize;
+        sect_geninfo[i].info.numSymbol   = pPrbMapElem->numSymb;
+        sect_geninfo[i].info.reMask      = 0xfff;
+        sect_geninfo[i].info.beamId      = pPrbMapElem->nBeamIndex;
+        if (i==0)
+            sect_geninfo[i].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
+        else
+        {
+            pPrbMapElemPrev = &prbMapElem->prbMap[i-1];
+            if (pPrbMapElemPrev->nStartSymb == pPrbMapElem->nStartSymb)
+            {
+                sect_geninfo[i].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
+                if (pPrbMapElemPrev->numSymb != pPrbMapElem->numSymb)
+                    print_err("section info error: previous numSymb %d not equal to current numSymb %d\n", pPrbMapElemPrev->numSymb, pPrbMapElem->numSymb);
+            }
+            else
+            {
+                sect_geninfo[i].info.symInc      = XRAN_SYMBOLNUMBER_INC;
+                if (pPrbMapElem->nStartSymb != (pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb))
+                    print_err("section info error: current startSym %d not equal to previous endSymb %d\n", pPrbMapElem->nStartSymb, pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb);
+            }
+        }
+
+        /* extension is not supported */
+        sect_geninfo[nsection].info.ef          = 0;
+        sect_geninfo[nsection].exDataSize       = 0;
+        //sect_geninfo[nsection].exData           = NULL;
+    }
+    params.numSections          = nsection;
+    params.sections             = sect_geninfo;
+
+    mbuf = xran_ethdi_mbuf_alloc();
+    if(unlikely(mbuf == NULL)) {
+        print_err("Alloc fail!\n");
+        return (-1);
+        }
+
+    ret = xran_prepare_ctrl_pkt(mbuf, &params, cc_id, ru_port_id, seq_id);
+    if(ret < 0) {
+        print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
+                    frame_id, subframe_id, slot_id, dir);
+    } else {
+        /* add in the ethernet header */
+        struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+        xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
+        tx_counter++;
+        for(i=0; i<nsection; i++)
+            xran_cp_add_section_info(pHandle,
+                    dir, cc_id, ru_port_id,
+                    (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
+                    &sect_geninfo[i].info);
+    }
+
+    return ret;
+}
+#if 0
+int xran_cp_create_rbmap(int dir, int tti, int cc_id,
+        struct xran_flat_buffer *prbMapElem,
+        struct xran_cp_rbmap_list *rbMapList)
+{
+  struct xran_prb_map *prb_map;
+  int list_index = 0;
+  int sym_id;
+  int i, j;
+
+    prb_map  = (struct xran_prb_map *)prbMapElm[0].pData;
+    cc_id   = prb_map->cc_id;
+    tti     = prb_map->tti_id;
+    dir     = prb_map->dir;
+
+
+    list_index = -1;
+    for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) {
+        /* skip symbol, if not matched with given direction */
+        int type_sym = xran_fs_get_symbol_type(cc_id, tti, sym_id);
+        if(type_sym != XRAN_SYMBOL_TYPE_FDD && type_sym != dir)
+            continue;
+
+        /* retrieve the information of RB allocation */
+        prb_map = (struct xran_prb_map *)prbMapElem[sym_id].pData;
+        if(unlikely(prb_map == NULL)) {
+            print_err("RB allocation table is NULL! (tti:%d, cc:%d, sym_id:%d)", tti, cc_id, sym_id);
+            continue;
+            }
+
+        /* creating 2D mapping */
+        for(i=0; i < prb_map->nPrbElm; i++) {
+            if(list_index < 0) {   /* create first entry */
+                list_index = 0;
+                rbMapList[list_index].grp_id    = 0;
+                rbMapList[list_index].sym_start = sym_id;   // prb_map->sym_id
+                rbMapList[list_index].sym_num   = 1;
+                rbMapList[list_index].rb_start  = prb_map->prbMap[i].nRBStart;
+                rbMapList[list_index].rb_num    = prb_map->prbMap[i].nRBSize;
+                rbMapList[list_index].beam_id   = prb_map->prbMap[i].nBeamIndex;
+                rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+                }
+            else {
+                /* find consecutive allocation from list */
+                for(j=0; j<list_index+1; j++) {
+                    if(prb_map->prbMap[i].nRBStart   != rbMapList[j].rb_start
+                            || prb_map->prbMap[i].nRBSize    != rbMapList[j].rb_num
+                            || prb_map->prbMap[i].nBeamIndex != rbMapList[j].beam_id
+                            || prb_map->prbMap[i].compMethod != rbMapList[j].comp_meth
+                            || sym_id != (rbMapList[j].sym_start+rbMapList[j].sym_num)) {
+                        /* move to next */
+                        continue;
+                        }
+                    else {
+                        /* consecutive allocation has been found */
+                        rbMapList[j].sym_num++;
+                        break;
+                        }
+                    }
+
+                if(j == list_index+1) { /* different allocation, create new entry */
+                    list_index++;
+                    rbMapList[list_index].grp_id    = 0;
+                    rbMapList[list_index].sym_start = sym_id;   // prb_map->sym_id
+                    rbMapList[list_index].sym_num   = 1;
+                    rbMapList[list_index].rb_start  = prb_map->prbMap[i].nRBStart;
+                    rbMapList[list_index].rb_num    = prb_map->prbMap[i].nRBSize;
+                    rbMapList[list_index].beam_id   = prb_map->prbMap[i].nBeamIndex;
+                    rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+                    }
+                }
+            } /* for(i=0; i < prb_map->nPrbElm; i++) */
+        } /* for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) */
+
+    list_index++;
+
+#if 0
+    for(i=0; i<list_index; i++) {
+        printf("[%c:%d-%d] %d - symstart=%d, symnum=%d, rbstart=%d, rbnum=%d, beamid=%d, comp=%d\n",
+                dir?'U':'D', tti, cc_id, i,
+                rbMapList[i].sym_start, rbMapList[i].sym_num,
+                rbMapList[i].rb_start, rbMapList[i].rb_num,
+                rbMapList[i].beam_id, rbMapList[i].comp_meth);
+        }
+#endif
+    return (list_index);
+}
+#endif
+
 void tx_cp_dl_cb(struct rte_timer *tim, void *arg)
 {
   long t1 = MLogTick();
-  int tti, sym;
+  int tti, buf_id;
+  int i, ret;
   uint32_t slot_id, subframe_id, frame_id;
-  int ant_id;
-  int32_t cc_id = 0;
-  uint16_t beam_id;
-  uint8_t num_eAxc, num_CCPorts;
+  int cc_id;
+  uint8_t ctx_id;
+  uint8_t ant_id, num_eAxc, num_CCPorts;
   void *pHandle;
+  int num_list;
+  struct xran_cp_rbmap_list rb_map_list[XRAN_MAX_PRBS*N_SYM_PER_SLOT];    /* array size can be reduced */
 
-  struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
   struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
 
-
     pHandle = NULL;     // TODO: temp implemantation
     num_eAxc    = xran_get_num_eAxc(pHandle);
     num_CCPorts = xran_get_num_cc(pHandle);
 
-    if(p_xran_lib_ctx->enableCP) {
+    if(p_xran_dev_ctx->enableCP) {
 
         tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
+        buf_id = tti % XRAN_N_FE_BUF_LEN;
 
         slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
         subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
         frame_id    = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+        ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
 
         print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
 
         for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
             for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
-                 // start new section information list
-                xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id);
 
-                beam_id = xran_get_beamid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id);
+                /* start new section information list */
+                xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id, ctx_id);
+
+                if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) { // 1 when FDD, DL slot or DL symbol is present in SP slot
+                    if (p_xran_dev_ctx->DynamicSectionEna){
+                        num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_DL, tti, cc_id,
+                            (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData);
+                    }
+                    else{
+                        struct xran_cp_gen_params params;
+                        struct xran_section_gen_info sect_geninfo[8];
+                        struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
+
+                        /* use symb 0 only with constant RBs for full slot */
+                        struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData;
+                        num_list = 1;
+                        rb_map_list[0].sym_start = 0;
+                        rb_map_list[0].sym_num   = 14;
+                        rb_map_list[0].rb_start  = prb_map->prbMap[0].nRBStart;
+                        rb_map_list[0].rb_num    = prb_map->prbMap[0].nRBSize;
+                        rb_map_list[0].beam_id   = prb_map->prbMap[0].nBeamIndex;
+                        rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod;
+
+                        for(i=0; i<num_list; i++) {
+                            ret = generate_cpmsg_dlul(pHandle, &params, sect_geninfo, mbuf, XRAN_DIR_DL,
+                                    frame_id, subframe_id, slot_id,
+                                    rb_map_list[i].sym_start, rb_map_list[i].sym_num,
+                                    rb_map_list[i].rb_start, rb_map_list[i].rb_num,
+                                    rb_map_list[i].beam_id, cc_id, ant_id, rb_map_list[i].comp_meth,
+                                    xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id), XRAN_SYMBOLNUMBER_NOTINC);
+
+                            if (ret == XRAN_STATUS_SUCCESS)
+                                send_cpmsg(pHandle, mbuf, &params, sect_geninfo,
+                                    cc_id, ant_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id));
+                        }
+                    }
+                } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) */
+            } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+        } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
+    } /* if(p_xran_dev_ctx->enableCP) */
 
-                send_cpmsg_dlul(pHandle, XRAN_DIR_DL,
-                                frame_id, subframe_id, slot_id,
-                                0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
-                                beam_id, cc_id, ant_id,
-                                xran_get_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id));
-                }
-            }
-        }
     MLogTask(PID_CP_DL_CB, t1, MLogTick());
 }
 
 void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
 {
     long t1 = MLogTick();
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
-    XranStatusInt32 status;
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    xran_status_t status;
     /* half of RX for current TTI as measured against current OTA time */
     int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+    int32_t cc_id;
 
-    if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+    if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
         return;
 
-    if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
-        status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */
-        if(p_xran_lib_ctx->pCallback[0])
-           p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
-    } else {
-        p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
+    for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
+        if(p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] == 0){
+            status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */
+            if(p_xran_dev_ctx->pCallback[cc_id])
+               p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
+        } else {
+            p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] = 0;
+        }
     }
     MLogTask(PID_UP_UL_HALF_DEAD_LINE_CB, t1, MLogTick());
 }
@@ -426,24 +907,28 @@ void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
 void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
 {
     long t1 = MLogTick();
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
-    XranStatusInt32 status;
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    xran_status_t status = 0;
     int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+    int32_t cc_id = 0;
 
-    if(rx_tti >= 8000-1)
-       rx_tti = 0;
+    if(rx_tti == 0)
+       rx_tti = (xran_fs_get_max_slot()-1);
     else
        rx_tti -= 1; /* end of RX for prev TTI as measured against current OTA time */
 
-    if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+    if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
         return;
 
-    if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
+    /* U-Plane */
+    for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
         status = (rx_tti << 16) | 7; /* last 7 sym means full slot of Symb */
-        if(p_xran_lib_ctx->pCallback[0])
-           p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
-    } else {
-        p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
+        if(p_xran_dev_ctx->pCallback[cc_id])
+           p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
+
+        if(p_xran_dev_ctx->pPrachCallback[cc_id])
+           p_xran_dev_ctx->pPrachCallback[cc_id](p_xran_dev_ctx->pPrachCallbackTag[cc_id], status);
+
     }
 
     MLogTask(PID_UP_UL_FULL_DEAD_LINE_CB, t1, MLogTick());
@@ -453,69 +938,105 @@ void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
 void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
 {
     long t1 = MLogTick();
-    int sym, tti;
-    uint32_t    frame_id    = 0;
-    uint32_t    subframe_id = 0;
-    uint32_t    slot_id     = 0;
-
+    int tti, buf_id;
+    int i, ret;
+    uint32_t slot_id, subframe_id, frame_id;
     int32_t cc_id;
     int ant_id, prach_port_id;
     uint16_t beam_id;
     uint8_t num_eAxc, num_CCPorts;
+    uint8_t ctx_id;
 
     void *pHandle;
+    int num_list;
+    struct xran_cp_rbmap_list rb_map_list[XRAN_MAX_PRBS*N_SYM_PER_SLOT];    /* array size can be reduced */
 
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
-    xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_lib_ctx->PrachCPConfig);
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
 
     pHandle     = NULL;     // TODO: temp implemantation
     num_eAxc    = xran_get_num_eAxc(pHandle);
     num_CCPorts = xran_get_num_cc(pHandle);
+    tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
+    buf_id = tti % XRAN_N_FE_BUF_LEN;
+    slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
+    subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
+    frame_id    = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+    ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
 
-    if (p_xran_lib_ctx->enableCP){
-        tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
-        slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
-        subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
-        frame_id    = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
-        print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
+    if(p_xran_dev_ctx->enableCP) {
 
+        print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
 
         for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
-            for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
-                // start new section information list
-                xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id);
+            for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
+                if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 ||
+                    xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1 ){
+                    /* start new section information list */
+                    xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id, ctx_id);
+                    if (p_xran_dev_ctx->DynamicSectionEna){
+                        /* create a map of RB allocation to generate proper C-Plane */
+                        num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_UL, tti, cc_id,
+                            (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData);
+                    }
+                    else{
+                        struct xran_cp_gen_params params;
+                        struct xran_section_gen_info sect_geninfo[8];
+                        struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
+                        /* use symb 0 only with constant RBs for full slot */
+                        struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData;
+                        num_list = 1;
+                        rb_map_list[0].sym_start = 0;
+                        rb_map_list[0].sym_num   = 14;
+                        rb_map_list[0].rb_start  = prb_map->prbMap[0].nRBStart;
+                        rb_map_list[0].rb_num    = prb_map->prbMap[0].nRBSize;
+                        rb_map_list[0].beam_id   = prb_map->prbMap[0].nBeamIndex;
+                        rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod;
+
+                        for(i=0; i<num_list; i++) {
+                            ret = generate_cpmsg_dlul(pHandle, &params, sect_geninfo, mbuf, XRAN_DIR_UL,
+                                    frame_id, subframe_id, slot_id,
+                                    rb_map_list[i].sym_start, rb_map_list[i].sym_num,
+                                    rb_map_list[i].rb_start, rb_map_list[i].rb_num,
+                                    rb_map_list[i].beam_id, cc_id, ant_id, rb_map_list[i].comp_meth,
+                                    xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id), XRAN_SYMBOLNUMBER_NOTINC);
+                            if (ret == XRAN_STATUS_SUCCESS)
+                                send_cpmsg(pHandle, mbuf, &params, sect_geninfo,
+                                    cc_id, ant_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id));
+                        }
+                    }
+                } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 || */
 
-                beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id);
-                send_cpmsg_dlul(pHandle, XRAN_DIR_UL,
-                                frame_id, subframe_id, slot_id,
-                                0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
-                                beam_id, cc_id, ant_id,
-                                xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id));
-            }
-        }
+            } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+        } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
+    } /* if(p_xran_dev_ctx->enableCP) */
 
-        if ((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (pPrachCPConfig->isPRACHslot[slot_id]==1))  //is prach slot
-        {
-            for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
+    if(p_xran_dev_ctx->enablePrach) {
+        uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id);
+        if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (isPRACHslot==1)) {   //is prach slot
+            for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
                 for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
-#if !defined(PRACH_USES_SHARED_PORT)
+                    struct xran_cp_gen_params params;
+                    struct xran_section_gen_info sect_geninfo[8];
+                    struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
                     prach_port_id = ant_id + num_eAxc;
-                    // start new section information list
-                    xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id);
-#else
-                    prach_port_id = ant_id;
-#endif
-                    beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
-                    send_cpmsg_prach(pHandle,
-                                    frame_id, subframe_id, slot_id,
-                                    beam_id, cc_id, prach_port_id,
-                                    xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id));
+                    /* start new section information list */
+                    xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, ctx_id);
+
+                    beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id); /* TODO: */
+                    ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
+                                frame_id, subframe_id, slot_id,
+                                beam_id, cc_id, prach_port_id,
+                                xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
+                    if (ret == XRAN_STATUS_SUCCESS)
+                        send_cpmsg(pHandle, mbuf, &params, sect_geninfo,
+                            cc_id, prach_port_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
                 }
             }
         }
-
     }
+
     MLogTask(PID_CP_UL_CB, t1, MLogTick());
 }
 
@@ -529,22 +1050,22 @@ void ul_up_full_slot_cb(struct rte_timer *tim, void *arg)
 void tti_to_phy_cb(struct rte_timer *tim, void *arg)
 {
     long t1 = MLogTick();
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
     static int first_call = 0;
-    p_xran_lib_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
+    p_xran_dev_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
     if (first_call){
-        if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
-            if(p_xran_lib_ctx->SkipTti[XRAN_CB_TTI] <= 0){
-                p_xran_lib_ctx->ttiCb[XRAN_CB_TTI](p_xran_lib_ctx->TtiCbParam[XRAN_CB_TTI]);
+        if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
+            if(p_xran_dev_ctx->SkipTti[XRAN_CB_TTI] <= 0){
+                p_xran_dev_ctx->ttiCb[XRAN_CB_TTI](p_xran_dev_ctx->TtiCbParam[XRAN_CB_TTI]);
             }else{
-                p_xran_lib_ctx->SkipTti[XRAN_CB_TTI]--;
+                p_xran_dev_ctx->SkipTti[XRAN_CB_TTI]--;
             }
         }
     } else {
-        if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
+        if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
             int32_t tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
-            if(tti == 8000-1)
+            if(tti == xran_fs_get_max_slot()-1)
                 first_call = 1;
         }
     }
@@ -570,7 +1091,7 @@ int xran_timing_source_thread(void *args)
     uint32_t sym_up_ul;
     int32_t sym_up;
     struct sched_param sched_param;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
     /* ToS = Top of Second start +- 1.5us */
     struct timespec ts;
@@ -583,7 +1104,7 @@ int xran_timing_source_thread(void *args)
     sched_param.sched_priority = 98;
 
     CPU_ZERO(&cpuset);
-    CPU_SET(p_xran_lib_ctx->xran_init_cfg.io_cfg.timing_core, &cpuset);
+    CPU_SET(p_xran_dev_ctx->fh_init.io_cfg.timing_core, &cpuset);
     if (result1 = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset))
     {
         printf("pthread_setaffinity_np failed: coreId = 2, result1 = %d\n",result1);
@@ -593,7 +1114,7 @@ int xran_timing_source_thread(void *args)
         printf("priority is not changed: coreId = 2, result1 = %d\n",result1);
     }
 
-    if (p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
+    if (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
         do {
            timespec_get(&ts, TIME_UTC);
         }while (ts.tv_nsec >1500);
@@ -603,18 +1124,18 @@ int xran_timing_source_thread(void *args)
             printf("lls-CU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
         }
 
-        delay_cp_dl = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_dl;
-        delay_cp_ul = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_ul;
-        delay_up    = p_xran_lib_ctx->xran_init_cfg.T1a_max_up;
-        delay_up_ul = p_xran_lib_ctx->xran_init_cfg.Ta4_max;
+        delay_cp_dl = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_dl;
+        delay_cp_ul = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_ul;
+        delay_up    = p_xran_dev_ctx->fh_init.T1a_max_up;
+        delay_up_ul = p_xran_dev_ctx->fh_init.Ta4_max;
 
         delay_cp2up = delay_up-delay_cp_dl;
 
         sym_cp_dl = delay_cp_dl*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
         sym_cp_ul = delay_cp_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
         sym_up_ul = delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT);
-        p_xran_lib_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
-        p_xran_lib_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
+        p_xran_dev_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
+        p_xran_dev_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
 
         printf("Start C-plane DL %d us after TTI  [trigger on sym %d]\n", delay_cp_dl, sym_cp_dl);
         printf("Start C-plane UL %d us after TTI  [trigger on sym %d]\n", delay_cp_ul, sym_cp_ul);
@@ -624,24 +1145,24 @@ int xran_timing_source_thread(void *args)
         printf("C-plane to U-plane delay %d us after TTI\n", delay_cp2up);
         printf("Start Sym timer %ld ns\n", TX_TIMER_INTERVAL/N_SYM_PER_SLOT);
 
-        p_xran_lib_ctx->pSymCallback[0][sym_cp_dl]    = xran_timer_arm;
-        p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb;
+        p_xran_dev_ctx->pSymCallback[0][sym_cp_dl]    = xran_timer_arm;
+        p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb;
 
-        p_xran_lib_ctx->pSymCallback[0][sym_cp_ul]    = xran_timer_arm;
-        p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb;
+        p_xran_dev_ctx->pSymCallback[0][sym_cp_ul]    = xran_timer_arm;
+        p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb;
 
         /* Full slot UL OTA + delay_up_ul */
-        p_xran_lib_ctx->pSymCallback[0][sym_up_ul]    = xran_timer_arm;
-        p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb;
+        p_xran_dev_ctx->pSymCallback[0][sym_up_ul]    = xran_timer_arm;
+        p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb;
 
         /* Half slot UL OTA + delay_up_ul*/
-        p_xran_lib_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2]    = xran_timer_arm;
-        p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb;
+        p_xran_dev_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2]    = xran_timer_arm;
+        p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb;
 
-    } else {    // APP_RU
+    } else {    // APP_O_RU
         /* calcualte when to send UL U-plane */
-        delay_up = p_xran_lib_ctx->xran_init_cfg.Ta3_min;
-        p_xran_lib_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
+        delay_up = p_xran_dev_ctx->fh_init.Ta3_min;
+        p_xran_dev_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
         printf("Start UL U-plane %d us after OTA [offset in sym %d]\n", delay_up, sym_up);
         do {
            timespec_get(&ts, TIME_UTC);
@@ -653,6 +1174,7 @@ int xran_timing_source_thread(void *args)
         }
     }
 
+    printf("interval_us %ld\n", interval_us);
     do {
        timespec_get(&ts, TIME_UTC);
     }while (ts.tv_nsec == 0);
@@ -661,9 +1183,11 @@ int xran_timing_source_thread(void *args)
         delta = poll_next_tick(interval_us*1000L/N_SYM_PER_SLOT);
         if (XRAN_STOPPED == xran_if_current_state)
             break;
-        sym_ota_cb(&sym_timer, timer_ctx);
+
+        if (likely(XRAN_RUNNING == xran_if_current_state))
+            sym_ota_cb(&sym_timer, timer_ctx);
     }
-    printf("Closing timing source thread...\n");
+    printf("Closing timing source thread...tx counter %lu, rx counter %lu\n", tx_counter, rx_counter);
 
     return 0;
 }
@@ -673,45 +1197,45 @@ int handle_ecpri_ethertype(struct rte_mbuf *pkt, uint64_t rx_time)
 {
     const struct xran_ecpri_hdr *ecpri_hdr;
     unsigned long t1;
+    int32_t ret = MBUF_FREE;
 
     if (rte_pktmbuf_data_len(pkt) < sizeof(struct xran_ecpri_hdr)) {
-        wlog("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
+        print_err("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
         return 0;
     }
 
     /* check eCPRI header. */
     ecpri_hdr = rte_pktmbuf_mtod(pkt, struct xran_ecpri_hdr *);
-    if(ecpri_hdr == NULL)
+    if(ecpri_hdr == NULL){
+        print_err("ecpri_hdr error\n");
         return MBUF_FREE;
+    }
 
-    switch(ecpri_hdr->ecpri_mesg_type) {
+    switch(ecpri_hdr->cmnhdr.ecpri_mesg_type) {
         case ECPRI_IQ_DATA:
-            t1 = MLogTick();
-            process_mbuf(pkt);
-            MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
+           // t1 = MLogTick();
+            ret = process_mbuf(pkt);
+          //  MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
             break;
         // For RU emulation
         case ECPRI_RT_CONTROL_DATA:
             t1 = MLogTick();
-            if(xran_lib_get_ctx()->xran_init_cfg.io_cfg.id == APP_RU) {
-                process_cplane(pkt);
+            if(xran_dev_get_ctx()->fh_init.io_cfg.id == O_RU) {
+                ret = process_cplane(pkt);
             } else {
-                print_err("LLS-CU recevied CP message!");
+                print_err("O-DU recevied C-Plane message!");
             }
             MLogTask(PID_PROCESS_CP_PKT, t1, MLogTick());
             break;
         default:
-            wlog("Invalid eCPRI message type - %d", ecpri_hdr->ecpri_mesg_type);
+            print_err("Invalid eCPRI message type - %d", ecpri_hdr->cmnhdr.ecpri_mesg_type);
         }
-#if 0
-//def DEBUG
-    return MBUF_KEEP;
-#else
-    return MBUF_FREE;
-#endif
+
+    return ret;
 }
 
-int xran_process_rx_sym(void *arg,
+int xran_process_prach_sym(void *arg,
+                        struct rte_mbuf *mbuf,
                         void *iq_data_start,
                         uint16_t size,
                         uint8_t CC_ID,
@@ -719,37 +1243,48 @@ int xran_process_rx_sym(void *arg,
                         uint8_t frame_id,
                         uint8_t subframe_id,
                         uint8_t slot_id,
-                        uint8_t symb_id)
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id)
 {
     char        *pos = NULL;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
-    uint32_t tti=0;
-    XranStatusInt32 status;
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    uint8_t symb_id_offset;
+    uint32_t tti = 0;
+    xran_status_t status;
     void *pHandle = NULL;
+    struct rte_mbuf *mb;
 
-    if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+    uint16_t iq_sample_size_bits = 16;
+
+    if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
         return 0;
 
     tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
 
     status = tti << 16 | symb_id;
 
-    if(tti < 8000 && CC_ID < XRAN_MAX_SECTOR_NR &&  CC_ID == 0 && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
-        pos = (char*) p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
+    if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
+        symb_id_offset = symb_id - p_xran_dev_ctx->prach_start_symbol[CC_ID]; //make the storing of prach packets to start from 0 for easy of processing within PHY
+        pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData;
         if(pos && iq_data_start && size){
-#ifdef XRAN_BYTE_ORDER_SWAP
-            int idx = 0;
-            uint16_t *restrict psrc = (uint16_t *)iq_data_start;
-            uint16_t *restrict pdst = (uint16_t *)pos;
-            /* network byte (be) order of IQ to CPU byte order (le) */
-            for (idx = 0; idx < size/sizeof(int16_t); idx++){
-                pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+            if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
+                int idx = 0;
+                uint16_t *psrc = (uint16_t *)iq_data_start;
+                uint16_t *pdst = (uint16_t *)pos;
+                /* network byte (be) order of IQ to CPU byte order (le) */
+                for (idx = 0; idx < size/sizeof(int16_t); idx++){
+                    pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+                }
+            }else {
+                mb = p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl;
+                rte_pktmbuf_free(mb);
+                p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData = iq_data_start;
+                p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl = mbuf;
             }
-#else
-#error xran spec is network byte order
-            /* for debug */
-            rte_memcpy(pdst, psrc, size);
-#endif
 #ifdef DEBUG_XRAN_BUFFERS
             if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
                 pos[1] != CC_ID  ||
@@ -764,25 +1299,176 @@ int xran_process_rx_sym(void *arg,
     } else {
         print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id);
     }
-    if (symb_id == 7 || symb_id == 13){
-        p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
 
-        if(p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
-            if(p_xran_lib_ctx->pCallback[0])
-               p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
-            p_xran_lib_ctx->rx_packet_callback_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID] = 1;
-            p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
+/*    if (symb_id == p_xran_dev_ctx->prach_last_symbol[CC_ID] ){
+        p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
+        if(p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
+            if(p_xran_dev_ctx->pPrachCallback[0])
+               p_xran_dev_ctx->pPrachCallback[0](p_xran_dev_ctx->pPrachCallbackTag[0], status);
+            p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
         }
     }
+*/
     return size;
 }
 
+int32_t xran_pkt_validate(void *arg,
+                        struct rte_mbuf *mbuf,
+                        void *iq_data_start,
+                        uint16_t size,
+                        uint8_t CC_ID,
+                        uint8_t Ant_ID,
+                        uint8_t frame_id,
+                        uint8_t subframe_id,
+                        uint8_t slot_id,
+                        uint8_t symb_id,
+                        struct ecpri_seq_id *seq_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id)
+{
+    struct xran_device_ctx * pctx = xran_dev_get_ctx();
+    struct xran_common_counters *pCnt = &pctx->fh_counters;
+
+    if(pctx->fh_init.io_cfg.id == O_DU) {
+        if(xran_check_upul_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
+            pCnt->Rx_pkt_dupl++;
+            return (XRAN_STATUS_FAIL);
+        }
+    }else if(pctx->fh_init.io_cfg.id == O_RU) {
+        if(xran_check_updl_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
+            pCnt->Rx_pkt_dupl++;
+            return (XRAN_STATUS_FAIL);
+        }
+    }else {
+        print_err("incorrect dev type %d\n", pctx->fh_init.io_cfg.id);
+    }
+
+    rx_counter++;
+
+    pCnt->Rx_on_time++;
+    pCnt->Total_msgs_rcvd++;
+
+    return XRAN_STATUS_SUCCESS;
+}
+
+int xran_process_rx_sym(void *arg,
+                        struct rte_mbuf *mbuf,
+                        void *iq_data_start,
+                        uint16_t size,
+                        uint8_t CC_ID,
+                        uint8_t Ant_ID,
+                        uint8_t frame_id,
+                        uint8_t subframe_id,
+                        uint8_t slot_id,
+                        uint8_t symb_id,
+                        uint16_t num_prbu,
+                        uint16_t start_prbu,
+                        uint16_t sym_inc,
+                        uint16_t rb,
+                        uint16_t sect_id,
+                        uint32_t *mb_free)
+{
+    char        *pos = NULL;
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    uint32_t tti = 0;
+    xran_status_t status;
+    void *pHandle = NULL;
+    struct rte_mbuf *mb = NULL;
+
+    uint16_t iq_sample_size_bits = 16;
+
+    tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
+
+    status = tti << 16 | symb_id;
+
+    if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
+        pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
+        pos += start_prbu * N_SC_PER_PRB*(iq_sample_size_bits/8)*2;
+        if(pos && iq_data_start && size){
+            if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
+                int idx = 0;
+                uint16_t *psrc = (uint16_t *)iq_data_start;
+                uint16_t *pdst = (uint16_t *)pos;
+                rte_panic("XRAN_CPU_LE_BYTE_ORDER is not supported 0x16%lx\n", (long)mb);
+                /* network byte (be) order of IQ to CPU byte order (le) */
+                for (idx = 0; idx < size/sizeof(int16_t); idx++){
+                    pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+                }
+            } else if (likely(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_NE_BE_BYTE_ORDER)){
+                if (likely (p_xran_dev_ctx->fh_init.mtu >=
+                              p_xran_dev_ctx->fh_cfg.nULRBs * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) {
+                    /* no fragmentation */
+                    mb = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl;
+                    if(mb){
+                       rte_pktmbuf_free(mb);
+                    }else{
+                       print_err("mb==NULL\n");
+                    }
+                    p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData = iq_data_start;
+                    p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl = mbuf;
+                    *mb_free = MBUF_KEEP;
+                } else {
+                    /* packet can be fragmented copy RBs */
+                    rte_memcpy(pos, iq_data_start, size);
+                    *mb_free = MBUF_FREE;
+                }
+            }
+#ifdef DEBUG_XRAN_BUFFERS
+            if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
+                pos[1] != CC_ID  ||
+                pos[2] != Ant_ID ||
+                pos[3] != symb_id){
+                    printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
+            }
+#endif
+        } else {
+            print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
+        }
+    } else {
+        print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id);
+    }
+
+    return size;
+}
+
+/* Send burst of packets on an output interface */
+static inline int
+xran_send_burst(struct xran_device_ctx *dev, uint16_t n, uint16_t port)
+{
+    struct rte_mbuf **m_table;
+    struct rte_mbuf *m;
+    int32_t i   = 0;
+    int j;
+    int32_t ret = 0;
+
+    m_table = (struct rte_mbuf **)dev->tx_mbufs[port].m_table;
+
+    for(i = 0; i < n; i++){
+        rte_mbuf_sanity_check(m_table[i], 0);
+        /*rte_pktmbuf_dump(stdout, m_table[i], 256);*/
+        tx_counter++;
+        ret += xran_ethdi_mbuf_send(m_table[i], ETHER_TYPE_ECPRI);
+    }
+
+
+    if (unlikely(ret < n)) {
+        print_err("ret < n\n");
+    }
+
+    return 0;
+}
+
 
 int xran_process_tx_sym(void *arg)
 {
     uint32_t    tti=0;
+#if XRAN_MLOG_VAR
     uint32_t    mlogVar[10];
     uint32_t    mlogVarCnt = 0;
+#endif
     unsigned long t1 = MLogTick();
 
     void        *pHandle = NULL;
@@ -798,56 +1484,61 @@ int xran_process_tx_sym(void *arg)
     uint32_t    sym_idx     = 0;
 
     char        *pos = NULL;
+    void        *mb  = NULL;
     int         prb_num = 0;
+    uint16_t    iq_sample_size_bits = 16; // TODO: make dynamic per
 
     struct xran_section_info *sectinfo;
     uint32_t next;
+    uint32_t num_sections;
+    uint8_t ctx_id;
 
     enum xran_pkt_dir  direction;
 
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
 
-
-    if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+    if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
         return 0;
 
-    if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
+    if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
         direction = XRAN_DIR_DL; /* lls-CU */
-        prb_num = NUM_OF_PRB_IN_FULL_BAND;
-        }
-    else {
+        prb_num = p_xran_dev_ctx->fh_cfg.nDLRBs;
+    } else {
         direction = XRAN_DIR_UL; /* RU */
-        prb_num = NUM_OF_PRB_IN_FULL_BAND; /*TODO: simulation on D-1541 @ 2.10GHz has issue with performace. reduce copy size */
-        }
+        prb_num = p_xran_dev_ctx->fh_cfg.nULRBs;
+    }
 
     /* RU: send symb after OTA time with delay (UL) */
     /* lls-CU:send symb in advance of OTA time (DL) */
-    sym_idx     = XranOffsetSym(p_xran_lib_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
+    sym_idx     = XranOffsetSym(p_xran_dev_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
 
     tti         = XranGetTtiNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
     slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
     subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
     frame_id    = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
     sym_id      = XranGetSymNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+    ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
 
     print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
 
+#if XRAN_MLOG_VAR
     mlogVar[mlogVarCnt++] = 0xAAAAAAAA;
     mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
     mlogVar[mlogVarCnt++] = sym_idx;
-    mlogVar[mlogVarCnt++] = abs(p_xran_lib_ctx->sym_up);
+    mlogVar[mlogVarCnt++] = abs(p_xran_dev_ctx->sym_up);
     mlogVar[mlogVarCnt++] = tti;
     mlogVar[mlogVarCnt++] = frame_id;
     mlogVar[mlogVarCnt++] = subframe_id;
     mlogVar[mlogVarCnt++] = slot_id;
     mlogVar[mlogVarCnt++] = sym_id;
     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
+#endif
 
     if(frame_id > 99) {
         print_err("OTA %d: TX:[sym_idx %d: TTI %d] fr %d sf %d slot %d sym %d\n",xran_lib_ota_sym_idx,  sym_idx, tti, frame_id, subframe_id, slot_id, sym_id);
-        xran_if_current_state =XRAN_STOPPED;
-        }
+        xran_if_current_state = XRAN_STOPPED;
+    }
 
     num_eAxc    = xran_get_num_eAxc(pHandle);
     num_CCPorts = xran_get_num_cc(pHandle);
@@ -855,55 +1546,208 @@ int xran_process_tx_sym(void *arg)
     /* U-Plane */
     for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
         for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
-            if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) {
+            if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU
+                    && p_xran_dev_ctx->enableCP) {
+                /*==== lls-CU and C-Plane has been enabled ===*/
                 next = 0;
-                while(next < xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id)) {
-                    sectinfo = xran_cp_iterate_section_info(pHandle, direction,
-                                        cc_id, ant_id, subframe_id, slot_id, &next);
+                num_sections = xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id, ctx_id);
+                /* iterate C-Plane configuration to generate corresponding U-Plane */
+                while(next < num_sections) {
+                    sectinfo = xran_cp_iterate_section_info(pHandle, direction, cc_id, ant_id, ctx_id, &next);
+
                     if(sectinfo == NULL)
                         break;
 
-                    /* pointer to IQs input */
-                    /* TODO: need to implement the case of partial RB assignment */
-                    pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
-                    print_dbg(">>> [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", next,
-                            sectinfo->type, sectinfo->id, sectinfo->startPrbc,
-                            sectinfo->numPrbc, sectinfo->numSymbol);
-
-                    if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) {
+                    if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) {   /* only supports type 1 */
                         print_err("Invalid section type in section DB - %d", sectinfo->type);
                         continue;
+                    }
+
+                    /* skip, if not scheduled */
+                    if(sym_id < sectinfo->startSymId || sym_id >= sectinfo->startSymId + sectinfo->numSymbol)
+                        continue;
+
+                   /* if(sectinfo->compMeth)
+                        iq_sample_size_bits = sectinfo->iqWidth;*/
+
+                    if(iq_sample_size_bits != 16) {/* TODO: support for compression */
+                        print_err("Incorrect iqWidth %d", iq_sample_size_bits);
+                        iq_sample_size_bits = 16;
+                    }
+
+                    print_dbg(">>> sym %2d [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", sym_id, next,
+                                    sectinfo->type, sectinfo->id, sectinfo->startPrbc,
+                                    sectinfo->numPrbc, sectinfo->numSymbol);
+
+                    p_xran_dev_ctx->tx_mbufs[0].len = 0;
+                    uint16_t len  = p_xran_dev_ctx->tx_mbufs[0].len;
+                    int16_t len2 = 0;
+                    uint16_t i    = 0;
+
+                    //Added for Klocworks
+                    if (len >= MBUF_TABLE_SIZE)
+                        len = MBUF_TABLE_SIZE - 1;
+
+                    pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+                    mb  = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
+
+                    /* first all PRBs */
+                    prepare_symbol_ex(direction, sectinfo->id,
+                                      mb,
+                                      (struct rb_map *)pos,
+                                      p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+                                      frame_id, subframe_id, slot_id, sym_id,
+                                      sectinfo->startPrbc, sectinfo->numPrbc,
+                                      cc_id, ant_id,
+                                      xran_get_updl_seqid(pHandle, cc_id, ant_id),
+                                      0);
+
+                    /* if we don't need to do any fragmentation */
+                    if (likely (p_xran_dev_ctx->fh_init.mtu >=
+                                    sectinfo->numPrbc * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) {
+                        /* no fragmentation */
+                        p_xran_dev_ctx->tx_mbufs[0].m_table[len] = mb;
+                        len2 = 1;
+                    } else {
+                        /* fragmentation */
+                        len2 = xran_app_fragment_packet(mb,
+                                                    &p_xran_dev_ctx->tx_mbufs[0].m_table[len],
+                                                    (uint16_t)(MBUF_TABLE_SIZE - len),
+                                                    p_xran_dev_ctx->fh_init.mtu,
+                                                    p_xran_dev_ctx->direct_pool,
+                                                    p_xran_dev_ctx->indirect_pool,
+                                                    sectinfo,
+                                                    xran_get_updl_seqid_addr(pHandle, cc_id, ant_id));
+
+                        /* Free input packet */
+                        rte_pktmbuf_free(mb);
+
+                        /* If we fail to fragment the packet */
+                        if (unlikely (len2 < 0)){
+                            print_err("len2= %d\n", len2);
+                            return 0;
                         }
+                    }
 
-                    send_symbol_ex(direction, sectinfo->id,
-                                    (struct rb_map *)pos,
-                                    frame_id, subframe_id, slot_id, sym_id,
-                                    sectinfo->startPrbc, sectinfo->numPrbc,
-                                    cc_id, ant_id,
-                                    xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
+                    if(len2 > 1){
+                        for (i = len; i < len + len2; i ++) {
+                            struct rte_mbuf *m;
+                            m = p_xran_dev_ctx->tx_mbufs[0].m_table[i];
+                            struct ether_hdr *eth_hdr = (struct ether_hdr *)
+                                rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct ether_hdr));
+                            if (eth_hdr == NULL) {
+                                rte_panic("No headroom in mbuf.\n");
+                            }
+                        }
                     }
-                }
 
-            else {  /* if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) */
-                /* pointer to IQs input */
-                pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+                    len += len2;
+
+                    if (unlikely(len > XRAN_MAX_PKT_BURST_PER_SYM)) {
+                          rte_panic("XRAN_MAX_PKT_BURST_PER_SYM\n");
+                    }
+
+                    /* Transmit packets */
+                    xran_send_burst(p_xran_dev_ctx, (uint16_t)len, 0);
+                    p_xran_dev_ctx->tx_mbufs[0].len = 0;
+                } /* while(section) */
+
+            }
+            else {
+                /*==== RU or C-Plane is disabled ===*/
+                xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
+
+                if(xran_fs_get_slot_type(cc_id, tti, ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SLOT_TYPE_DL : XRAN_SLOT_TYPE_UL)) ==  1
+                        || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) ==  1
+                        || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_FDD) ==  1){
+
+                    if(xran_fs_get_symbol_type(cc_id, tti, sym_id) == ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SYMBOL_TYPE_DL : XRAN_SYMBOL_TYPE_UL)
+                       || xran_fs_get_symbol_type(cc_id, tti, sym_id) == XRAN_SYMBOL_TYPE_FDD){
+
+                        if(iq_sample_size_bits != 16)
+                            print_err("Incorrect iqWidth %d\n", iq_sample_size_bits );
+
+                        pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+                        mb  = (void*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
+
+                        if( prb_num > 136 || prb_num == 0) {
+                            uint16_t sec_id  = xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id);
+                            /* first 136 PRBs */
+                            send_symbol_ex(direction,
+                                            sec_id,
+                                            NULL,
+                                            (struct rb_map *)pos,
+                                            p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+                                            frame_id, subframe_id, slot_id, sym_id,
+                                            0, 136,
+                                            cc_id, ant_id,
+                                            (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+                                                xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+                                                xran_get_upul_seqid(pHandle, cc_id, ant_id));
+
+                             pos += 136 * N_SC_PER_PRB * (iq_sample_size_bits/8)*2;
+                             /* last 137 PRBs */
+                             send_symbol_ex(direction, sec_id,
+                                             NULL,
+                                             (struct rb_map *)pos,
+                                             p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+                                             frame_id, subframe_id, slot_id, sym_id,
+                                             136, 137,
+                                             cc_id, ant_id,
+                                             (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+                                                xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+                                                xran_get_upul_seqid(pHandle,  cc_id, ant_id));
+                        } else {
 #ifdef DEBUG_XRAN_BUFFERS
-                if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
-                    pos[1] != cc_id ||
-                    pos[2] != ant_id ||
-                    pos[3] != sym_id)
-                        printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
+                            if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
+                                pos[1] != cc_id ||
+                                pos[2] != ant_id ||
+                                pos[3] != sym_id)
+                                    printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
 #endif
-                send_symbol_ex(direction,
-                                xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id),
-                                (struct rb_map *)pos,
-                                frame_id, subframe_id, slot_id, sym_id,
-                                0, prb_num,
-                                cc_id, ant_id,
-                                xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
+                            send_symbol_ex(direction,
+                                    xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id),
+                                    (struct rte_mbuf *)mb,
+                                    (struct rb_map *)pos,
+                                    p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+                                    frame_id, subframe_id, slot_id, sym_id,
+                                    0, prb_num,
+                                    cc_id, ant_id,
+                                    (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+                                        xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+                                        xran_get_upul_seqid(pHandle, cc_id, ant_id));
+                        }
+
+                        if(p_xran_dev_ctx->enablePrach
+                                && (p_xran_dev_ctx->fh_init.io_cfg.id == O_RU)) {   /* Only RU needs to send PRACH I/Q */
+                            uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id);
+                            if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0])
+                                    && (isPRACHslot == 1)
+                                    && (sym_id >= p_xran_dev_ctx->prach_start_symbol[cc_id])
+                                    && (sym_id <= p_xran_dev_ctx->prach_last_symbol[cc_id])) {  //is prach slot
+                                for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
+                                    int prach_port_id = ant_id + num_eAxc;
+                                    pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pData;
+                                    pos += (sym_id - p_xran_dev_ctx->prach_start_symbol[cc_id]) * pPrachCPConfig->numPrbc * N_SC_PER_PRB * 4;
+                                    mb  = NULL;//(void*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pCtrl;
+                                    send_symbol_ex(direction,
+                                            xran_alloc_sectionid(pHandle, direction, cc_id, prach_port_id, slot_id),
+                                            (struct rte_mbuf *)mb,
+                                            (struct rb_map *)pos,
+                                            p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+                                            frame_id, subframe_id, slot_id, sym_id,
+                                            pPrachCPConfig->startPrbc, pPrachCPConfig->numPrbc,
+                                            cc_id, prach_port_id,
+                                            xran_get_upul_seqid(pHandle, cc_id, prach_port_id));
+                                }
+                            } /* if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) .... */
+                        } /* if(p_xran_dev_ctx->enablePrach ..... */
+
+                    } /* RU mode or C-Plane is not used */
                 }
             }
-        }
+        } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+    } /* for(ant_id = 0; ant_id < num_eAxc; ant_id++) */
 
     MLogTask(PID_PROCESS_TX_SYM, t1, MLogTick());
     return 0;
@@ -946,106 +1790,111 @@ int xran_packet_and_dpdk_timer_thread(void *args)
 }
 
 
-int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle)
+int32_t
+xran_init(int argc, char *argv[],
+           struct xran_fh_init *p_xran_fh_init, char *appName, void ** pXranLayerHandle)
 {
-    int i;
-    int j;
+    int32_t i;
+    int32_t j;
 
     struct xran_io_loop_cfg *p_io_cfg = (struct xran_io_loop_cfg *)&p_xran_fh_init->io_cfg;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
-    int  lcore_id = 0;
+    int32_t  lcore_id = 0;
     char filename[64];
 
-    memset(p_xran_lib_ctx, 0, sizeof(struct xran_lib_ctx));
+    memset(p_xran_dev_ctx, 0, sizeof(struct xran_device_ctx));
+
     /* copy init */
-    p_xran_lib_ctx->xran_init_cfg = *p_xran_fh_init;
+    p_xran_dev_ctx->fh_init = *p_xran_fh_init;
 
-    xran_if_current_state = XRAN_RUNNING;
-    interval_us =  p_xran_fh_init->ttiPeriod;
+    printf(" %s: MTU %d\n", __FUNCTION__, p_xran_dev_ctx->fh_init.mtu);
 
-    p_xran_lib_ctx->llscu_id = p_xran_fh_init->llscuId;
-    memcpy(&(p_xran_lib_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(XRANEAXCIDCONFIG));
+    xran_if_current_state = XRAN_INIT;
 
-    p_xran_lib_ctx->enableCP = p_xran_fh_init->enableCP;
+    memcpy(&(p_xran_dev_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(struct xran_eaxcid_config));
+
+    p_xran_dev_ctx->enableCP    = p_xran_fh_init->enableCP;
+    p_xran_dev_ctx->enablePrach = p_xran_fh_init->prachEnable;
+    p_xran_dev_ctx->DynamicSectionEna = p_xran_fh_init->DynamicSectionEna;
 
     xran_register_ethertype_handler(ETHER_TYPE_ECPRI, handle_ecpri_ethertype);
     if (p_io_cfg->id == 0)
-        xran_ethdi_init_dpdk_io(basename(appName),
+        xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
                            p_io_cfg,
                            &lcore_id,
-                           (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
-                           (struct ether_addr *)p_xran_fh_init->p_ru_addr,
+                           (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
+                           (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
                            p_xran_fh_init->cp_vlan_tag,
                            p_xran_fh_init->up_vlan_tag);
     else
-        xran_ethdi_init_dpdk_io(basename(appName),
+        xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
                            p_io_cfg,
                            &lcore_id,
-                           (struct ether_addr *)p_xran_fh_init->p_ru_addr,
-                           (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
+                           (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
+                           (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
                            p_xran_fh_init->cp_vlan_tag,
                            p_xran_fh_init->up_vlan_tag);
 
     for(i = 0; i < 10; i++ )
         rte_timer_init(&tti_to_phy_timer[i]);
 
-    rte_timer_init(&tti_timer);
     rte_timer_init(&sym_timer);
-    rte_timer_init(&tx_cp_dl_timer);
-    rte_timer_init(&tx_cp_ul_timer);
-    rte_timer_init(&tx_up_timer);
+    for (i = 0; i< MAX_NUM_OF_DPDK_TIMERS; i++)
+        rte_timer_init(&dpdk_timer[i]);
+
+    p_xran_dev_ctx->direct_pool   = socket_direct_pool;
+    p_xran_dev_ctx->indirect_pool = socket_indirect_pool;
 
-    for(i = 0; i < XRAN_MAX_SECTOR_NR;  i++ ){
-        unsigned n = snprintf(&p_xran_lib_ctx->ring_name[0][i][0], RTE_RING_NAMESIZE, "dl_sym_ring_%u", i);
-        p_xran_lib_ctx->dl_sym_idx_ring[i]   = rte_ring_create(&p_xran_lib_ctx->ring_name[0][i][0], XRAN_RING_SIZE,
-                                               rte_lcore_to_socket_id(lcore_id), RING_F_SP_ENQ | RING_F_SC_DEQ);
+    printf("Set debug stop %d, debug stop count %d\n", p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
+    timing_set_debug_stop(p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
+
+    for (uint32_t nCellIdx = 0; nCellIdx < XRAN_MAX_SECTOR_NR; nCellIdx++){
+        xran_fs_clear_slot_type(nCellIdx);
     }
 
+    *pXranLayerHandle = p_xran_dev_ctx;
 
-    lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
-    PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
+    return 0;
+}
 
-    /* Start packet processing thread */
-    if (rte_eal_remote_launch(ring_processing_thread, NULL, lcore_id))
-        rte_panic("ring_processing_thread() failed to start\n");
+int32_t xran_sector_get_instances (void * pDevHandle, uint16_t nNumInstances,
+               xran_cc_handle_t * pSectorInstanceHandles)
+{
+    xran_status_t nStatus = XRAN_STATUS_FAIL;
+    struct xran_device_ctx *pDev = (struct xran_device_ctx *)pDevHandle;
+    XranSectorHandleInfo *pCcHandle = NULL;
+    int32_t i = 0;
 
-    if(p_io_cfg->pkt_aux_core > 0){
-        lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
-        PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
+    /* Check for the Valid Parameters */
+    CHECK_NOT_NULL (pSectorInstanceHandles, XRAN_STATUS_INVALID_PARAM);
 
-        /* Start packet processing thread */
-        if (rte_eal_remote_launch(xran_packet_and_dpdk_timer_thread, NULL, lcore_id))
-            rte_panic("ring_processing_thread() failed to start\n");
+    if (!nNumInstances) {
+        print_dbg("Instance is not assigned for this function !!! \n");
+        return XRAN_STATUS_INVALID_PARAM;
     }
 
-    lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
-    PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
-
-    /* Start packet processing thread */
-    if (rte_eal_remote_launch(xran_timing_source_thread, xran_lib_get_ctx(), lcore_id))
-        rte_panic("thread_run() failed to start\n");
+    for (i = 0; i < nNumInstances; i++) {
 
-    printf("Set debug stop %d\n", p_xran_fh_init->debugStop);
-    timing_set_debug_stop(p_xran_fh_init->debugStop);
+        /* Allocate Memory for CC handles */
+        pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64);
 
-    memset(&DevHandle, 0, sizeof(XranLibHandleInfoStruct));
+        if(pCcHandle == NULL)
+            return XRAN_STATUS_RESOURCE;
 
-    *pHandle = &DevHandle;
+        memset (pCcHandle, 0, (sizeof (XranSectorHandleInfo)));
 
-    return 0;
-}
+        pCcHandle->nIndex    = i;
+        pCcHandle->nXranPort = pDev->xran_port_id;
 
-int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
-               XranCcInstanceHandleVoidP * pSectorInstanceHandles)
-{
-    int i;
+        printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, pDev->xran_port_id, i, pCcHandle);
+        pLibInstanceHandles[pDev->xran_port_id][i] = pSectorInstanceHandles[i] = pCcHandle;
 
-    /* only one handle as only one CC is currently supported */
-    for(i = 0; i < nNumInstances; i++ )
-        pSectorInstanceHandles[i] = pHandle;
+        printf("Handle: %p Instance: %p\n",
+            &pSectorInstanceHandles[i], pSectorInstanceHandles[i]);
+    }
 
-    return 0;
+    return XRAN_STATUS_SUCCESS;
 }
 
 int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
@@ -1057,66 +1906,109 @@ int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
 
 int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
 {
-    XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    uint32_t nAllocBufferSize;
 
     char pool_name[RTE_MEMPOOL_NAMESIZE];
 
-    snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "bm_mempool_%ld", pPoolIndex);
+    snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
+        pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
+
+    nAllocBufferSize = nBufferSize + sizeof(struct ether_hdr) +
+        sizeof (struct xran_ecpri_hdr) +
+        sizeof (struct radio_app_common_hdr) +
+        sizeof(struct data_section_hdr) + 256;
+
+
+    printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name,
+                        pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize);
 
-    pXran->p_bufferPool[pXran->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
-           MBUF_CACHE, 0, XRAN_MAX_MBUF_LEN, rte_socket_id());
+    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;
+    }
 
-    pXran->bufferPoolElmSz[pXran->nBufferPoolIndex]  = nBufferSize;
-    pXran->bufferPoolNumElm[pXran->nBufferPoolIndex] = nNumberOfBuffers;
+    pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex]  = nBufferSize;
+    pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
 
-    print_dbg("[nPoolIndex %d] mb pool %p \n", pXran->nBufferPoolIndex,  pXran->p_bufferPool[pXran->nBufferPoolIndex]);
+    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 = pXran->nBufferPoolIndex++;
+    *pPoolIndex = pXranCc->nBufferPoolIndex++;
 
     return 0;
 }
 
-int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr)
+int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData,  void **ppCtrl)
 {
-    XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
-    *ppVirtAddr = NULL;
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    *ppData = NULL;
+    *ppCtrl = NULL;
 
-    struct rte_mbuf * mb =  rte_pktmbuf_alloc(pXran->p_bufferPool[nPoolIndex]);
+    struct rte_mbuf * mb =  rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
 
     if(mb){
-        *ppVirtAddr = rte_pktmbuf_append(mb, pXran->bufferPoolElmSz[nPoolIndex]);
-
+        char * start     = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
+        char * ethhdr    = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
+
+        if(start && ethhdr){
+            char * iq_offset = rte_pktmbuf_mtod(mb, char * );
+            /* skip headers */
+            iq_offset = iq_offset + sizeof(struct 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 (*ppVirtAddr ==  NULL){
-        print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXran->bufferPoolElmSz[nPoolIndex]);
+    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 *pVirtAddr)
+int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
 {
-    XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
-    rte_pktmbuf_free(pVirtAddr);
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+
+    if(pCtrl)
+        rte_pktmbuf_free(pCtrl);
 
     return 0;
 }
 
 int32_t xran_5g_fronthault_config (void * pHandle,
-                XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XranTransportBlockCallbackFn pCallback,
+                struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                xran_transport_callback_fn pCallback,
                 void *pCallbackTag)
 {
-    XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
-    XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    xran_status_t nStatus = XRAN_STATUS_SUCCESS;
     int j, i = 0, z, k;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
     print_dbg("%s\n", __FUNCTION__);
 
@@ -1125,31 +2017,59 @@ int32_t xran_5g_fronthault_config (void * pHandle,
         printf("Handle is NULL!\n");
         return XRAN_STATUS_FAIL;
     }
+
     if (pCallback == NULL)
     {
         printf ("no callback\n");
         return XRAN_STATUS_FAIL;
     }
 
+    i = pXranCc->nIndex;
+
     for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
     {
         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulTxBuffers[j][i][z][0];
-
-           p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList =   *pSrcBuffer[z][j];
-
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulRxBuffers[j][i][z][0];
-           p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
+            /* U-plane TX */
+
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxBuffers[j][i][z][0];
+
+            p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList =   *pSrcBuffer[z][j];
+
+            /* C-plane TX */
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxPrbMapBuffers[j][i][z][0];
+
+            p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList =   *pSrcCpBuffer[z][j];
+
+            /* U-plane RX */
+
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxBuffers[j][i][z][0];
+
+            p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
+
+            /* C-plane RX */
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxPrbMapBuffers[j][i][z][0];
+
+            p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList =   *pDstCpBuffer[z][j];
         }
     }
 
@@ -1158,7 +2078,7 @@ int32_t xran_5g_fronthault_config (void * pHandle,
         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
             printf("TTI:TX 0x%02x Sec %d Ant%d\n",j,i,z);
             for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
-                uint8_t *ptr = p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
+                uint8_t *ptr = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
                 printf("    sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]);
             }
         }
@@ -1167,29 +2087,29 @@ int32_t xran_5g_fronthault_config (void * pHandle,
         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
             printf("TTI:RX 0x%02x Sec %d Ant%d\n",j,i,z);
             for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
-                uint8_t *ptr = p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
+                uint8_t *ptr = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
                 printf("    sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]);
             }
         }
 #endif
 
-    p_xran_lib_ctx->pCallback[i]    = pCallback;
-    p_xran_lib_ctx->pCallbackTag[i] = pCallbackTag;
+    p_xran_dev_ctx->pCallback[i]    = pCallback;
+    p_xran_dev_ctx->pCallbackTag[i] = pCallbackTag;
 
-    p_xran_lib_ctx->xran2phy_mem_ready = 1;
+    p_xran_dev_ctx->xran2phy_mem_ready = 1;
 
     return nStatus;
 }
 
 int32_t xran_5g_prach_req (void *  pHandle,
-                XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
-                XranTransportBlockCallbackFn pCallback,
+                struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+                xran_transport_callback_fn pCallback,
                 void *pCallbackTag)
 {
-    XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
-    XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
+    XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+    xran_status_t nStatus = XRAN_STATUS_SUCCESS;
     int j, i = 0, z;
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
     if(NULL == pHandle)
     {
@@ -1202,74 +2122,96 @@ int32_t xran_5g_prach_req (void *  pHandle,
         return XRAN_STATUS_FAIL;
     }
 
+    i = pXranCc->nIndex;
+
     for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
     {
         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFHPrachRxBuffers[j][i][z][0];
-           p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHPrachRxBuffers[j][i][z][0];
+           p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
         }
     }
 
-    p_xran_lib_ctx->pPrachCallback[i]    = pCallback;
-    p_xran_lib_ctx->pPrachCallbackTag[i] = pCallbackTag;
+    p_xran_dev_ctx->pPrachCallback[i]    = pCallback;
+    p_xran_dev_ctx->pPrachCallbackTag[i] = pCallbackTag;
 
     return 0;
 }
 
-int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
-                uint32_t nTxPhaseCps,
-                uint32_t nRxPhaseCps,
-                uint8_t nSectorId)
+int32_t xran_open(void *pHandle, struct xran_fh_config* pConf)
 {
-    /* functionality is not yet implemented */
-    return 0;
-}
+    int32_t i;
+    uint8_t nNumerology = 0;
+    int32_t  lcore_id = 0;
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+    struct xran_fh_config *pFhCfg;
+    pFhCfg = &(p_xran_dev_ctx->fh_cfg);
 
-int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf)
-{
-    int i;
-    uint8_t slotNr;
-    XRANFHCONFIG *pFhCfg;
-    xRANPrachCPConfigStruct *pPrachCPConfig = &(xran_lib_get_ctx()->PrachCPConfig);
-    pFhCfg = &(xran_lib_get_ctx()->xran_fh_cfg);
-    memcpy(pFhCfg, pConf, sizeof(XRANFHCONFIG));
-    PXRANPRACHCONFIG pPRACHConfig = &pFhCfg->prach_conf;
-    uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
-    const xRANPrachConfigTableStruct *pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
-    uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
-    const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt - FORMAT_A1];
-    memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct));
+    memcpy(pFhCfg, pConf, sizeof(struct xran_fh_config));
 
-    //setup PRACH configuration for C-Plane
-    pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC;         // 3, PRACH preamble format A1~3, B1~4, C0, C2
-    pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
-    pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
-    pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
-    pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
-    pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
-    pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
-    pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
-    pPrachCPConfig->x = pxRANPrachConfigTable->x;
-    pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
-    pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
+    nNumerology = xran_get_conf_numerology(pHandle);
 
-    pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
-    for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
+    if (pConf->nCC > XRAN_MAX_SECTOR_NR)
     {
-        slotNr = pxRANPrachConfigTable->slotNr[i];
-        if (slotNr > 0)
-            pPrachCPConfig->isPRACHslot[slotNr] = 1;
+        if(pConf->log_level)
+            printf("Number of cells %d exceeds max number supported %d!\n", pConf->nCC, XRAN_MAX_SECTOR_NR);
+        pConf->nCC = XRAN_MAX_SECTOR_NR;
+
+    }
+    if(pConf->ru_conf.iqOrder != XRAN_I_Q_ORDER
+        || pConf->ru_conf.byteOrder != XRAN_NE_BE_BYTE_ORDER ){
+
+        print_err("Byte order and/or IQ order is not suppirted [IQ %d byte %d]\n", pConf->ru_conf.iqOrder, pConf->ru_conf.byteOrder);
+        return XRAN_STATUS_FAIL;
     }
 
+    //setup PRACH configuration for C-Plane
+    xran_init_prach(pConf, p_xran_dev_ctx);
+
     xran_cp_init_sectiondb(pHandle);
     xran_init_sectionid(pHandle);
     xran_init_seqid(pHandle);
 
+    interval_us = xran_fs_get_tti_interval(nNumerology);
+
+    if(pConf->log_level){
+        printf("%s: interval_us=%ld\n", __FUNCTION__, interval_us);
+    }
+    timing_set_numerology(nNumerology);
+
+    for(i = 0 ; i <pConf->nCC; i++){
+        xran_fs_set_slot_type(i, pConf->frame_conf.nFrameDuplexType, pConf->frame_conf.nTddPeriod,
+            pConf->frame_conf.sSlotConfig);
+    }
+
+    xran_fs_slot_limit_init(xran_fs_get_tti_interval(nNumerology));
+
+    if(xran_ethdi_get_ctx()->io_cfg.bbdev_mode != XRAN_BBDEV_NOT_USED){
+        p_xran_dev_ctx->bbdev_dec = pConf->bbdev_dec;
+        p_xran_dev_ctx->bbdev_enc = pConf->bbdev_enc;
+    }
+
+    /* Start packet processing thread */
+    if((uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF] != 0xFFFF &&
+        (uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF] != 0xFFFF ){
+        if(pConf->log_level){
+            print_dbg("XRAN_UP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF]);
+            print_dbg("XRAN_CP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF]);
+        }
+        if (rte_eal_remote_launch(xran_timing_source_thread, xran_dev_get_ctx(), xran_ethdi_get_ctx()->io_cfg.timing_core))
+            rte_panic("thread_run() failed to start\n");
+    } else
+        if(pConf->log_level){
+            printf("Eth port was not open. Processing thread was not started\n");
+        }
+
+
+
     return 0;
 }
 
@@ -1288,8 +2230,10 @@ int32_t xran_stop(void *pHandle)
 int32_t xran_close(void *pHandle)
 {
     xran_if_current_state = XRAN_STOPPED;
-    xran_cp_free_sectiondb(pHandle);
-    rte_eal_mp_wait_lcore();
+    //TODO: fix memory leak xran_cp_free_sectiondb(pHandle);
+    //rte_eal_mp_wait_lcore();
+    //xran_ethdi_ports_stats();
+
     return 0;
 }
 
@@ -1299,19 +2243,19 @@ int32_t xran_mm_destroy (void * pHandle)
     return -1;
 }
 
-int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb,  uint8_t ant)
+int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb,  uint8_t ant)
 {
     /* functionality is not yet implemented */
     return -1;
 }
 
-int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
+int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
 {
-    struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+    struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
 
-    p_xran_lib_ctx->ttiCb[id]      = Cb;
-    p_xran_lib_ctx->TtiCbParam[id] = cbParam;
-    p_xran_lib_ctx->SkipTti[id]    = skipTtiNum;
+    p_xran_dev_ctx->ttiCb[id]      = Cb;
+    p_xran_dev_ctx->TtiCbParam[id] = cbParam;
+    p_xran_dev_ctx->SkipTti[id]    = skipTtiNum;
 
     return 0;
 }
@@ -1329,24 +2273,15 @@ int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx,  uint32_
     return tti;
 }
 
-/**
- * @brief Get supported maximum number of sections
- *
- * @return maximum number of sections
- */
-inline uint8_t xran_get_max_sections(void *pHandle)
-{
-    return (XRAN_MAX_NUM_SECTIONS);
-}
 
 /**
  * @brief Get the configuration of eAxC ID
  *
  * @return the pointer of configuration
  */
-inline XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle)
+inline struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle)
 {
-    return (&(xran_lib_get_ctx()->eAxc_id_cfg));
+    return (&(xran_dev_get_ctx()->eAxc_id_cfg));
 }
 
 /**
@@ -1372,7 +2307,7 @@ inline uint8_t xran_get_conf_fftsize(void *pHandle)
 /**
  * @brief Get the configuration of nummerology
  *
- * @return subcarrier spacing value for PRACH
+ * @return Configured numerology
  */
 inline uint8_t xran_get_conf_numerology(void *pHandle)
 {
@@ -1386,7 +2321,7 @@ inline uint8_t xran_get_conf_numerology(void *pHandle)
  */
 inline uint8_t xran_get_conf_iqwidth(void *pHandle)
 {
-  XRANFHCONFIG *pFhCfg;
+    struct xran_fh_config *pFhCfg;
 
     pFhCfg = xran_lib_get_ctx_fhcfg();
     return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth);
@@ -1402,30 +2337,11 @@ inline uint8_t xran_get_conf_compmethod(void *pHandle)
     return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth);
 }
 
-/**
- * @brief Get the configuration of lls-cu ID
- *
- * @return Configured lls-cu ID
- */
-inline uint8_t xran_get_llscuid(void *pHandle)
-{
-    return (xran_lib_get_ctx()->llscu_id);
-}
-
-/**
- * @brief Get the configuration of lls-cu ID
- *
- * @return Configured lls-cu ID
- */
-inline uint8_t xran_get_sectorid(void *pHandle)
-{
-    return (xran_lib_get_ctx()->sector_id);
-}
 
 /**
  * @brief Get the configuration of the number of component carriers
  *
- * @return Configured the number of componen carriers
+ * @return Configured the number of component carriers
  */
 inline uint8_t xran_get_num_cc(void *pHandle)
 {
@@ -1442,4 +2358,15 @@ inline uint8_t xran_get_num_eAxc(void *pHandle)
     return (xran_lib_get_ctx_fhcfg()->neAxc);
 }
 
+int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats)
+{
+    struct xran_device_ctx* pDev = (struct xran_device_ctx*)pXranLayerHandle;
+
+    if(pStats && pDev) {
+        *pStats  =  pDev->fh_counters;
+        return XRAN_STATUS_SUCCESS;
+    } else {
+        return XRAN_STATUS_INVALID_PARAM;
+    }
+}
 
index 6caee87..8649b01 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief Modules provide debug prints and utility functions
  * @file xran_printf.h
@@ -101,7 +100,16 @@ extern "C" {
 
 #endif /* _IASSERT_*/
 
-
+#ifdef CHECK_PARAMS
+#define CHECK_NOT_NULL(param, returnValue)      \
+if (param == NULL)                          \
+{                                           \
+    print_err("%s is NULL!\n", #param);   \
+    return returnValue;                     \
+}
+#else
+#define CHECK_NOT_NULL(param, returnValue)
+#endif
 
 #ifdef __cplusplus
 }
index e030a86..c45d83c 100644 (file)
@@ -15,7 +15,6 @@
 *   limitations under the License.
 *
 *******************************************************************************/
-
 /**
  * @brief This file provides implementation of synchronization related APIs (PTP/1588)
  *        for XRAN.
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <math.h>
 
 #include "xran_sync_api.h"
 #include "xran_printf.h"
@@ -67,30 +61,27 @@ static int is_process_running(char *pname)
     char full_path[BUF_LEN] = {0};
     char read_proc_name[BUF_LEN] = {0};
     int res = 1;
-    int null = 0;
-    int dir_fd = dirfd((DIR*)PROC_DIR);
-    DIR *dir = fdopendir(dir_fd);
+    DIR *dir = opendir(PROC_DIR);
     if (NULL == dir) {
         return 1;
     }
 
     struct dirent *entry = NULL;
-    while ((entry = readdir(dir))) {
+    while (entry = readdir(dir)) {
         long pid = atol(entry->d_name);
         if (0 == pid)
             continue;
-
-       snprintf(full_path, BUF_LEN,"%s/%ld/%s", PROC_DIR, pid, COMM_FILE);
-       int proc_name_file = open(full_path, O_RDONLY);
-        if (null == proc_name_file)
+        sprintf(full_path, "%s/%ld/%s", PROC_DIR, pid, COMM_FILE);
+        FILE *proc_name_file = fopen(full_path, "r");
+        if (NULL == proc_name_file)
             continue;
-        fgets( read_proc_name, BUF_LEN, (FILE*)proc_name_file);
+        fgets( read_proc_name, BUF_LEN, proc_name_file);
         if (0 == strncmp(read_proc_name, pname, strlen(pname))) {
             res = 0;
-           close(proc_name_file);
+            fclose(proc_name_file);
             break;
         }
-       close(proc_name_file);
+        fclose(proc_name_file);
     }
     closedir(dir);
     return res;
index 875b0b6..c77a39e 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides implementation to Timing for XRAN.
  *
 
 #include "xran_timer.h"
 #include "xran_printf.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_mlog_lnx.h"
 #include "xran_lib_mlog_tasks_id.h"
 #include "ethdi.h"
+#include "xran_fh_o_du.h"
+#include "xran_common.h"
 
 #define NSEC_PER_SEC  1000000000L
 #define NSEC_PER_USEC 1000L
 #define THRESHOLD        35  /**< the avg cost of clock_gettime() in ns */
 #define TIMECOMPENSATION 2   /**< time compensation in us, avg latency of clock_nanosleep */
 
-#define SEC_MOD_STOP (30)
+#define SEC_MOD_STOP (60)
 
 static struct timespec started_time;
 static struct timespec last_time;
@@ -59,20 +56,46 @@ static struct timespec* p_temp_time;
 
 static unsigned long current_second = 0;
 static unsigned long started_second = 0;
+static uint8_t numerlogy = 0;
 extern uint32_t xran_lib_ota_sym;
 extern uint32_t xran_lib_ota_tti;
 extern uint32_t xran_lib_ota_sym_idx;
 
 static int debugStop = 0;
+static int debugStopCount = 0;
+
+static long fine_tuning[5][2] =
+{
+    {71428L, 71429L},  /* mu = 0 */
+    {35714L, 35715L},  /* mu = 1 */
+    {0, 0},            /* mu = 2 not supported */
+    {8928L, 8929L},    /* mu = 3 */
+    {0,0  }            /* mu = 4 not supported */
+};
+
+static uint8_t slots_per_subframe[4] =
+{
+    1,  /* mu = 0 */
+    2,  /* mu = 1 */
+    4,  /* mu = 2 */
+    8,  /* mu = 3 */
+};
 
 uint64_t timing_get_current_second(void)
 {
     return current_second;
 }
 
-int timing_set_debug_stop(int value)
+int timing_set_numerology(uint8_t value)
+{
+    numerlogy = value;
+    return numerlogy;
+}
+
+int timing_set_debug_stop(int value, int count)
 {
     debugStop = value;
+    debugStopCount = count;
 
     if(debugStop){
         clock_gettime(CLOCK_REALTIME, &started_time);
@@ -107,6 +130,14 @@ long poll_next_tick(long interval_ns)
         clock_gettime(CLOCK_REALTIME, p_cur_time);
         delta = (p_cur_time->tv_sec * NSEC_PER_SEC + p_cur_time->tv_nsec) - target_time;
         if(delta > 0 || (delta < 0 && abs(delta) < THRESHOLD)) {
+            if (debugStop &&(debugStopCount > 0) && (tx_counter >= debugStopCount)){
+                uint64_t t1;
+                printf("STOP:[%ld.%09ld], debugStopCount %d, tx_counter %ld\n", p_cur_time->tv_sec, p_cur_time->tv_nsec, debugStopCount, tx_counter);
+                t1 = MLogTick();
+                rte_pause();
+                MLogTask(PID_TIME_SYSTIME_STOP, t1, MLogTick());
+                xran_if_current_state = XRAN_STOPPED;
+            }
             if(current_second != p_cur_time->tv_sec){
                 current_second = p_cur_time->tv_sec;
                 xran_lib_ota_sym_idx = 0;
@@ -127,12 +158,12 @@ long poll_next_tick(long interval_ns)
                 }
                 p_cur_time->tv_nsec = 0; // adjust to 1pps
             } else {
-                xran_lib_ota_sym_idx = XranIncrementSymIdx(xran_lib_ota_sym_idx, 14*8);
+                xran_lib_ota_sym_idx = XranIncrementSymIdx(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*slots_per_subframe[numerlogy]);
                 /* adjust to sym boundary */
                 if(sym_cnt & 1)
-                    sym_acc += 8928L;
+                    sym_acc +=  fine_tuning[numerlogy][0];
                 else
-                    sym_acc += 8929L;
+                    sym_acc +=  fine_tuning[numerlogy][1];
                 /* fine tune to second boundary */
                 if(sym_cnt % 13 == 0)
                     sym_acc += 1;
@@ -146,6 +177,11 @@ long poll_next_tick(long interval_ns)
             p_last_time = p_cur_time;
             p_cur_time  = p_temp_time;
             break;
+        } else {
+            if( likely(xran_if_current_state == XRAN_RUNNING)){
+                ring_processing_func();
+                process_dpdk_io();
+            }
         }
   }
 
index 9e1d192..325616b 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file provides the implementation for Transport lyaer (eCPRI) API.
  *
 #include <rte_common.h>
 #include <rte_config.h>
 
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
 #include "xran_common.h"
 #include "xran_transport.h"
+#include "xran_pkt_cp.h"
+#include "xran_cp_api.h"
 #include "xran_up_api.h"
+#include "xran_printf.h"
 
 
+/**
+ * @brief return eCPRI header size without eCPRI common header
+ *
+ * @ingroup xran
+ *
+ * @return the size of eCPRI header without common header
+ */
+int xran_get_ecpri_hdr_size(void)
+{
+    return(sizeof(struct xran_ecpri_hdr) - sizeof(struct xran_ecpri_cmn_hdr));
+}
+
 /**
  * @brief Compose ecpriRtcid/ecpriPcid
  *
+ * @ingroup xran
+ *
  * @param CU_Port_ID CU Port ID
  * @param BanbSector_ID Band Sector ID
  * @param CC_ID Component Carrier ID
  * @param Ant_ID RU Port ID (antenna ID)
  * @return uint16_t composed ecpriRtcid/ecpriPcid (network byte order)
  */
-inline uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)
+uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)
 {
   uint16_t cid;
-  XRANEAXCIDCONFIG *conf;
+  struct xran_eaxcid_config *conf;
 
     conf = xran_get_conf_eAxC(NULL);
 
@@ -64,13 +80,15 @@ inline uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint
 /**
  * @brief Decompose ecpriRtcid/ecpriPcid
  *
+ * @ingroup xran
+ *
  * @param cid composed ecpriRtcid/ecpriPcid (network byte order)
  * @param result the pointer of the structure to store decomposed values
  * @return none
  */
-inline void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
+void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
 {
-  XRANEAXCIDCONFIG *conf;
+  struct xran_eaxcid_config *conf;
 
     conf = xran_get_conf_eAxC(NULL);
     cid = rte_be_to_cpu_16(cid);
@@ -86,6 +104,8 @@ inline void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
 /**
  * @brief modify the payload size of eCPRI header in xRAN packet
  *
+ * @ingroup xran
+ *
  * @param mbuf Initialized rte_mbuf packet which has eCPRI header already
  * @param size payload size to be updated
  * @return none
@@ -96,6 +116,115 @@ inline void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size)
 
     ecpri_hdr = rte_pktmbuf_mtod(mbuf, struct xran_ecpri_hdr *);
 
-    ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(size);
+    ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(size);
+}
+
+
+/**
+ * @brief Build ECPRI header and returns added length
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ *  The pointer of the packet buffer to be parsed
+ * @param CC_ID
+ *  Component Carrier ID for this C-Plane message
+ * @param Ant_ID
+ *  Antenna ID(RU Port ID) for this C-Plane message
+ * @param seq_id
+ *  Sequence ID for this C-Plane message
+ * @param ecpri_hdr
+ *  The pointer to ECPRI header
+ * @return
+ *  added payload size on success
+ *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
+                        uint8_t CC_ID, uint8_t Ant_ID,
+                        uint8_t seq_id,
+                        struct xran_ecpri_hdr **ecpri_hdr)
+{
+  uint32_t payloadlen;
+  struct xran_ecpri_hdr *tmp;
+
+
+    tmp = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
+    if(unlikely(tmp == NULL)) {
+        print_err("Fail to allocate the space for eCPRI hedaer!");
+        return (XRAN_STATUS_RESOURCE);
+        }
+
+    /* Fill common header */
+    tmp->cmnhdr.ecpri_ver           = XRAN_ECPRI_VER;
+    tmp->cmnhdr.ecpri_resv          = 0;     // should be zero
+    tmp->cmnhdr.ecpri_concat        = 0;
+    tmp->cmnhdr.ecpri_mesg_type     = ECPRI_RT_CONTROL_DATA;
+    tmp->ecpri_xtc_id               = xran_compose_cid(0, 0, CC_ID, Ant_ID);
+
+    /* TODO: Transport layer fragmentation is not supported */
+    tmp->ecpri_seq_id.seq_id        = seq_id;
+    tmp->ecpri_seq_id.sub_seq_id    = 0;
+    tmp->ecpri_seq_id.e_bit         = 1;
+
+    /* Starts with eCPRI header size */
+    payloadlen = xran_get_ecpri_hdr_size();
+
+    *ecpri_hdr = tmp;
+
+    return (payloadlen);
+}
+
+/**
+ * @brief Parse ECPRI header
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ *  The pointer of the packet buffer to be parsed
+ * @param ecpri_hdr
+ *  The pointer to ECPRI header
+ * @param pkt_info
+ *  The pointer of sturcture to store the information from header
+ * @return
+ *  XRAN_STATUS_SUCCESS on success
+ *  XRAN_STATUS_INVALID_PACKET if failed to parse the packet
+ */
+int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
+                    struct xran_ecpri_hdr **ecpri_hdr,
+                    struct xran_recv_packet_info *pkt_info)
+{
+  int ret;
+
+
+    *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
+    if(*ecpri_hdr == NULL) {
+        print_err("Invalid packet - eCPRI hedaer!");
+        return (XRAN_STATUS_INVALID_PACKET);
+        }
+
+    /* Process eCPRI header */
+    ret = XRAN_STATUS_SUCCESS;
+    if((*ecpri_hdr)->cmnhdr.ecpri_ver != XRAN_ECPRI_VER) {
+        print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.ecpri_ver);
+        ret = XRAN_STATUS_INVALID_PACKET;
+        }
+    if((*ecpri_hdr)->cmnhdr.ecpri_resv != 0) {
+        print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.ecpri_resv);
+        ret = XRAN_STATUS_INVALID_PACKET;
+        }
+
+    if(pkt_info != NULL) {
+        /* store the information from header */
+        pkt_info->ecpri_version = (*ecpri_hdr)->cmnhdr.ecpri_ver;
+        pkt_info->msg_type      = (enum ecpri_msg_type)(*ecpri_hdr)->cmnhdr.ecpri_mesg_type;
+        pkt_info->payload_len   = rte_be_to_cpu_16((*ecpri_hdr)->cmnhdr.ecpri_payl_size);
+
+        pkt_info->seq_id        = (*ecpri_hdr)->ecpri_seq_id.seq_id;
+        pkt_info->subseq_id     = (*ecpri_hdr)->ecpri_seq_id.sub_seq_id;
+        pkt_info->ebit          = (*ecpri_hdr)->ecpri_seq_id.e_bit;
+        xran_decompose_cid((*ecpri_hdr)->ecpri_xtc_id, &(pkt_info->eaxc));
+        }
+
+    return (ret);
 }
 
index 99feefb..1af11c4 100644 (file)
@@ -16,7 +16,6 @@
 *
 *******************************************************************************/
 
-
 /**
  * @brief This file defines those table used in 5G NR spec.
  * @file xran_ul_tables.c
@@ -843,8 +842,12 @@ const xRANPrachConfigTableStruct gxranPrachDataTable_mmw[XRAN_PRACH_CONFIG_TABLE
     { 255, { FORMAT_A3, FORMAT_B3 }, 1, { 0 }, { 7, 15, 23, 31, 39 }, 5, 2, 1, 2, 6 },
 };
 
-const xRANPrachPreambleLRAStruct gxranPreambleforLRA[XRAN_PRACH_PREAMBLE_FORMAT_OF_ABC] =
+const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13] =
 {
+    {FORMAT_0, 839,  125, 1 , 3168 },
+    {FORMAT_1, 839,  125, 2 ,21024 },
+    {FORMAT_2, 839,  125, 4 , 4688 },
+    {FORMAT_3, 839,    5, 1 , 3168 },
     {FORMAT_A1, 139,  15, 2 ,  288 },
     {FORMAT_A2, 139,  15, 4 ,  576 },
     {FORMAT_A3, 139,  15, 6 ,  864 },
index a8c71f2..3fb5ba9 100644 (file)
  * @author Intel Corporation
  *
  **/
+#include <inttypes.h>
 
 #include <rte_memcpy.h>
-#include <inttypes.h>
-#include "xran_fh_lls_cu.h"
+#include <rte_mbuf.h>
+
+#include "xran_fh_o_du.h"
 #include "xran_transport.h"
 #include "xran_up_api.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_printf.h"
+#include "xran_mlog_lnx.h"
 
 extern uint32_t xran_lib_ota_tti;
 
-
 /**
  * @brief Builds eCPRI header in xRAN packet
  *
@@ -63,22 +61,24 @@ static int build_ecpri_hdr(struct rte_mbuf *mbuf,
     if (NULL == ecpri_hdr)
         return 1;
 
-    ecpri_hdr->ecpri_ver = XRAN_ECPRI_VER;
-    ecpri_hdr->ecpri_resv = 0;
-    ecpri_hdr->ecpri_concat = 0;
-    ecpri_hdr->ecpri_mesg_type = ECPRI_IQ_DATA;
+    ecpri_hdr->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
+    ecpri_hdr->cmnhdr.ecpri_resv = 0;
+    ecpri_hdr->cmnhdr.ecpri_concat = 0;
+    ecpri_hdr->cmnhdr.ecpri_mesg_type = ECPRI_IQ_DATA;
 
     if (iq_data_offset + iq_samples_bytes_in_mbuf > iq_data_num_bytes) {
-        ecpri_hdr->ecpri_payl_size =
+        ecpri_hdr->cmnhdr.ecpri_payl_size =
             rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
                 sizeof(struct data_section_hdr) +
-                (iq_data_num_bytes - iq_data_offset));
+                (iq_data_num_bytes - iq_data_offset) +
+                xran_get_ecpri_hdr_size());
         ecpri_hdr->ecpri_seq_id.e_bit = 1;  /* last segment */
     } else {
-        ecpri_hdr->ecpri_payl_size =
+        ecpri_hdr->cmnhdr.ecpri_payl_size =
             rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
                 sizeof(struct data_section_hdr) +
-                iq_samples_bytes_in_mbuf);
+                iq_samples_bytes_in_mbuf +
+                xran_get_ecpri_hdr_size());
         ecpri_hdr->ecpri_seq_id.e_bit = 0;
     }
 
@@ -108,18 +108,20 @@ static int xran_build_ecpri_hdr_ex(struct rte_mbuf *mbuf,
                               uint8_t Ant_ID,
                               uint8_t seq_id)
 {
-    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)
-        rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)(pChar + sizeof(struct ether_hdr));
 
     if (NULL == ecpri_hdr)
         return 1;
 
-    ecpri_hdr->ecpri_ver       = XRAN_ECPRI_VER;
-    ecpri_hdr->ecpri_resv      = 0;     // should be zero
-    ecpri_hdr->ecpri_concat    = 0;
-    ecpri_hdr->ecpri_mesg_type = ecpri_mesg_type;
-    ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(payl_size
-                            + sizeof(struct data_section_hdr)+sizeof(struct radio_app_common_hdr));
+    ecpri_hdr->cmnhdr.ecpri_ver       = XRAN_ECPRI_VER;
+    ecpri_hdr->cmnhdr.ecpri_resv      = 0;     // should be zero
+    ecpri_hdr->cmnhdr.ecpri_concat    = 0;
+    ecpri_hdr->cmnhdr.ecpri_mesg_type = ecpri_mesg_type;
+    ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payl_size
+                                    + sizeof(struct data_section_hdr)
+                                    + sizeof(struct radio_app_common_hdr)
+                                    + xran_get_ecpri_hdr_size());
 
     /* one to one lls-CU to RU only and band sector is the same */
     ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
@@ -146,8 +148,9 @@ static int build_application_layer(
     struct rte_mbuf *mbuf,
     const struct radio_app_common_hdr *app_hdr_input)
 {
-    struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)
-        rte_pktmbuf_append(mbuf, sizeof(struct radio_app_common_hdr));
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+    struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)(pChar + sizeof(struct ether_hdr)
+        + sizeof (struct xran_ecpri_hdr));
 
     if (NULL == app_hdr)
         return 1;
@@ -168,8 +171,9 @@ static int build_section_hdr(
     struct rte_mbuf *mbuf,
     const struct data_section_hdr *sec_hdr)
 {
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
     struct data_section_hdr *section_hdr = (struct data_section_hdr *)
-        rte_pktmbuf_append(mbuf, sizeof(struct data_section_hdr));
+        (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr));
 
     if (NULL == section_hdr)
         return 1;
@@ -190,37 +194,35 @@ static int build_section_hdr(
 static uint16_t append_iq_samples_ex(
     struct rte_mbuf *mbuf,
     const void *iq_data_start,
-    const uint32_t iq_data_num_bytes)
+    const uint32_t iq_data_num_bytes,
+    enum xran_input_byte_order iq_buf_byte_order,
+    uint32_t do_copy)
 {
-    uint16_t free_space_in_pkt = rte_pktmbuf_tailroom(mbuf);
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+    void *iq_sam_buf  = (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr)
+                        + sizeof(struct radio_app_common_hdr)
+                        + sizeof(struct data_section_hdr));
 
-    if(free_space_in_pkt >= iq_data_num_bytes){
-
-        void *iq_sam_buf = (void *)rte_pktmbuf_append(mbuf, iq_data_num_bytes);
-        if (iq_sam_buf == NULL)
-            return 0;
-#ifdef XRAN_BYTE_ORDER_SWAP
+    if (iq_sam_buf == NULL){
+        print_err("iq_sam_buf == NULL\n");
+        return 0;
+    }
+    if(iq_buf_byte_order == XRAN_CPU_LE_BYTE_ORDER){
         int idx = 0;
-        uint16_t *restrict psrc = (uint16_t *)iq_data_start;
-        uint16_t *restrict pdst = (uint16_t *)iq_sam_buf;
+        uint16_t *psrc = (uint16_t *)iq_data_start;
+        uint16_t *pdst = (uint16_t *)iq_sam_buf;
         /* CPU byte order (le) of IQ to network byte order (be) */
         for (idx = 0; idx < iq_data_num_bytes/sizeof(int16_t); idx++){
             pdst[idx]  =  (psrc[idx]>>8) | (psrc[idx]<<8); //rte_cpu_to_be_16(psrc[idx]);
         }
-#else
-#error xran spec is network byte order
-        /* for debug */
-        rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start,  iq_data_num_bytes);
-
-#endif
-
-        return iq_data_num_bytes;
+    }else if(iq_buf_byte_order == XRAN_NE_BE_BYTE_ORDER){
+        if(do_copy)
+           rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start,  iq_data_num_bytes);
     }
 
-    return 0;
+    return iq_data_num_bytes;
 }
 
-
 /**
  * @brief Function for appending IQ samples data to the mbuf.
  *
@@ -363,10 +365,17 @@ int xran_extract_iq_samples(struct rte_mbuf *mbuf,
     uint8_t *subframe_id,
     uint8_t *slot_id,
     uint8_t *symb_id,
-    struct ecpri_seq_id *seq_id)
+    struct ecpri_seq_id *seq_id,
+    uint16_t *num_prbu,
+    uint16_t *start_prbu,
+    uint16_t *sym_inc,
+    uint16_t *rb,
+    uint16_t *sect_id)
 {
+#if XRAN_MLOG_VAR
     uint32_t mlogVar[10];
     uint32_t mlogVarCnt = 0;
+#endif
     struct xran_eaxc_info result;
 
     if (NULL == mbuf)
@@ -408,11 +417,20 @@ int xran_extract_iq_samples(struct rte_mbuf *mbuf,
         *symb_id = radio_hdr->sf_slot_sym.symb_id;
 
     /* Process data section hdr */
-    const struct data_section_hdr *data_hdr =
+    struct data_section_hdr *data_hdr =
         (void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));
     if (data_hdr == NULL)
         return 0;       /* packet too short */
 
+    /* cpu byte order */
+    data_hdr->fields.all_bits  = rte_be_to_cpu_32(data_hdr->fields.all_bits);
+
+    *num_prbu   = data_hdr->fields.num_prbu;
+    *start_prbu = data_hdr->fields.start_prbu;
+    *sym_inc    = data_hdr->fields.sym_inc;
+    *rb         = data_hdr->fields.rb;
+    *sect_id    = data_hdr->fields.sect_id;
+
 #ifdef COMPRESSION
     const struct data_section_compression_hdr *data_compr_hdr =
         (void *) rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
@@ -428,14 +446,19 @@ int xran_extract_iq_samples(struct rte_mbuf *mbuf,
     if (*iq_data_start == NULL)
         return 0;
 
-    mlogVar[mlogVarCnt++] = 0xBBBBBBB;
+#if XRAN_MLOG_VAR
+    mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
     mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
     mlogVar[mlogVarCnt++] = radio_hdr->frame_id;
     mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.subframe_id;
     mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.slot_id;
     mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.symb_id;
+    mlogVar[mlogVarCnt++] = data_hdr->fields.sect_id;
+    mlogVar[mlogVarCnt++] = data_hdr->fields.start_prbu;
+    mlogVar[mlogVarCnt++] = data_hdr->fields.num_prbu;
     mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(mbuf);
     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
+#endif
 
     return rte_pktmbuf_pkt_len(mbuf);
 }
@@ -456,26 +479,34 @@ int xran_extract_iq_samples(struct rte_mbuf *mbuf,
 int xran_prepare_iq_symbol_portion_no_comp(
                         struct rte_mbuf *mbuf,
                         const void *iq_data_start,
+                        const enum xran_input_byte_order iq_buf_byte_order,
                         const uint32_t iq_data_num_bytes,
                         struct xran_up_pkt_gen_no_compression_params *params,
                         uint8_t CC_ID,
                         uint8_t Ant_ID,
-                        uint8_t seq_id)
+                        uint8_t seq_id,
+                        uint32_t do_copy)
 {
     if(xran_build_ecpri_hdr_ex(mbuf,
                            ECPRI_IQ_DATA,
                            iq_data_num_bytes,
                            CC_ID,
                            Ant_ID,
-                           seq_id))
+                           seq_id)){
+        print_err("xran_build_ecpri_hdr_ex return 0\n");
         return 0;
+    }
 
-    if (build_application_layer(mbuf, &(params->app_params)) != 0)
+    if (build_application_layer(mbuf, &(params->app_params)) != 0){
+        print_err("build_application_layer return != 0\n");
         return 0;
+    }
 
-    if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0)
+    if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0){
+        print_err("build_section_hdr return != 0\n");
         return 0;
+    }
 
-    return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes);
+    return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes, iq_buf_byte_order, do_copy);
 }
 
index 43f070c..3168b83 100644 (file)
 #*   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.
+#*   limitations under the  License.
 #*
 #*******************************************************************************/
 1. Introduction
 xRAN Lib performs communication between the low-layer split central unit (lls-CU) and RU, it is highly-optimized software implementation based on Intel Architecture to provide the standard interface implementation based on O-RAN front haul interface specification. 
 
 2. Supported features
-please refer PRD in the table <<xRAN release track table.xlsx>>, only ICC compiler was supported for this version.
+Please refer to the Document ORAN Front Haul Interface Library based on Intel's xRAN Front Haul SW Architecture Specifications Section 4.2 Supported Feature Set, both GCC/ICC compiler are supported for this version.
 
 3. Fixed Issues
 It's first version of seed code for feature development, future fixed issues will be tracked here.
 
 4. Known Issues
-From current unit testing coverage, no Know issues was founded yet.
+From current unit testing coverage, no issues have been found yet. 
 
 5. Prerequisites for install
 
-5.1 Intel Compiler version
+5.1. Prerequisites
+
+5.1.0 System configuration
+
+VFIO requires:
+linux:
+                IOMMU=ON
+BIOS:
+                Intel(R) Virtualization Technology Enabled
+                Intel(R) VT for Directed I/O - Enabled
+                ACS Control - Enabled
+                Coherency Support - Disabled
+5.1.1 Compiler
+
 icc -v
-icc version 18.0.1 (gcc version 4.8.5 compatibility)
+icc version 19.0.3.206 (gcc version 4.8.5 compatibility)
 
 Link to ICC (community free version):
 https://software.intel.com/en-us/system-studio/choose-download#technical
 
+5.1.2  DPDK 18.08
 
-5.2  DPDK version
-dpdk_18.08
-
-5.3   compile DPDK with command
-[dpdk]# ./usertools/dpdk-setup.sh
+5.1.3  Compile DPDK with
+[root@5gnr-sc12-xran dpdk]# ./usertools/dpdk-setup.sh    // Where the root@5gnr-sc12-xran dpdk corresponds to the location in the server for the dpdk installation folder
 
 select [16] x86_64-native-linuxapp-icc
-select [18] Insert IGB UIO module
+select [19] Insert VFIO module
 exit   [35] Exit Script
 
-5.4 Find PCIe device of Fortville port 
+5.1.4 Find PCIe device of Fortville port
 
 lspci |grep Eth
 19:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
@@ -57,42 +68,41 @@ lspci |grep Eth
 d8:00.0 << Ethernet controller: Intel Corporation Ethernet Controller XL710 for 40GbE QSFP+ (rev 02) <<<< this one
 d8:00.1 Ethernet controller: Intel Corporation Ethernet Controller XL710 for 40GbE QSFP+ (rev 02)
 
-5.5 Corresponding Eth device via
+5.1.5 Corresponding Eth device via
 
 ifconfig -a
 
 find port Eth with correct PCIe Bus address as per list above
 
-ethtool -i enp216s0f0
+ethtool -i enp218s0f0
 driver: i40e
-version: 2.4.10  << i40e driver
-firmware-version: 6.01 0x800034a4 1.1747.0
+version: 2.4.10 << driver
+firmware-version: 6.80 0x80003cfd 1.2007.0
 expansion-rom-version:
-bus-info: 0000:d8:00.0 <<< this one 
+bus-info: 0000:da:00.0 << this one
 supports-statistics: yes
 supports-test: yes
 supports-eeprom-access: yes
 supports-register-dump: yes
 supports-priv-flags: yes
 
-5.6 install correct 2.4.10 i40e version if different (https://downloadcenter.intel.com/download/28306/Intel-Network-Adapter-Driver-for-PCIe-40-Gigabit-Ethernet-Network-Connections-Under-Linux-)
+5.1.6 install correct 2.4.10 i40e version if different (https://downloadcenter.intel.com/download/28306/Intel-Network-Adapter-Driver-for-PCIe-40-Gigabit-Ethernet-Network-Connections-Under-Linux-)
 
-make sure firmare version is 
+make sure firmare version is at least this version or higher
 
-firmware-version: 6.01 
+firmware-version: 6.01
 
-5.7 make sure that linux boot arguments are correct 
+5.1.7 make sure that linux boot arguments are correct
 
 cat /proc/cmdline
-BOOT_IMAGE=/vmlinuz-3.10.0-rt56 root=/dev/mapper/centos_5gnr--skx--sp-root ro crashkernel=auto rd.lvm.lv=centos_5gnr-skx-sp/root rd.lvm.lv=centos_5gnr-skx-sp/swap intel_iommu=off usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 intel_pstate=disable cgroup_disable=memory mce=off idle=poll hugepagesz=1G hugepages=20 hugepagesz=2M hugepages=0 default_hugepagesz=1G isolcpus=1-35 rcu_nocbs=1-35 kthread_cpus=0 irqaffinity=0 nohz_full=1-35
-5.8 enable SRIOV VF port for XRAN 
+BOOT_IMAGE=/vmlinuz-3.10.0-rt56 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap intel_iommu=on iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 intel_pstate=disable cgroup_disable=memory mce=off idle=poll hugepagesz=1G hugepages=20 hugepagesz=2M hugepages=0 default_hugepagesz=1G isolcpus=1-39 rcu_nocbs=1-39 kthread_cpus=0 irqaffinity=0 nohz_full=1-39
+1.10 enable SRIOV VF port for XRAN
 
 echo 2 > /sys/class/net/enp216s0f0/device/sriov_numvfs
 
 see https://doc.dpdk.org/guides/nics/intel_vf.html
 
-5.9 Check Virtual Function was created 
+5.1.8 Check Virtual Function was created
 
 lspci |grep Eth
 19:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
@@ -104,7 +114,7 @@ d8:00.1 Ethernet controller: Intel Corporation Ethernet Controller XL710 for 40G
 d8:02.0 Ethernet controller: Intel Corporation XL710/X710 Virtual Function (rev 02) <<<< this is XRAN port (u-plane)
 d8:02.1 Ethernet controller: Intel Corporation XL710/X710 Virtual Function (rev 02) <<<< this is XRAN port (c-plane)
 
-5.10 Configure VFs
+5.1.9 Configure VFs
 - set mac to 00:11:22:33:44:66
 - set Vlan tag to 2 (U-plane) for VF0
 - set Vlan tag to 1 (C-plane) for VF1
@@ -136,32 +146,342 @@ d8:02.1 Ethernet controller: Intel Corporation XL710/X710 Virtual Function (rev
     link/ether 96:fa:4d:04:4d:87 brd ff:ff:ff:ff:ff:ff
 13: enp216s2f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000
     link/ether a6:67:49:bb:bd:5e brd ff:ff:ff:ff:ff:ff
-6. Install xRAN Lib 
-6.1 start matlab and run gen_test.m
-copy ant_*.bin  to /xran/app
-
-6.2 build xran sample application
-export XRAN_DIR=xRAN folder
-export RTE_SDK=dpdk folder
-[xRAN root folder]$ ./build.sh
 
-6.3 update Eth port used for XRAN
-in ./app/run_lls-cu.sh
-ports have to match VF function from step 1.11 (0000:d8:02.0 - U-plane  0000:d8:02.1 C-plane)
-
-6.4 Run dpdk.sh to assign port to PMD 
-
-[xran root folder]# ./app/dpdk.sh
+6. Install
+
+6.1.1 start matlab and run gen_test.m with correct Numerology, Bandwidth and number of slots
+copy ant_*.bin  to /xran/app/usecase/mu{X}_{Y}MHz
+       where X is numerology: 0,1,3
+             Y is 5,10,20,100 MHz bandwidth
+
+6.1.2 compile xran sample application (Please make sure that the export match your install directories for SDK, ORAN_FH_lib (i.e. XRAN_DIR), google test
+export RTE_SDK=/opt/dpdk-18.08
+export RTE_TARGET=x86_64-native-linuxapp-icc
+export XRAN_DIR= /home/npg_wireless-flexran_xran/
+export export GTEST_ROOT=/opt/gtest/gtest-1.7.0 
+
+ ./build.sh
+Number of commandline arguments: 0
+Building xRAN Library
+LIBXRANSO=0
+  CC ../lib/ethernet/ethdi.o
+  CC ../lib/ethernet/ethernet.o
+  CC ../lib/src/xran_up_api.o
+  CC ../lib/src/xran_sync_api.o
+  CC ../lib/src/xran_timer.o
+  CC ../lib/src/xran_cp_api.o
+  CC ../lib/src/xran_transport.o
+  CC ../lib/src/xran_common.o
+  CC ../lib/src/xran_ul_tables.o
+  CC ../lib/src/xran_frame_struct.o
+  CC ../lib/src/xran_compression.o
+  CC ../lib/src/xran_app_frag.o
+  CC ../lib/src/xran_main.o
+  AR libxran.a
+  INSTALL-LIB libxran.a
+Building xRAN Test Application
+  CC ../app/src/common.o
+  CC ../app/src/sample-app.o
+remark #11074: Inlining inhibited by limit max-size
+remark #11076: To get full report use -qopt-report=4 -qopt-report-phase ipo
+  CC ../app/src/config.o
+  LD sample-app
+  INSTALL-APP sample-app
+  INSTALL-MAP sample-app.map
+
+
+6.1.3 update Eth port used for XRAN
+
+
+cat ./run_o_du.sh
+#! /bin/bash
+
+ulimit -c unlimited
+echo 1 > /proc/sys/kernel/core_uses_pid
+
+grep Huge /proc/meminfo
+huge_folder="/mnt/huge_bbu"
+[ -d "$huge_folder" ] || mkdir -p $huge_folder
+if ! mount | grep $huge_folder; then
+ mount none $huge_folder -t hugetlbfs -o rw,mode=0777
+fi
+
+#40G
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat  0000:da:02.0 0000:da:02.1
+                                                              ^^^^^ ports have to match VF function from step 1.11 (0000:da:02.0 - U-plane  0000:da:02.1 C-plane)
+
+umount $huge_folder
+rmdir $huge_folder
+
+
+cat ./dpdk.sh
+...
+$RTE_SDK/usertools/dpdk-devbind.py --status
+if [ ${VM_DETECT} == 'HOST' ]; then
+    #HOST
+
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.0 <<< port has to match VF function from step 1.11
+    $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.1 <<< port has to match VF function from step 1.11
+
+       1.
+Run
+
+6.2.1 Run dpdk.sh to assign port to PMD
+
+[root@5gnr-sc12-xran app]# ./dpdk.sh
 
 Network devices using DPDK-compatible driver
 ============================================
-0000:d8:02.0 'XL710/X710 Virtual Function 154c' drv=igb_uio unused=i40evf
-0000:d8:02.1 'XL710/X710 Virtual Function 154c' drv=igb_uio unused=i40evf
-
-
-6.5 Run XRAN lls-CU sample app 
-setup RU mac address in config_file_lls_cu.dat
-[xran root folder]# ./app/run_lls-cu.sh
-
+0000:da:02.0 'XL710/X710 Virtual Function 154c' drv=vfio-pci unused=i40evf,igb_uio
+0000:da:02.1 'XL710/X710 Virtual Function 154c' drv=vfio-pci unused=i40evf,igb_uio
+
+
+6.2.2 Run XRAN sample app
+setup RU mac address in config_file_o_du.dat for corespondig usecase
+
+e.g.
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat  0000:da:02.0 0000:da:02.1
+
+ruMac=00:11:22:33:44:55  #RU VF for RU
+
+execute O-DU sample app
+
+[root@sc12-xran-ru-1 app]# ./run_o_du.sh
+HugePages_Total:      20
+HugePages_Free:       11
+HugePages_Rsvd:        0
+HugePages_Surp:        0
+Hugepagesize:    1048576 kB
+Machine is synchronized using PTP!
+mu_number: 3
+nDLAbsFrePointA: 27968160
+nULAbsFrePointA: 27968160
+nDLBandwidth: 100
+nULBandwidth: 100
+nULFftSize: 1024
+nULFftSize: 1024
+nFrameDuplexType: 1
+nTddPeriod: 4
+sSlotConfig0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig3: 0 2 2 1 1 1 1 1 1 1 1 1 1 1
+mtu 9600
+lls-CU MAC address: 00:11:22:33:44:66
+RU MAC address: 00:11:22:33:44:55
+numSlots: 40
+antC0: ./usecase/mu3_100mhz/ant_0.bin
+antC1: ./usecase/mu3_100mhz/ant_1.bin
+antC2: ./usecase/mu3_100mhz/ant_2.bin
+antC3: ./usecase/mu3_100mhz/ant_3.bin
+antC4: ./usecase/mu3_100mhz/ant_4.bin
+antC5: ./usecase/mu3_100mhz/ant_5.bin
+antC6: ./usecase/mu3_100mhz/ant_6.bin
+antC7: ./usecase/mu3_100mhz/ant_7.bin
+antC8: ./usecase/mu3_100mhz/ant_8.bin
+antC9: ./usecase/mu3_100mhz/ant_9.bin
+antC10: ./usecase/mu3_100mhz/ant_10.bin
+antC11: ./usecase/mu3_100mhz/ant_11.bin
+antC12: ./usecase/mu3_100mhz/ant_12.bin
+antC13: ./usecase/mu3_100mhz/ant_13.bin
+antC14: ./usecase/mu3_100mhz/ant_14.bin
+antC15: ./usecase/mu3_100mhz/ant_15.bin
+Prach enable: 0
+Prach config index: 81
+debugStop: 1
+CPenable: 1
+cp_vlan_tag: 1
+up_vlan_tag: 2
+Tadv_cp_dl: 25
+T2a_min_cp_dl: 50
+T2a_max_cp_dl: 140
+T2a_min_cp_ul: 50
+T2a_max_cp_ul: 140
+T2a_min_up: 25
+T2a_max_up: 140
+Ta3_min: 20
+Ta3_max: 32
+T1a_min_cp_dl: 70
+T1a_max_cp_dl: 100
+T1a_min_cp_ul: 60
+T1a_max_cp_ul: 70
+T1a_min_up: 35
+T1a_max_up: 50
+Ta4_min: 0
+Ta4_max: 45
+115 lines of config file has been read.
+numCCPorts 1 num_eAxc4
+set O-DU
+IQ files size is 40 slots
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+Loading file ./usecase/mu3_100mhz/ant_0.bin to  DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62ad088010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_1.bin to  DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62aced6010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_2.bin to  DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62acd24010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_3.bin to  DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62acb72010) size (1774080) bytes num (1774080)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant0.txt: from addr (0x7f62ad088010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant0.bin: from addr (0x7f62ad088010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant1.txt: from addr (0x7f62aced6010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant1.bin: from addr (0x7f62aced6010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant2.txt: from addr (0x7f62acd24010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant2.bin: from addr (0x7f62acd24010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant3.txt: from addr (0x7f62acb72010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant3.bin: from addr (0x7f62acb72010) size (887040) bytes num (887040)
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [0]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [1]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [2]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [3]
+System clock (rdtsc) resolution 1596250371 [Hz]
+Ticks per us 1596
+ xran_init: MTU 9600
+xran_ethdi_init_dpdk_io: Calling rte_eal_init:wls -c ffffffff -m5120 --proc-type=auto --file-prefix wls -w 0000:00:00.0
+EAL: Detected 40 lcore(s)
+EAL: Detected 2 NUMA nodes
+EAL: Auto-detected process type: PRIMARY
+EAL: Multi-process socket /var/run/dpdk/wls/mp_socket
+EAL: No free hugepages reported in hugepages-2048kB
+EAL: Probing VFIO support...
+EAL: VFIO support initialized
+EAL: PCI device 0000:da:02.0 on NUMA socket 1
+EAL:   probe driver: 8086:154c net_i40e_vf
+EAL:   using IOMMU type 1 (Type 1)
+initializing port 0 for TX, drv=net_i40e_vf
+Port 0 MAC: 00 11 22 33 44 66
+
+Checking link status ... done
+Port 0 Link Up - speed 40000 Mbps - full-duplex
+EAL: PCI device 0000:da:02.1 on NUMA socket 1
+EAL:   probe driver: 8086:154c net_i40e_vf
+initializing port 1 for TX, drv=net_i40e_vf
+Port 1 MAC: 00 11 22 33 44 66
+
+Checking link status ... done
+Port 1 Link Up - speed 40000 Mbps - full-duplex
+Set debug stop 1
+FFT Order 10
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_cal_nrarfcn: nCenterFreq[28015680] nDeltaFglobal[60] nFoffs[24250080] nNoffs[2016667] nNRARFCN[2079427]
+DL center freq 28015680 DL NR-ARFCN  2079427
+app_xran_cal_nrarfcn: nCenterFreq[28015680] nDeltaFglobal[60] nFoffs[24250080] nNoffs[2016667] nNRARFCN[2079427]
+UL center freq 28015680 UL NR-ARFCN  2079427
+XRAN front haul xran_mm_init
+xran_sector_get_instances [0]: CC 0 handle 0xd013380
+Handle: 0x5a07cb8 Instance: 0xd013380
+init_xran [0]: CC 0 handle 0xd013380
+Sucess xran_mm_init
+nSectorNum 1
+nSectorIndex[0] = 0
+[ handle 0xd013380 0 0 ] [nPoolIndex 0] nNumberOfBuffers 4480 nBufferSize 3328
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 0] mb pool 0x24a7ad440
+nSectorIndex[0] = 0
+[ handle 0xd013380 0 0 ] [nPoolIndex 1] nNumberOfBuffers 4480 nBufferSize 2216
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 1] mb pool 0x24956d100
+[ handle 0xd013380 0 0 ] [nPoolIndex 2] nNumberOfBuffers 4480 nBufferSize 3328
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 2] mb pool 0x248818dc0
+[ handle 0xd013380 0 0 ] [nPoolIndex 3] nNumberOfBuffers 4480 nBufferSize 2216
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 3] mb pool 0x2475d8a80
+[ handle 0xd013380 0 0 ] [nPoolIndex 4] nNumberOfBuffers 4480 nBufferSize 8192
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 4] mb pool 0x246884740
+@@@ NB cell 0 DL NR-ARFCN  0,DL phase comp flag 0 UL NR-ARFCN  0,UL phase comp flag 0
+init_xran_iq_content
+xRAN open PRACH config: Numerology 3 ConfIdx 81, preambleFmrt 6 startsymb 7, numSymbol 6, occassionsInPrachSlot 1
+PRACH: x 1 y[0] 0, y[1] 0 prach slot: 3.. 5 .... 7 .... 9 .... 11 .... 13 ..
+
+PRACH start symbol 7 lastsymbol 12
+xran_cp_init_sectiondb:Allocation Size for Section DB : 128 (1x8x16)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for Section DB : 128 (1x8x16)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_open: interval_us=125
+nSlotNum[0] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+            numDlSlots[1] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[1] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+            numDlSlots[2] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[2] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+            numDlSlots[3] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[3] : numDlSym[1] numGuardSym[2] numUlSym[11] XRAN_SLOT_TYPE_SP
+            numDlSlots[3] numUlSlots[0] numSpSlots[1] numSpDlSlots[1] numSpUlSlots[1]
+xran_fs_set_slot_type: nPhyInstanceId[0] nFrameDuplexType[1], nTddPeriod[4]
+DLRate[1.000000] ULRate[0.250000]
+SlotPattern:
+Slot:   0    1    2    3
+    0   DL   DL   DL   SP
+
+xran_timing_source_thread [CPU  7] [PID: 292331]
+MLogOpen: filename(mlog-o-du.bin) mlogSubframes (0), mlogCores(32), mlogSize(0) mlog_mask (-1)
+    mlogSubframes (256), mlogCores(32), mlogSize(7168)
+    localMLogTimerInit
+lls-CU: thread_run start time: 06/10/19 21:09:37.000000028 UTC [125]
+Start C-plane DL 25 us after TTI  [trigger on sym 3]
+Start C-plane UL 55 us after TTI  [trigger on sym 7]
+Start U-plane DL 50 us before OTA [offset  in sym -6]
+Start U-plane UL 45 us OTA        [offset  in sym 6]
+C-plane to U-plane delay 25 us after TTI
+Start Sym timer 8928 ns
+interval_us 125
+        System clock (CLOCK_REALTIME)  resolution 1000037471 [Hz]
+        Ticks per us 1000
+    MLog Storage: 0x7f6298487100 -> 0x7f629bc88d20 [ 58727456 bytes ]
+    localMLogFreqReg: 1000. Storing: 1000
+    Mlog Open successful
+
+----------------------------------------
+MLog Info: virt=0x00007f6298487100 size=58727456
+----------------------------------------
+Start XRAN traffic
++---------------------------------------+
+| Press 1 to start 5G NR XRAN traffic   |
+| Press 2 reserved for future use       |
+| Press 3 to quit                       |
++---------------------------------------+
+rx_counter 0 tx_counter 1376072
+rx_counter 0 tx_counter 1720112
+rx_counter 0 tx_counter 2064161
+rx_counter 0 tx_counter 2408212
+rx_counter 0 tx_counter 2752232
+
+type 3 to stop
+3
+rx_counter 0 tx_counter 3096264
+Stop XRAN traffic
+get_xran_iq_content
+Closing timing source thread...
+Closing l1 app... Ending all threads...
+MLogPrint: ext_filename((null).bin)
+    Opening MLog File: mlog-o-du-c0.bin
+    MLog file mlog-o-du-c0.bin closed
+    Mlog Print successful
+
+Failed at  xran_mm_destroy, status -2
+Dump IQs...
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [0]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [1]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [2]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [3]
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant0.txt: from addr (0x7f62ac9c0010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant0.bin: from addr (0x7f62ac9c0010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant1.txt: from addr (0x7f62ac80e010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant1.bin: from addr (0x7f62ac80e010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant2.txt: from addr (0x7f62ac65c010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant2.bin: from addr (0x7f62ac65c010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant3.txt: from addr (0x7f62ac4aa010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant3.bin: from addr (0x7f62ac4aa010) size (887040) bytes num (887040)