Commit 9965acda authored by Hongzhi Wang's avatar Hongzhi Wang Committed by Robert Schmidt

Add O-RAN 7.2 FHI library and documentation

- Add the O-RAN 7.2 FHI library, interfacing with OSC xRAN library
- Add documentation and patches necessary to make it run
- Add some sample config files

This is a squashed commit. It was made with the contributions of:
- Manish Kumar Singh <manish1.kumar@amd.com>
- thamizhselvan.k <thamizhselvan.k@vvdntech.in>
- rajeshwari.p <rajeshwari.p@vvdntech.in>
- Raymond Knopp <raymond.knopp@eurecom.fr>
- Sagar Arora <sagar.arora@openairinterface.org>
- Sofia Pison <Sofia.Pison@eurecom.fr>
- Ting-An Lin <lingwanjae@gmail.com>
parent 96ab8b99
......@@ -64,6 +64,21 @@ check_option(${ASN1C_EXEC} -no-gen-JER ASN1C_EXEC)
check_option(${ASN1C_EXEC} -no-gen-BER ASN1C_EXEC)
check_option(${ASN1C_EXEC} -no-gen-OER ASN1C_EXEC)
add_list2_option(TP_PROTO "None" "Ethernet" "benetel4g" "benetel5g" "oran_fhlib_5g")
if (${TP_PROTO} STREQUAL "oran_fhlib_5g")
if(DEFINED ENV{RTE_SDK})
message("RTE_SDK $ENV{RTE_SDK}")
else()
message(FATAL_ERROR "RTE_SDK Not defined")
endif()
if(DEFINED ENV{RTE_TARGET})
message("RTE_TARGET $ENV{RTE_TARGET}")
else()
message(FATAL_ERROR "RTE_TARGET is NOT defined")
endif()
endif()
#uhd 4.0 and iris installs by default in /usr/local
include_directories("/usr/local/include/")
#use native cmake method as this package is not in pkg-config
......@@ -149,7 +164,20 @@ set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
set (OPENAIR_CMAKE ${OPENAIR_DIR}/cmake_targets)
set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
set (INTEL_LIB /usr/local/intel64)
set (DPDK_DIR $ENV{RTE_SDK}/$ENV{RTE_TARGET}/include)
if(DEFINED ENV{XRAN_LIB_DIR})
set (XRAN_LIB_DIR $ENV{XRAN_LIB_DIR})
else()
set (XRAN_LIB_DIR /usr/local/xran)
endif()
set (XRAN_DIR $ENV{XRAN_LIB_DIR}/../src)
set (XRAN_COMMON_DIR $ENV{XRAN_LIB_DIR}/../../test/common)
set (XRAN_LIB_API_DIR $ENV{XRAN_LIB_DIR}/../api)
Message("XRAN_LIB_DIR: ${XRAN_LIB_DIR}, DPDK_DIR: ${DPDK_DIR}")
project (OpenAirInterface)
####################################################
......@@ -602,6 +630,30 @@ SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive
target_link_libraries(benetel_5g PRIVATE ${DPDK_LIBS})
target_link_libraries(benetel_5g PRIVATE pthread dl rt m numa)
# ORAN 5G library
######################################################################
set(ORAN_FHLIB_5G_SOURCE
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/oran.cpp
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/xran_lib_wrap.cpp
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/oran_isolate.c
)
add_library(oran_fhlib_5g MODULE ${ORAN_FHLIB_5G_SOURCE})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${DPDK_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${INTEL_LIB})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_COMMON_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_LIB_API_DIR})
set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include")
SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive")
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE ${DPDK_LIBS})
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE -L${XRAN_LIB_DIR} -lxran)
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE pthread dl rt m numa)
target_link_libraries(oran_fhlib_5g PRIVATE asn1_nr_rrc asn1_lte_rrc)
##########################################################
# LDPC offload library
......
......@@ -109,7 +109,7 @@ Options:
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
-S | --core_simulators
......@@ -295,6 +295,8 @@ function main() {
shift 2;;
-t | --transport)
TP=$2
echo_info "TP set to ${TP}"
CMAKE_CMD="$CMAKE_CMD -DTP_PROTO=$2"
shift 2;;
-P | --phy_simulators)
SIMUS_PHY=1
......@@ -479,7 +481,7 @@ function main() {
if [ ! -v BUILD_UHD_FROM_SOURCE ] && [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then
install_usrp_uhd_driver $UHD_IMAGES_DIR
fi
fi
fi
if [ "$HW" == "OAI_BLADERF" ] ; then
echo_info "installing packages for BLADERF support"
check_install_bladerf_driver
......@@ -627,7 +629,12 @@ function main() {
compilations $BUILD_DIR benetel_5g.txt benetel_5g
ln -sf libbenetel_5g.so liboai_transpro.so
echo_info "liboai_transpro.so is linked to BENETEL4G transport"
fi
fi
if [ "$TP" == "oran_fhlib_5g" ]; then
compilations $BUILD_DIR oran_fhlib_5g.txt oran_fhlib_5g
ln -sf liboran_fhlib_5g.so liboai_transpro.so
echo_info "liboai_transpro.so is linked to oran_fhlib_5G transport"
fi
fi
fi
......
From d1ad2907b3c3572de193ae770912436fb0a96443 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 16:18:08 +0530
Subject: [PATCH 2/2] disable dedicated bandwidth config for Amarisoft UE
simbox
---
openair2/RRC/NR/MESSAGES/asn1_msg.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index e52e637dd8..f15735b36f 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1213,10 +1213,8 @@ void fill_initial_cellGroupConfig(int uid,
physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook = NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic;
cellGroupConfig->physicalCellGroupConfig = physicalCellGroupConfig;
- cellGroupConfig->spCellConfig = calloc(1,sizeof(*cellGroupConfig->spCellConfig));
+ cellGroupConfig->spCellConfig = NULL;
- fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,servingcellconfigdedicated,configuration);
-
cellGroupConfig->sCellToAddModList = NULL;
cellGroupConfig->sCellToReleaseList = NULL;
}
--
2.25.1
From a7f20ad7c4ada7d50f21c5a8f15b1baab37481fa Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:42:36 +0530
Subject: [PATCH 1/4] compile libxran using-gcc and disable avx512
---
fhi_lib/build.sh | 7 ++++---
fhi_lib/lib/Makefile | 23 ++++++++++++-----------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/fhi_lib/build.sh b/fhi_lib/build.sh
index 22859b5..575bcc5 100755
--- a/fhi_lib/build.sh
+++ b/fhi_lib/build.sh
@@ -70,11 +70,12 @@ echo "LIBXRANSO = ${LIBXRANSO}"
echo "MLOG = ${MLOG}"
cd $XRAN_FH_LIB_DIR
+make clean
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
+#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
diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile
index 579a0c6..de5309d 100644
--- a/fhi_lib/lib/Makefile
+++ b/fhi_lib/lib/Makefile
@@ -23,11 +23,11 @@ MYCUSTOMSPACE1='------------------------------------------------------------'
##############################################################
# Tools configuration
##############################################################
-CC := icc
-CPP := icpc
+CC := gcc
+#CPP := icpc
AS := as
AR := ar
-LD := icc
+LD := gcc
OBJDUMP := objdump
ifeq ($(SHELL),cmd.exe)
@@ -95,9 +95,10 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
-fPIC \
-Wall \
-Wimplicit-function-declaration \
- -g -O3 -wd1786
+ -g -O0 -mssse3 \
+ -march=native
-CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+#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 -fPIC \
-no-prec-sqrt -falign-functions=16 -fast-transcendentals \
-Werror -Wno-unused-variable -std=c++11 -mcmodel=large
@@ -121,14 +122,14 @@ 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)
+OBJS := $(CC_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))
-CPP_COMP := -O3 -xcore-avx512 -restrict -g -fasm-blocks
+CPP_COMP := -O3 -xcore-avx512 -restrict -g
CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF)
CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF)
@@ -160,7 +161,7 @@ $(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)
+generate_deps : clear_dep $(CC_DEPS)
.PHONY : echo_start_build
@@ -211,10 +212,10 @@ welcome_line :
debug : all
release : all
-$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(AS_OBJTARGETS)
@echo [AR] $(subst $(BUILDDIR)/,,$@)
ifeq ($(XRAN_LIB_SO),)
- @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+ @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(AS_OBJTARGETS)
else
- @$(CC) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS) -shared -fPIC -o $@
+ @$(CC) $(CC_OBJTARGETS) $(AS_OBJTARGETS) -shared -fPIC -o $@
endif
--
2.25.1
From f26a9e9a3b902d56fffcb40644fa7d3e17d793f9 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:43:50 +0530
Subject: [PATCH 2/4] return correct slot_id
---
fhi_lib/lib/src/xran_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 17acc2a..8f5705e 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -609,6 +609,7 @@ static inline int8_t xran_check_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t
uint32_t xran_slotid_convert(uint16_t slot_id, uint16_t dir) //dir = 0, from PHY slotid to xran spec slotid as defined in 5.3.2, dir=1, from xran slotid to phy slotid
{
+ return slot_id;
#ifdef FCN_ADAPT
return slot_id;
#endif
--
2.25.1
From 3055c4a6cdb3ffa91deb4c6c11ecad0c95fef759 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:46:02 +0530
Subject: [PATCH 3/4] disable pkt validate at process_mbuf
---
fhi_lib/lib/src/xran_common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index c4cb3fb..5bbacf7 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -192,6 +192,7 @@ int process_mbuf(struct rte_mbuf *pkt)
return MBUF_FREE;
}
+#if 0
valid_res = xran_pkt_validate(NULL,
pkt,
iq_samp_buf,
@@ -213,6 +214,7 @@ int process_mbuf(struct rte_mbuf *pkt)
print_dbg("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;
}
+#endif
if (Ant_ID >= p_x_ctx->srs_cfg.eAxC_offset && p_x_ctx->fh_init.srsEnable) {
/* SRS packet has ruportid = 2*num_eAxc + ant_id */
--
2.25.1
From 5c99462d138042f99b3a02cec013f75bbc3732a9 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:48:25 +0530
Subject: [PATCH 4/4] process all rx ring
---
fhi_lib/lib/src/xran_common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index 5bbacf7..eaefe45 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -737,8 +737,8 @@ int32_t ring_processing_func(void)
/* UP first */
for (i = 0; i < ctx->io_cfg.num_vfs && i < (XRAN_VF_MAX - 1); i = i+2){
- if (process_ring(ctx->rx_ring[i]))
- return 0;
+ process_ring(ctx->rx_ring[i]);
+ process_ring(ctx->rx_ring[i+1]);
/* CP next */
if(ctx->io_cfg.id == O_RU) /* process CP only on O-RU */
--
2.25.1
diff --git a/fhi_lib/test/common/common_typedef_xran.h b/fhi_lib/test/common/common_typedef_xran.h
index 9e84bd3..65621f5 100644
--- a/fhi_lib/test/common/common_typedef_xran.h
+++ b/fhi_lib/test/common/common_typedef_xran.h
@@ -88,7 +88,7 @@ typedef enum{
CPU_GENERIC, /*!< C */
SSE4_2, /*!< SSE4_2 */
AVX, /*!< AVX */
- AVX2, /*!< AVX2 */
+ AVX_2, /*!< AVX2 */
AVX_512, /*!< AVX512 */
}instruction_cpu_support;
diff --git a/fhi_lib/test/common/common.hpp b/fhi_lib/test/common/common.hpp
index 9b01b06..64a1baf 100644
--- a/fhi_lib/test/common/common.hpp
+++ b/fhi_lib/test/common/common.hpp
@@ -31,7 +31,7 @@
#include <rte_malloc.h>
#endif
-#include "gtest/gtest.h"
+//#include "gtest/gtest.h"
#include "common_typedef_xran.h"
@@ -106,7 +106,7 @@ json read_json_from_file(const std::string &filename);
\return Pointer to the allocated memory with data from the file.
\throws std::runtime_error when memory cannot be allocated.
*/
-char* read_data_to_aligned_array(const std::string &filename);
+//char* read_data_to_aligned_array(const std::string &filename);
/*!
\brief Measure the TSC on the machine
@@ -140,6 +140,7 @@ unsigned long tsc_tick();
values, e.g. 1, 0.001, 5e-05, etc. or filename. Depends on the get type test framework can either
read the value or load data from the file - and it happens automatically (*pff* MAGIC!).
*/
+#if 0
class KernelTests : public testing::TestWithParam<unsigned>
{
public:
@@ -827,5 +828,6 @@ T* generate_random_real_numbers(const long size, const unsigned alignment, const
return generate_random_numbers<T, std::uniform_real_distribution<T>>(size, alignment, distribution);
}
+#endif
#endif //XRANLIB_COMMON_HPP
diff --git a/fhi_lib/lib/src/xran_common.h b/fhi_lib/lib/src/xran_common.h
index 4f2928d..5028376 100644
--- a/fhi_lib/lib/src/xran_common.h
+++ b/fhi_lib/lib/src/xran_common.h
@@ -351,6 +351,7 @@ uint8_t xran_get_num_ant_elm(void *pHandle);
enum xran_category xran_get_ru_category(void *pHandle);
struct xran_device_ctx *xran_dev_get_ctx(void);
+int xran_is_prach_slot(uint32_t subframe_id, uint32_t slot_id);
int xran_register_cb_mbuf2ring(xran_ethdi_mbuf_send_fn mbuf_send_cp, xran_ethdi_mbuf_send_fn mbuf_send_up);
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI 7.2 Fronthaul Interface 5G SA Tutorial</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# 1. Prerequisites
The hardware on which we have tried this tutorial:
|Hardware (CPU,RAM) |Operating System |NIC (Vendor,Driver,Firmware) |
|--------------------------------------------|----------------------------------|-------------------------------------------------|
|Intel(R) Xeon(R) Gold 6154 (2x18 Core), 64GB|RHEL 8.6 (4.18.0-372.26.1.rt7.183)|QLogic FastLinQ QL41000,qede,mbi 15.35.1 |
|Intel(R) Xeon(R) Gold 6354 18-Core, 128GB |RHEL 8.7 (4.18.0-425.10.1.rt7.220)|Intel XXV710 for 25GbE SFP28,i40e,6.02 0x80003888|
|AMD EPYC 7513 32-Core Processor, 256GB |Ubuntu 20.04 (5.4.143-rt64) |Intel X710 for 10GbE SFP+,i40e,5.04 0x80002530 |
**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers.
We always set our servers to maximum performance mode.
```bash
tuned-adm profile realtime
```
For PTP grandmaster we have used Fibrolan Falcon-RX. The O-RU which we have used for this tutorial is VVDN LPRU.
## 1.1 DPDK(Data Plane Development Kit)
Download DPDK version 20.05.0
```bash
wget http://fast.dpdk.org/rel/dpdk-20.05.tar.xz
```
DPDK Compilation
```bash
tar -xvf dpdk-20.05.tar.xz
cd dpdk-20.05
meson build
cd build
sudo ninja
sudo ninja install
make install T=x86_64-native-linuxapp-gcc
```
## 1.2 Setup
We have mentioned the information for our setup but if you want more information then you can refer to below links,
```bash
1. [O-RAN-SC O-DU Setup Configuration](https://docs.o-ran-sc.org/projects/o-ran-sc-o-du-phy/en/latest/Setup-Configuration_fh.html)
2. [O-RAN Cloud Platform Reference Designs 2.0,O-RAN.WG6.CLOUD-REF-v02.00,February 2021](https://orandownloadsweb.azurewebsites.net/specifications)
```
### 1.2.1 RHEL
These arguments we tried on both RHEL 8.6 (4.18.0-372.26.1.rt7.183.el8_6.x86_64) and 8.7 (4.18.0-425.10.1.rt7.220.el8_7.x86_64)
Update Linux boot arguments
```bash
igb.max_vfs=2 intel_iommu=on iommu=pt intel_pstate=disable nosoftlockup tsc=nowatchdog mitigations=off cgroup_memory=1 cgroup_enable=memory mce=off idle=poll hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 skew_tick=1 isolcpus=managed_irq,domain,0-2,8-17 nohz_full=0-2,8-17 rcu_nocbs=0-2,8-17 rcu_nocb_poll
```
### 1.2.2 Ubuntu
Install real time kernel followed by updating boot arguments
```bash
isolcpus=0-2,8-17 nohz=on nohz_full=0-2,8-17 rcu_nocbs=0-2,8-17 rcu_nocb_poll nosoftlockup default_hugepagesz=1GB hugepagesz=1G hugepages=10 amd_iommu=on iommu=pt
```
Isolated CPU 0-2 are used for DPDK/ORAN and CPU 8 for `ru_thread` in our example config
## 1.3 PTP configuration
You can refer to the [following o-ran link](https://docs.o-ran-sc.org/projects/o-ran-sc-o-du-phy/en/latest/PTP-configuration_fh.html) for PTP configuration. In our setup we used Fibrolan Falcon-RX for PTP grandmaster.
```bash
git clone http://git.code.sf.net/p/linuxptp/code linuxptp
git checkout v2.0
make && make install
./ptp4l -i ens1f1 -m -H -2 -s -f configs/default.cfg
./phc2sys -w -m -s ens1f1 -R 8 -f configs/default.cfg
```
# 2. Build OAI-FHI gNB
## 2.1 Build ORAN Fronthaul Interface Library
Download ORAN FHI library
```bash
git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git
cd phy
git checkout oran_release_bronze_v1.1
```
Apply patches (available in `oai_folder/cmake_targets/tools/oran_fhi_integration_patches/`)
```bash
git apply oran-fhi-1-compile-libxran-using-gcc-and-disable-avx512.patch
git apply oran-fhi-2-return-correct-slot_id.patch
git apply oran-fhi-3-disable-pkt-validate-at-process_mbuf.patch
git apply oran-fhi-4-process_all_rx_ring.patch
git apply oran-fhi-5-remove-not-used-dependencies.patch
```
Set up the environment (change the path if you use different folders)
```bash
export XRAN_LIB_DIR=~/phy/fhi_lib/lib/build
export XRAN_DIR=~/phy/fhi_lib
export RTE_SDK=~/dpdk-20.05
export RTE_TARGET=x86_64-native-linuxapp-gcc
export RTE_INCLUDE=${RTE_SDK}/${RTE_TARGET}/include
```
Compile Fronthaul Interface Library
```bash
cd phy/fhi_lib/
./build.sh
```
## 2.2 Build OAI gNB
```bash
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
cd openairinterface5g
git checkout develop
source oaienv
cd cmake_targets
./build_oai --gNB --ninja -t oran_fhlib_5g (Add, -I if you are building for the first time on server for installing external dependencies)
```
# 3. Configure Server and OAI gNB
## 3.1 Update following in fronthaul interface configuration - oran.fhi.json
```
* DU Mac-address: Parameter o_du_macaddr
* RU MAC Address: Parameter o_ru_macaddr
* PCI address: Parameter dpdk_dev_up and dpdk_dev_cp
```
## 3.2 Copy Fronthaul Configuration File
```bash
cd ran_build/build
cp ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/oran.fhi.json .
```
## 3.2 Bind Devices
```bash
sudo modprobe vfio_pci
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.0
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.1
```
## 3.3 Bind Devices
```bash
echo "2" > /sys/class/net/ens1f1/device/sriov_numvfs
sudo ip link set ens1f1 vf 0 mac 00:11:22:33:44:66 spoofchk off
sudo ip link set ens1f1 vf 1 mac 00:11:22:33:44:66 spoofchk off
sudo modprobe vfio_pci
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.0
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.1
```
# 4. Run OAI gNB
## 4.1 Run OAI gNB
```bash
cd ran_build/build
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/oran.fh.band78.fr1.273PRB.conf --sa --reorder-thread-disable
```
......@@ -86,6 +86,7 @@ Some directories under `radio` contain READMEs:
- [RFsimulator](../radio/rfsimulator/README.md)
- [USRP](../radio/USRP/README.md)
- [O-RAN 7.2 FHI](./ORAN_FHI7.2_Tutorial.md)
- [BladeRF](../radio/BLADERF/README)
- [IQPlayer](../radio/iqplayer/DOC/iqrecordplayer_usage.md), and [general documentation](./iqrecordplayer_usage.md)
......
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _ORAN_H_
#define _ORAN_H_
#include "shared_buffers.h"
#include "common_lib.h"
void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp);
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot);
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
typedef struct {
eth_state_t e;
shared_buffers buffers;
rru_config_msg_type_t last_msg;
int capabilities_sent;
void *oran_priv;
} oran_eth_state_t;
#endif /* _ORAN_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "oran_isolate.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "openair1/PHY/defs_gNB.h"
typedef struct {
eth_state_t e;
rru_config_msg_type_t last_msg;
int capabilities_sent;
void *oran_priv;
} oran_eth_state_t;
int trx_oran_start(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
// Start ORAN
if (start_oran(s->oran_priv) != 0) {
printf("%s:%d:%s: Start ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Start ORAN. Done\n");
}
return 0;
}
void trx_oran_end(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
stop_oran(s->oran_priv);
close_oran(s->oran_priv);
}
int trx_oran_stop(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
stop_oran(s->oran_priv);
return (0);
}
int trx_oran_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int exmimo_dump_config)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_set_gains(openair0_device *device, openair0_config_t *openair0_cfg)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_get_stats(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_reset_stats(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int ethernet_tune(openair0_device *device, unsigned int option, int value)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
int trx_oran_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
int trx_oran_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
char *msg_type(int t)
{
static char *s[12] = {
"RAU_tick",
"RRU_capabilities",
"RRU_config",
"RRU_config_ok",
"RRU_start",
"RRU_stop",
"RRU_sync_ok",
"RRU_frame_resynch",
"RRU_MSG_max_num",
"RRU_check_sync",
"RRU_config_update",
"RRU_config_update_ok",
};
if (t < 0 || t > 11)
return "UNKNOWN";
return s[t];
}
int trx_oran_ctlsend(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
oran_eth_state_t *s = device->priv;
printf("ORAN: %s\n", __FUNCTION__);
printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, msg_type(rru_config_msg->type));
s->last_msg = rru_config_msg->type;
return msg_len;
}
int trx_oran_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
oran_eth_state_t *s = device->priv;
printf("ORAN: %s\n", __FUNCTION__);
if (s->last_msg == RAU_tick && s->capabilities_sent == 0) {
printf("ORAN ctrlrcv RRU_tick received and send capabilities hard coded\n");
RRU_capabilities_t *cap;
rru_config_msg->type = RRU_capabilities;
rru_config_msg->len = sizeof(RRU_CONFIG_msg_t) - MAX_RRU_CONFIG_SIZE + sizeof(RRU_capabilities_t);
// Fill RRU capabilities (see openair1/PHY/defs_RU.h)
// For now they are hard coded - try to retreive the params from openari device
cap = (RRU_capabilities_t *)&rru_config_msg->msg[0];
cap->FH_fmt = OAI_IF4p5_only;
cap->num_bands = 1;
cap->band_list[0] = 78;
// cap->num_concurrent_bands = 1; component carriers
cap->nb_rx[0] = 1; // device->openair0_cfg->rx_num_channels;
cap->nb_tx[0] = 1; // device->openair0_cfg->tx_num_channels;
cap->max_pdschReferenceSignalPower[0] = -27;
cap->max_rxgain[0] = 90;
cap->N_RB_DL[0] = 106;
cap->N_RB_UL[0] = 106;
s->capabilities_sent = 1;
return rru_config_msg->len;
}
if (s->last_msg == RRU_config) {
printf("Oran RRU_config\n");
rru_config_msg->type = RRU_config_ok;
}
return 0;
}
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
{
oran_eth_state_t *s = ru->ifdevice.priv;
int symbol;
int32_t *rxdata;
int antenna;
static uint8_t sync = 0;
ru_info_t ru_info;
ru_info.nb_rx = ru->nb_rx;
ru_info.rxdataF = ru->common.rxdataF;
ru_info.prach_buf = (int *)ru->prach_rxsigF[0]; // index: [prach_oca][ant_id]
RU_proc_t *proc = &ru->proc;
extern uint16_t sl_ahead;
int f, sl;
int ret = xran_fh_rx_read_slot(s->oran_priv, &ru_info, &f, &sl, *frame, *slot, sync);
if (ret != 0) {
printf("ORAN: ORAN_fh_if4p5_south_in ERROR in RX function \n");
}
proc->tti_rx = sl;
proc->frame_rx = f;
proc->tti_tx = (sl + sl_ahead) % 20;
proc->frame_tx = (sl > (19 - sl_ahead)) ? (f + 1) & 1023 : f;
if (proc->first_rx == 0) {
if (proc->tti_rx != *slot) {
LOG_E(PHY, "Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n", proc->tti_rx, *slot);
*slot = proc->tti_rx;
}
if (proc->frame_rx != *frame) {
LOG_E(PHY, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d proc->tti_rx %d tti %d)\n", proc->frame_rx, *frame, proc->tti_rx, *slot);
*frame = proc->frame_rx;
}
} else {
proc->first_rx = 0;
LOG_I(PHY, "before adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
*frame = proc->frame_rx;
*slot = proc->tti_rx;
LOG_I(PHY, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
}
sync = 1;
}
void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
openair0_device *device = &ru->ifdevice;
oran_eth_state_t *s = device->priv;
ru_info_t ru_info;
ru_info.nb_tx = ru->nb_tx;
ru_info.txdataF_BF = ru->common.txdataF_BF;
// printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp);
int ret = xran_fh_tx_send_slot(s->oran_priv, &ru_info, frame, slot, timestamp);
if (ret != 0) {
printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n");
}
}
void *get_internal_parameter(char *name)
{
printf("ORAN: %s\n", __FUNCTION__);
if (!strcmp(name, "fh_if4p5_south_in"))
return (void *)oran_fh_if4p5_south_in;
if (!strcmp(name, "fh_if4p5_south_out"))
return (void *)oran_fh_if4p5_south_out;
return NULL;
}
__attribute__((__visibility__("default"))) int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params)
{
oran_eth_state_t *eth;
device->Mod_id = 0;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_oran_start;
device->trx_get_stats_func = trx_oran_get_stats;
device->trx_reset_stats_func = trx_oran_reset_stats;
device->trx_end_func = trx_oran_end;
device->trx_stop_func = trx_oran_stop;
device->trx_set_freq_func = trx_oran_set_freq;
device->trx_set_gains_func = trx_oran_set_gains;
device->trx_write_func = trx_oran_write_raw;
device->trx_read_func = trx_oran_read_raw;
device->trx_ctlsend_func = trx_oran_ctlsend;
device->trx_ctlrecv_func = trx_oran_ctlrecv;
device->get_internal_parameter = get_internal_parameter;
eth = (oran_eth_state_t *)calloc(1, sizeof(oran_eth_state_t));
if (eth == NULL) {
AssertFatal(0 == 1, "out of memory\n");
}
eth->e.flags = ETH_RAW_IF4p5_MODE;
eth->e.compression = NO_COMPRESS;
eth->e.if_name = eth_params->local_if_name;
eth->oran_priv = define_oran_pointer();
device->priv = eth;
device->openair0_cfg = &openair0_cfg[0];
eth->last_msg = (rru_config_msg_type_t)-1;
oran_eth_state_t *s = eth;
printf("ORAN: %s\n", __FUNCTION__);
// Check if the machine is PTP sync
check_xran_ptp_sync();
// SetUp
if (setup_oran(s->oran_priv) != 0) {
printf("%s:%d:%s: SetUp ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("SetUp ORAN. Done\n");
}
// Dump ORAN config
dump_oran_config(s->oran_priv);
// Register physide callbacks
register_physide_callbacks(s->oran_priv);
printf("Register physide callbacks. Done\n");
// Open callbacks
open_oran_callback(s->oran_priv);
printf("Open Oran callbacks. Done\n");
// Init ORAN
initialize_oran(s->oran_priv);
printf("Init Oran. Done\n");
// Open ORAN
open_oran(s->oran_priv);
printf("xran_open. Done\n");
return 0;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _ORAN_ISOLATE_H_
#define _ORAN_ISOLATE_H_
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
/*
* Structure added to bear the information needed from OAI RU
*/
typedef struct ru_info_s {
// Needed for UL
int nb_rx;
int32_t **rxdataF;
// Needed for DL
int nb_tx;
int32_t **txdataF_BF;
// Needed for Prach
int **prach_buf;
} ru_info_t;
#ifdef __cplusplus
extern "C" {
#endif
void *define_oran_pointer();
void dump_oran_config(void *xranlib_);
int setup_oran(void *xranlib_);
int open_oran_callback(void *xranlib_);
int open_oran(void *xranlib_);
int initialize_oran(void *xranlib_);
int start_oran(void *xranlib_);
int stop_oran(void *xranlib_);
int close_oran(void *xranlib_);
int register_physide_callbacks(void *xranlib_);
int load_iq_from_file(void *xranlib_);
int xran_fh_rx_read_slot(void *xranlib_, ru_info_t *ru, int *frame, int *slot, int oframe, int oslot, uint8_t sync);
int xran_fh_tx_send_buffer(void *xranlib_);
int xran_fh_tx_send_slot(void *xranlib_, ru_info_t *ru, int frame, int slot, uint64_t timestamp);
int compute_xran_statistics(void *xranlib_);
void check_xran_ptp_sync();
#ifdef __cplusplus
}
#endif
#endif /* _ORAN_ISOLATE_H_ */
This diff is collapsed.
/*******************************************************************************
* The MIT License (MIT)
* Copyright 2018 JSON for Modern C++
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
*******************************************************************************/
#ifndef XRAN_LIB_WRAP_HPP
#define XRAN_LIB_WRAP_HPP
#include <exception>
#include <random>
#include <string>
#include <utility>
#include <vector>
#include <malloc.h>
#include <stdint.h>
#include "common.hpp"
#include "xran_fh_o_du.h"
#include "xran_common.h"
#include "xran_frame_struct.h"
#define XRAN_UT_CFG_FILENAME "oran.fhi.json"
#define XRAN_UT_KEY_GLOBALCFG "GLOBAL"
#define XRAN_UT_KEY_GLOBALCFG_IO "io_cfg"
#define XRAN_UT_KEY_GLOBALCFG_EAXCID "eAxCId_cfg"
#define XRAN_UT_KEY_GLOBALCFG_PRACH "prach_cfg"
#define XRAN_UT_KEY_GLOBALCFG_RU "ru_cfg"
#define XRAN_UT_KEY_GLOBALCFG_SLOT "slotcfg_"
#define MAX_NUM_OF_XRAN_CTX (2)
#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)
#define FPGA_TO_SW_PRACH_RX_BUFFER_LEN (8192)
#define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR * XRAN_MAX_ANTENNA_NR)
enum xran_in_period { XRAN_IN_PREV_PERIOD = 0, XRAN_IN_CURR_PERIOD, XRAN_IN_NEXT_PERIOD };
extern "C" {
extern uint32_t xran_lib_ota_tti;
extern uint32_t xran_lib_ota_sym;
extern uint32_t xran_lib_ota_sym_idx;
extern uint32_t xran_SFN_at_Sec_Start;
void sym_ota_cb(struct rte_timer *tim, void *arg);
void tti_ota_cb(struct rte_timer *tim, void *arg);
}
class xranLibWraper {
public:
typedef enum {
XRANFTHTX_OUT = 0,
XRANFTHTX_PRB_MAP_OUT,
XRANFTHTX_SEC_DESC_OUT,
XRANFTHRX_IN,
XRANFTHRX_PRB_MAP_IN,
XRANFTHTX_SEC_DESC_IN,
XRANFTHRACH_IN,
XRANSRS_IN,
MAX_SW_XRAN_INTERFACE_NUM
} SWXRANInterfaceTypeEnum;
enum nChBw {
PHY_BW_5MHZ = 5,
PHY_BW_10MHZ = 10,
PHY_BW_15MHZ = 15,
PHY_BW_20MHZ = 20,
PHY_BW_25MHZ = 25,
PHY_BW_30MHZ = 30,
PHY_BW_40MHZ = 40,
PHY_BW_50MHZ = 50,
PHY_BW_60MHZ = 60,
PHY_BW_70MHZ = 70,
PHY_BW_80MHZ = 80,
PHY_BW_90MHZ = 90,
PHY_BW_100MHZ = 100,
PHY_BW_200MHZ = 200,
PHY_BW_400MHZ = 400
};
// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
const uint16_t nNumRbsPerSymF1[3][13] = {
// 5MHz 10MHz 15MHz 20MHz 25MHz 30MHz 40MHz 50MHz 60MHz 70MHz 80MHz 90MHz 100MHz
{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
const uint16_t nNumRbsPerSymF2[2][4] = {
// 50MHz 100MHz 200MHz 400MHz
{66, 132, 264, 0}, // Numerology 2 (60KHz)
{32, 66, 132, 264} // Numerology 3 (120KHz)
};
protected:
char argv[25] = {'u', 'n', 'i', 't', 't', 'e', 's', 't', '\0'};
// char argv[25] = "unittest";
std::string m_dpdk_dev_up, m_dpdk_dev_cp, m_dpdk_bbdev;
void *m_xranhandle;
uint8_t m_du_mac[6]; // = { 0x00,0x11, 0x22, 0x33, 0x44, 0x55 }; // This is hard coded here and then it is read from the conf file
uint8_t m_ru_mac[XRAN_VF_MAX][6]; //= { 0x00,0x11, 0x22, 0x33, 0x44, 0x66 }; // This is hard coded here and then it is read from the conf file
bool m_bSub6;
uint32_t m_nSlots; // = 20;
struct xran_fh_config m_xranConf;
struct xran_fh_init m_xranInit;
struct xran_timer_ctx {
uint32_t tti_to_process;
} m_timer_ctx[MAX_NUM_OF_XRAN_CTX];
/* io struct */
BbuIoBufCtrlStruct m_sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
/* Cat B */
BbuIoBufCtrlStruct m_sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
/* buffers lists */
struct xran_flat_buffer m_sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
/* Cat B SRS buffers */
struct xran_flat_buffer m_sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];
void *m_nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
uint32_t m_nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool
uint32_t m_nSW_ToFpga_FTH_TxBufferLen;
uint32_t m_nFpgaToSW_FTH_RxBufferLen;
int32_t m_nSectorIndex[XRAN_MAX_SECTOR_NR];
int iq_bfw_buffer_size_dl = 0;
int iq_bfw_buffer_size_ul = 0;
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
private:
json m_global_cfg;
template <typename T>
T get_globalcfg(const std::string &type, const std::string &parameter_name)
{
return m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name];
}
template <typename T>
std::vector<T> get_globalcfg_array(const std::string &type, const std::string &parameter_name)
{
auto array_size = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name].size();
std::vector<T> result(array_size);
for (unsigned number = 0; number < array_size; number++)
result.at(number) = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name][number];
return result;
}
uint16_t get_eaxcid_mask(int numbit, int shift);
int init_memory();
public:
// Class constructor
xranLibWraper();
// Class Distructor
~xranLibWraper();
int SetUp();
void TearDown();
int Init(struct xran_fh_config *pCfg = nullptr);
void Cleanup();
void Open(xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up, void *fh_rx_callback, void *fh_rx_prach_callback, void *fh_srs_callback);
void Close();
int Start();
int Stop();
/* emulation of timer */
void update_tti();
void update_symbol_index();
int apply_cpenable(bool flag);
int get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg);
int get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6);
void *get_xranhandle();
void *get_timer_ctx();
int get_symbol_index();
int get_ota_tti();
int get_SFN_at_sec_start();
int get_symbol_offset(int32_t offSym, int32_t otaSym, int32_t numSymTotal, enum xran_in_period *pInPeriod);
bool is_running();
enum xran_category get_rucategory();
int get_numerology();
int get_duplextype();
uint32_t get_num_cc();
uint32_t get_num_eaxc();
uint32_t get_num_eaxc_ul();
uint32_t get_num_dlrbs();
uint32_t get_num_ulrbs();
uint32_t get_num_antelmtrx();
bool is_cpenable();
bool is_prachenable();
bool is_dynamicsection();
bool get_sub6();
void get_cfg_prach(struct xran_prach_config *pCfg);
void get_cfg_frame(struct xran_frame_config *pCfg);
void get_cfg_ru(struct xran_ru_config *pCfg);
void get_cfg_fh(struct xran_fh_config *pCfg);
};
/* external declaration for the instance */
extern xranLibWraper *xranlib;
#endif // XRAN_LIB_WRAP_HPP
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment