Compare commits

...

17 Commits

Author SHA1 Message Date
Teodora Vladić
c95134273d Use pull when polling not defined
Squash in:
WIP: fix(oran_fhlib_5g): Attempt to fix handling of PRACH
2026-03-17 13:48:27 +01:00
Romain Beurdouche
845608bdf6 fix(oran_fhlib_5g): Correctly read PRACH beam index in K release
Co-authored-by: Mario Joa-Ng <mario.joa-ng@openairinterface.com>
2026-03-16 10:39:59 +00:00
Mario Joa-Ng
59be412e90 fix two PRACH bugs. 1. Use *pPrbMap = (struct xran_prb_map *)bufs->prachdstdecomp instead of * pPrbMap = (struct xran_prb_map *)&bufs->prachdstdecomp as pointer of PrbMap. 2. Clear nRxPkt of the RbMap of the previous slot. 2026-03-16 10:39:59 +00:00
Romain Beurdouche
979bd26c60 WIP: fix(oran_fhlib_5g): Attempt to fix handling of PRACH
This is an incomplete attempt to complete the parent commit which is also WIP.

Try to add a PRACH callback in order to properly handle PRACH in K release.
As of now a segmentation fault is issued when trying to decompress the PRACH data.
2026-03-16 10:39:59 +00:00
Romain Beurdouche
890153f261 WIP: fix(oran_fhlib_5g): Use new RX PRB mapping
K release introduced a new structure to describe the segmentation of RX symbols.
This commit enables using this structure to retrieve RX data.

The commit is incomplete.
As of this commit, the PRACH buffer is initialized to 0 in order to avoid a segmentation fault but it should normally be initialized using `oran_allocate_cplane_buffers`.
2026-03-16 10:39:59 +00:00
Romain Beurdouche
aaf2cb3a2a fix(oran_fhlib_5g): Trim padding of UL U-Plane packets
Some RUs produce UL U-Plane packets with padding.
Packets with padding are considered erroneous by XRAN and are dropped.
Instead of dropping these packets, we trim their padding.
2026-03-16 10:39:59 +00:00
Romain Beurdouche
4b9bf7ad87 feat(oran_fhlib_5g): RX error counters
K releases added RX error counters
This commits adds a printing of these counters with LOG_I
2026-03-16 10:39:59 +00:00
Jaroslava Fiedlerova
a3adf09a78 Install libatomic in FHI72 gNB images
libatomic is required by DPDK 22.11.7
2026-03-16 10:39:59 +00:00
Romain Beurdouche
12640cb431 fix(oran_fhlib_5g): Fix build on Arm
Disable new AVX related additions
2026-03-16 10:39:59 +00:00
Robert Schmidt
db2adf231b TODO FHI7.2 on ARM: fix meson platform error
Avoid error

    config/arm/meson.build:603:8: ERROR: Problem encountered: Unsupported part number 0xd4f of implementer 0x41. Please add support for it or use the generic (-Dplatform=generic) build.

as suggested by meson. More information and a proper fix might be found
here:
https://doc.dpdk.org/guides/linux_gsg/cross_build_dpdk_for_arm64.html#supported-soc-configuration
2026-03-16 10:39:59 +00:00
Robert Schmidt
c90f80afea FHI7.2 docker images: make output less verbose on build 2026-03-16 10:39:59 +00:00
Romain Beurdouche
84f990ce0f feat(CI): Build FHI with K release
Updated the dockerfiles for building FHI with K release and DPDK 22.11.0
2026-03-16 10:39:59 +00:00
Romain Beurdouche
0bdc418fb4 fix(oran_fhlib_5g): Hotfix conflict with LiteON FR2 support
Disallow Prb Map per Symbol for K Release

To be fixed properly later
2026-03-16 10:39:57 +00:00
Romain Beurdouche
b7bd4d0639 feat(oran_fhlib_5g): Changes to run K release
* Initialize leak detector
* Fill IO config field holding the number of mbufs to be allocated
* Allocate and fill `activeMUs` in the FH config
* Start timing source, worker thread and activate CCs upon starting the FH
* Fill `mu_number[0]` in FH config
* Invert trx_oran end and stop
* Set `neAxcUl`
2026-03-16 10:18:12 +00:00
Romain Beurdouche
ca54feab40 feat(oran_fhlib_5g): Adapt oran_fhlib_5g for K release
Adapt the oran_fhlib_5g code to compile with xran K release.
Like previously E and F, uses preprocessor directives to separate codes for different xran releases.

Notes:
1. Release K of the FHI library supports many numerologies on one instance.
   As of now the integration supports only one numerology.
2. Several arrays in the xran interface are indexed by the numerology.
   It was ambiguous whether they were indexed by the actual numerology number or by the index of the relevant numerology within the numerology array.
   They are actually indexed by the numerology number so that when one is using only numerlogy 1 for example, he should only use perMu[1], fftSize[1], ...
2026-03-16 10:18:10 +00:00
Romain Beurdouche
5aae6ed1f9 feat(oran_fhlib_5g): update Findxran
Update the Cmake find script for xran to detect K release (11.1.1).
2026-03-16 09:44:52 +00:00
Romain Beurdouche
9483497920 feat(oran_fhlib_5g): patch for K release
Added a patch for K release inspired from the patch of F release.
xran K release compiles with DPDK v22.11 and custom DPDK install path.
2026-03-16 09:44:52 +00:00
18 changed files with 1924 additions and 138 deletions

View File

@@ -23,9 +23,9 @@
# -------
#
# Finds the xran library. Note that the library number is as follows:
# - oran_bronze_release_v1.1 -> 2.1.1 (B = second letter)
# - oran_e_maintenance_release_v1.0 -> 5.1.0
# the version is currently hardcoded to 5.1.0
# - oran_e_maintenance_release_v1.5 -> 5.1.6
# - oran_f_release_v1.3 -> 6.1.4
# - oran_k_release_v1.1 -> 11.1.1
#
# Required options
# ^^^^^^^^^^^^^^^^
@@ -107,6 +107,8 @@ if (xran_VERSION_STRING MATCHES "^oran_e_maintenance_release_v")
string(REGEX REPLACE "oran_e_maintenance_release_v([0-9]+).([0-9]+)" "5.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_f_release_v")
string(REGEX REPLACE "oran_f_release_v([0-9]+).([0-9]+)" "6.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_k_release_v")
string(REGEX REPLACE "oran_k_release_v([0-9]+).([0-9]+)" "11.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_bronze_release_v")
string(REGEX REPLACE "oran_bronze_release_v([0-9]+).([0-9]+)" "2.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
else()

View File

@@ -0,0 +1,982 @@
diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h
index 3819d8e..e7bfaa9 100644
--- a/fhi_lib/app/src/common.h
+++ b/fhi_lib/app/src/common.h
@@ -28,7 +28,7 @@
#include <rte_common.h>
#include <rte_mbuf.h>
-#define VERSIONX "#DIRTY#"
+#define VERSIONX "oran_k_release_v1.1"
#define APP_O_DU 0
#define APP_O_RU 1
diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile
index d0c238c..d20c44f 100644
--- a/fhi_lib/lib/Makefile
+++ b/fhi_lib/lib/Makefile
@@ -23,20 +23,41 @@ MYCUSTOMSPACE1='------------------------------------------------------------'
##############################################################
# Tools configuration
##############################################################
-ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc)
- CC := icc
- CPP := icpc
- AS := as
- AR := ar
- LD := icc
-else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx)
- CC := icx
- CPP := icpx
- AS := as
- AR := llvm-ar
- LD := icx
+
+# Default target architecture and compiler
+TARGET ?= x86
+
+# Architecture and compiler-specific tools and flags
+ifeq ($(TARGET), x86)
+ ifeq ($(WIRELESS_SDK_TOOLCHAIN),gcc)
+ CC := gcc
+ CPP := g++
+ AS := as
+ AR := ar
+ LD := gcc
+ else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc)
+ CC := icc
+ CPP := icpc
+ AS := as
+ AR := ar
+ LD := icc
+ else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx)
+ CC := icx
+ CPP := icpx
+ AS := as
+ AR := llvm-ar
+ LD := icx
+ else
+ $(error "Please define WIRELESS_SDK_TOOLCHAIN environment variable")
+ endif
+else ifeq ($(TARGET), armv8) # aarch64
+ CC := gcc
+ CPP := g++
+ LD := gcc
+ CFLAGS += -march=armv8-a
+ LDFLAGS +=
else
- $(error "Please define WIRELESS_SDK_TOOLCHAIN environment variable")
+ $(error Unsupported target architecture: $(TARGET))
endif
ifeq ($(WIRELESS_SDK_TARGET_ISA),avx512)
@@ -79,7 +100,7 @@ ifeq ($(RTE_SDK),)
endif
RTE_TARGET ?= x86_64-native-linux-icc
-RTE_INC := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH):/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk)
+RTE_INC := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH):/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkg-config --cflags-only-I libdpdk)
API_DIR := $(PROJECT_DIR)/api
SRC_DIR := $(PROJECT_DIR)/src
@@ -110,22 +131,23 @@ CC_SRC = $(ETH_DIR)/xran_ethdi.c \
$(SRC_DIR)/xran_main.c \
$(SRC_DIR)/xran_delay_measurement.c
-CPP_SRC = $(SRC_DIR)/xran_compression.cpp \
- $(SRC_DIR)/xran_bfp_ref.cpp \
- $(SRC_DIR)/xran_bfp_cplane8.cpp \
- $(SRC_DIR)/xran_bfp_cplane16.cpp \
- $(SRC_DIR)/xran_bfp_cplane32.cpp \
- $(SRC_DIR)/xran_bfp_cplane64.cpp \
- $(SRC_DIR)/xran_bfp_uplane.cpp \
- $(SRC_DIR)/xran_mod_compression.cpp
-
-CPP_SRC_SNC = $(SRC_DIR)/xran_compression_snc.cpp \
- $(SRC_DIR)/xran_bfp_cplane8_snc.cpp \
- $(SRC_DIR)/xran_bfp_cplane16_snc.cpp \
- $(SRC_DIR)/xran_bfp_cplane32_snc.cpp \
- $(SRC_DIR)/xran_bfp_cplane64_snc.cpp \
- $(SRC_DIR)/xran_bfp_uplane_snc.cpp \
- $(SRC_DIR)/xran_bfp_uplane_spr.cpp
+ifeq ($(TARGET), x86)
+ CPP_SRC = $(SRC_DIR)/xran_compression.cpp \
+ $(SRC_DIR)/xran_bfp_ref.cpp \
+ $(SRC_DIR)/xran_bfp_cplane8.cpp \
+ $(SRC_DIR)/xran_bfp_cplane16.cpp \
+ $(SRC_DIR)/xran_bfp_cplane32.cpp \
+ $(SRC_DIR)/xran_bfp_cplane64.cpp \
+ $(SRC_DIR)/xran_bfp_uplane.cpp
+
+ CPP_SRC_SNC = $(SRC_DIR)/xran_compression_snc.cpp \
+ $(SRC_DIR)/xran_bfp_cplane8_snc.cpp \
+ $(SRC_DIR)/xran_bfp_cplane16_snc.cpp \
+ $(SRC_DIR)/xran_bfp_cplane32_snc.cpp \
+ $(SRC_DIR)/xran_bfp_cplane64_snc.cpp \
+ $(SRC_DIR)/xran_bfp_uplane_snc.cpp \
+ $(SRC_DIR)/xran_bfp_uplane_spr.cpp
+endif
CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
-fdata-sections \
@@ -134,7 +156,11 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
-fPIC \
-Wall \
-Wimplicit-function-declaration \
- -g -O3 -mcmodel=large
+ -g -O
+
+ifeq ($(TARGET), x86)
+CC_FLAGS += -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512
+endif
ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc)
CC_FLAGS += -wd1786 -restrict
@@ -148,9 +174,15 @@ ifeq ($(WIRELESS_SDK_TARGET_ISA),spr)
CC_FLAGS += -D_BBLIB_SPR_ -qopt-zmm-usage=high
endif
-CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \
- -falign-functions=16 \
- -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -fPIC
+ifeq ($(TARGET), x86)
+ CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \
+ -fPIC \
+ -falign-functions=16 \
+ -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512
+else ifeq ($(TARGET), armv8)
+ CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \
+ -Werror -Wno-unused-variable -std=c++14
+endif
ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc)
CPP_FLAGS += -fp-model fast=2 -no-prec-div -no-prec-sqrt -fast-transcendentals -restrict
@@ -164,7 +196,7 @@ ifeq ($(WIRELESS_SDK_TARGET_ISA),spr)
CPP_FLAGS += -D_BBLIB_SPR_ -qopt-zmm-usage=high
endif
-INC := -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) -I$(RTE_INC)
+INC := -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) $(RTE_INC)
DEF :=
ifeq ($(MLOG),1)
INC += -I$(MLOG_DIR)/source
@@ -210,8 +242,13 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC))
AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
#-qopt-report=5 -qopt-matmul -qopt-report-phase=all
-CPP_COMP := -O3 -DNDEBUG -fPIE -fasm-blocks
-CPP_COMP_SNC := -O3 -DNDEBUG -fPIE -fasm-blocks
+ifeq ($(TARGET), x86)
+ CPP_COMP := -O3 -DNDEBUG -fPIE
+ CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE
+else ifeq ($(TARGET), armv8)
+ CPP_COMP := -O3 -DNDEBUG -fPIE -Wrestrict
+ CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE -Wrestrict
+endif
CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF)
CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF)
CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF)
diff --git a/fhi_lib/lib/api/xran_fh_o_du.h b/fhi_lib/lib/api/xran_fh_o_du.h
index 1261fa0..5d4f942 100644
--- a/fhi_lib/lib/api/xran_fh_o_du.h
+++ b/fhi_lib/lib/api/xran_fh_o_du.h
@@ -158,7 +158,7 @@ extern "C" {
#define XRAN_SSB_MAX_NUM_SC (240) /**< 3GPP TS 38.211 - 7.4.3.1 Time-frequency structure of an SS/PBCH block */
#define XRAN_SSB_MAX_NUM_PRB (XRAN_SSB_MAX_NUM_SC / XRAN_NUM_OF_SC_PER_RB)
-#define XRAN_MAX_FRAGMENT (2) /**< Max number of fragmentations in single symbol */
+#define XRAN_MAX_FRAGMENT (6) /**< Max number of fragmentations in single symbol */
#define XRAN_MAX_RX_PKT_PER_SYM (32) /**< Max number of packets received in single symbol */
#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
@@ -1800,7 +1800,7 @@ int32_t xran_start(void *pHandle);
* @return
* 0 - on success
*/
-int32_t xran_activate_cc(int32_t port_id, int32_t cc_id);
+int32_t xran_activate_cc(void *pHandle, int32_t cc_id);
/**
* @ingroup xran
@@ -1816,7 +1816,7 @@ int32_t xran_activate_cc(int32_t port_id, int32_t cc_id);
* @return
* 0 - on success
*/
-int32_t xran_deactivate_cc(int32_t port_id, int32_t cc_id);
+int32_t xran_deactivate_cc(void *pHandle, int32_t cc_id);
/**
* @ingroup xran
diff --git a/fhi_lib/lib/api/xran_pkt_cp.h b/fhi_lib/lib/api/xran_pkt_cp.h
index 0c690a1..8b67b67 100644
--- a/fhi_lib/lib/api/xran_pkt_cp.h
+++ b/fhi_lib/lib/api/xran_pkt_cp.h
@@ -33,6 +33,14 @@
extern "C" {
#endif
+#include <stdint.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+typedef int32x4_t simd_data_t;
+#else
+#include <xmmintrin.h>
+typedef __m128i simd_data_t;
+#endif
/**********************************************************************
* Common structures for C/U-plane
@@ -256,7 +264,7 @@ union xran_cp_radioapp_section_ext3_first {
}all_bits;
struct{
- __m128i data_field1;
+ simd_data_t data_field1;
}data_field;
} __attribute__((__packed__));
diff --git a/fhi_lib/lib/api/xran_timer.h b/fhi_lib/lib/api/xran_timer.h
index 2efb9dc..fa628a8 100644
--- a/fhi_lib/lib/api/xran_timer.h
+++ b/fhi_lib/lib/api/xran_timer.h
@@ -119,12 +119,30 @@ inline unsigned long get_ticks_diff(unsigned long curr_tick, unsigned long last_
return (unsigned long)(0xFFFFFFFFFFFFFFFF - last_tick + curr_tick);
}
+#if defined(__x86_64__)
inline uint64_t xran_tick(void)
{
uint32_t hi, lo;
__asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 );
}
+#elif defined(__aarch64__)
+#include <sys/time.h>
+inline uint64_t xran_tick(void) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+}
+#elif defined(__arm__)
+#include <time.h>
+inline uint64_t xran_tick(void) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec;
+}
+#else
+#error "Unsupported architecture"
+#endif
int xran_timingsource_set_gpsoffset(int64_t offset_sec, int64_t offset_nsec);
//uint32_t xran_timingsource_get_coreid(void);
diff --git a/fhi_lib/lib/api/xran_up_api.h b/fhi_lib/lib/api/xran_up_api.h
index 28dfb89..c267278 100644
--- a/fhi_lib/lib/api/xran_up_api.h
+++ b/fhi_lib/lib/api/xran_up_api.h
@@ -80,6 +80,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
uint8_t *subframe_id,
uint8_t *slot_id,
uint8_t *symb_id,
+ uint8_t *filter_id,
union ecpri_seq_id *seq_id,
uint16_t *num_prbu,
uint16_t *start_prbu,
@@ -90,7 +91,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
uint8_t *iqWidth,
- uint8_t oxu_port_id);
+ uint8_t oxu_port_id,
+ uint8_t *is_prach);
int32_t xran_extract_iq_samples_dataheader(struct rte_mbuf *mbuf,
void **iq_data_start,
diff --git a/fhi_lib/lib/ethernet/xran_ethdi.c b/fhi_lib/lib/ethernet/xran_ethdi.c
index a4f4f0d..04028d2 100644
--- a/fhi_lib/lib/ethernet/xran_ethdi.c
+++ b/fhi_lib/lib/ethernet/xran_ethdi.c
@@ -37,7 +37,10 @@
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <numa.h>
#include <rte_config.h>
#include <rte_common.h>
@@ -371,8 +374,8 @@ int32_t xran_ethdi_init_dpdk(char *name, char *vfio_name, struct xran_io_cfg *io
char bbdev_vdev_aux[XRAN_MAX_AUX_BBDEV_NUM][32];
char vfio_token[64] = "";
char iova_mode[32] = "--iova-mode=pa";
- char socket_mem[32] = "--socket-mem=8192";
- char socket_limit[32] = "--socket-limit=8192";
+ char socket_mem[32] = "--socket-mem=0";
+ char socket_limit[32] = "--socket-limit=0";
uint32_t cpu = 0;
uint32_t node = 0;
@@ -488,8 +491,11 @@ int32_t xran_ethdi_init_dpdk(char *name, char *vfio_name, struct xran_io_cfg *io
}
printf("\n");
+#if defined(__arm__) || defined(__aarch64__)
+#else
if(rte_vect_set_max_simd_bitwidth(RTE_VECT_SIMD_512) < 0)
rte_panic("Cannot init RTE_VECT_SIMD_512: %s\n", rte_strerror(rte_errno));
+#endif
/* This will return on system_core, which is not necessarily the
* one we're on right now. */
@@ -567,11 +573,13 @@ int32_t xran_ethdi_init_dpdk_ports(struct xran_io_cfg *io_cfg,
ctx->tx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING_TRX,
rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ);
PANIC_ON(ctx->tx_ring[i] == NULL, "failed to allocate rx ring");
+ printf("Created ring %s on core %d\n", ring_name, *lcore_id);
for(qi = 0; qi < io_cfg->num_rxq; qi++) {
snprintf(ring_name, RTE_DIM(ring_name), "%s_%d_%d_%d", "rx_ring_cp", i, qi, port[i]);
ctx->rx_ring[i][qi] = rte_ring_create(ring_name, NUM_MBUFS_RING_TRX,
rte_lcore_to_socket_id(*lcore_id), RING_F_SP_ENQ);
PANIC_ON(ctx->rx_ring[i][qi] == NULL, "failed to allocate rx ring");
+ printf("Created ring %s on core %d\n",ring_name,*lcore_id);
}
}
} else {
@@ -640,7 +648,7 @@ int32_t xran_ethdi_init_dpdk_ports(struct xran_io_cfg *io_cfg,
snprintf(ring_name, RTE_DIM(ring_name), "%s_%d_%d", "dl_gen_ring_up", i,io_cfg->nDpdkProcessID);
ctx->up_dl_pkt_gen_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), /*RING_F_SC_DEQ*/0);
PANIC_ON(ctx->up_dl_pkt_gen_ring[i] == NULL, "failed to allocate dl gen ring");
- printf("created %s\n", ring_name);
+ printf("created %s on core %d\n", ring_name, *lcore_id);
}
return 1;
diff --git a/fhi_lib/lib/ethernet/xran_ethernet.c b/fhi_lib/lib/ethernet/xran_ethernet.c
index b8ce4ee..05857f7 100644
--- a/fhi_lib/lib/ethernet/xran_ethernet.c
+++ b/fhi_lib/lib/ethernet/xran_ethernet.c
@@ -37,7 +37,10 @@
#include <sys/types.h>
#include <stdlib.h>
#include <math.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_config.h>
#include <rte_common.h>
diff --git a/fhi_lib/lib/src/xran_bfp_byte_packing_utils.hpp b/fhi_lib/lib/src/xran_bfp_byte_packing_utils.hpp
index 483efb3..bf170a2 100644
--- a/fhi_lib/lib/src/xran_bfp_byte_packing_utils.hpp
+++ b/fhi_lib/lib/src/xran_bfp_byte_packing_utils.hpp
@@ -894,7 +894,7 @@ namespace BlockFloatCompander
/// Mask to zero unwanted bits
const __m256i k_expMask = _mm256_set1_epi16(0xFFFC);
- return _mm256_and_epi64(compDataCombined, k_expMask);
+ return _mm256_and_si256(compDataCombined, k_expMask);
}
}
diff --git a/fhi_lib/lib/src/xran_bfp_uplane.cpp b/fhi_lib/lib/src/xran_bfp_uplane.cpp
index 7b70bf2..f412868 100644
--- a/fhi_lib/lib/src/xran_bfp_uplane.cpp
+++ b/fhi_lib/lib/src/xran_bfp_uplane.cpp
@@ -89,7 +89,7 @@ namespace BFP_UPlane
{
const __m512i* rawData = reinterpret_cast<const __m512i*>(dataIn.dataExpanded);
/// Abs
- const auto rawDataAbs = _mm512_abs_epi16(rawData[0]);
+ const auto rawDataAbs = _mm512_abs_epi16(_mm512_loadu_epi16(rawData));
/// No need to do a full horizontal max operation here, just do a max IQ step,
/// compute the exponents and then use a reduce max over all exponent values. This
/// is the fastest way to handle a single RB.
@@ -431,4 +431,4 @@ BlockFloatCompander::BFPExpandUserPlaneAvx512(const CompressedData& dataIn, Expa
BFP_UPlane::expandByAllocN<BlockFloatCompander::networkByteUnpack12b>(dataIn, dataOut, k_totNumBytesPerRB12, k_maxExpShift12);
break;
}
-}
\ No newline at end of file
+}
diff --git a/fhi_lib/lib/src/xran_cb_proc.c b/fhi_lib/lib/src/xran_cb_proc.c
index 56db2bf..35010d5 100644
--- a/fhi_lib/lib/src/xran_cb_proc.c
+++ b/fhi_lib/lib/src/xran_cb_proc.c
@@ -25,7 +25,10 @@
#include <unistd.h>
#include <stdio.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
#include <rte_errno.h>
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index 5613646..f1d0f87 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -31,7 +31,10 @@
#include <sys/time.h>
#include <time.h>
#include <pthread.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_mbuf.h>
#include <stdio.h>
#include <stdbool.h>
@@ -967,11 +970,14 @@ int32_t process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *
uint8_t compMeth = 0;
uint8_t iqWidth = 0;
+ uint8_t is_prach = 0;
+
int ret = MBUF_FREE;
uint32_t mb_free = 0;
int32_t valid_res = 0;
int expect_comp = (p_dev_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);
enum xran_comp_hdr_type staticComp = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
+ uint8_t filter_id;
#ifdef POLL_EBBU_OFFLOAD
PXRAN_TIMER_CTX pCtx = xran_timer_get_ctx_ebbu_offload();
@@ -991,9 +997,9 @@ int32_t process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *
return MBUF_FREE;
num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf,
- &CC_ID, &Ant_ID, &frame_id, &subframe_id, &slot_id, &symb_id, &seq,
+ &CC_ID, &Ant_ID, &frame_id, &subframe_id, &slot_id, &symb_id, &filter_id, &seq,
&num_prbu, &start_prbu, &sym_inc, &rb, &sect_id,
- expect_comp, staticComp, &compMeth, &iqWidth, XRAN_GET_OXU_PORT_ID(p_dev_ctx));
+ expect_comp, staticComp, &compMeth, &iqWidth, XRAN_GET_OXU_PORT_ID(p_dev_ctx), &is_prach);
if (unlikely(num_bytes <= 0))
{
print_err("num_bytes is wrong [%d]\n", num_bytes);
@@ -1128,6 +1134,9 @@ int32_t process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *
} /* else if (Ant_ID >= p_dev_ctx->srs_cfg.srsEaxcOffset ...... */
else
{
+ pCnt->rx_counter++;
+ pCnt->Rx_on_time++;
+ pCnt->Total_msgs_rcvd++;
struct xran_prach_cp_config *PrachCfg = NULL;
if(p_dev_ctx->dssEnable)
@@ -1143,9 +1152,7 @@ int32_t process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *
PrachCfg = &(p_dev_ctx->perMu[mu].PrachCPConfig);
}
- if (Ant_ID >= PrachCfg->prachEaxcOffset
- && Ant_ID < (PrachCfg->prachEaxcOffset +xran_get_num_eAxc(p_dev_ctx))
- && p_dev_ctx->fh_cfg.perMu[mu].prachEnable)
+ if (p_dev_ctx->fh_cfg.perMu[mu].prachEnable && is_prach)
{
if(p_dev_ctx->fh_cfg.ru_conf.xranTech == XRAN_RAN_5GNR)
{
@@ -1992,8 +1999,7 @@ int32_t ring_processing_func(void* args)
rte_timer_manage();
#endif
- if (process_ring(ctx->rx_ring[i][qi], i, qi))
- return 0;
+ process_ring(ctx->rx_ring[i][qi], i, qi);
}
// }
}
diff --git a/fhi_lib/lib/src/xran_compression.cpp b/fhi_lib/lib/src/xran_compression.cpp
index c35f7cd..437326b 100644
--- a/fhi_lib/lib/src/xran_compression.cpp
+++ b/fhi_lib/lib/src/xran_compression.cpp
@@ -52,16 +52,7 @@ struct xran_lib_compander_for_isa
{
xran_lib_compander_for_isa() {
if (gCpuCapability == -1) {
-#ifdef _BBLIB_SPR_
- if (_may_i_use_cpu_feature(_FEATURE_F16C)) {
- gCpuCapability = 2;
- } else
-#endif
- if (_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52)) {
- gCpuCapability = 1;
- } else {
- gCpuCapability = 0;
- }
+ gCpuCapability = 0;
}
printf("xran_lib_compander_for_isa: %d\n", gCpuCapability);
@@ -89,11 +80,7 @@ xranlib_compress(const struct xranlib_compress_request *request,
return xranlib_5gnr_mod_compression(&mod_request, &mod_response);
}
else{
- if(XRANLIB_COMPAND_CHECK_CPU_CAPABILITY()) {
- return xranlib_compress_avxsnc(request,response);
- } else {
- return xranlib_compress_avx512(request,response);
- }
+ return xranlib_compress_avx512(request,response);
}
}
@@ -118,8 +105,6 @@ xranlib_decompress(const struct xranlib_decompress_request *request,
else{
if((gCpuCapability == 2)&&(request->SprEnable == 1)) {
return xranlib_decompress_5gisa(request,response);
- } else if(XRANLIB_COMPAND_CHECK_CPU_CAPABILITY()) {
- return xranlib_decompress_avxsnc(request,response);
} else {
return xranlib_decompress_avx512(request,response);
}
@@ -191,22 +176,14 @@ int32_t
xranlib_compress_bfw(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response)
{
- if(XRANLIB_COMPAND_CHECK_CPU_CAPABILITY()) {
- return xranlib_compress_avxsnc_bfw(request,response);
- } else {
- return xranlib_compress_avx512_bfw(request,response);
- }
+ return xranlib_compress_avx512_bfw(request,response);
}
int32_t
xranlib_decompress_bfw(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response)
{
- if(XRANLIB_COMPAND_CHECK_CPU_CAPABILITY()) {
- return xranlib_decompress_avxsnc_bfw(request,response);
- } else {
- return xranlib_decompress_avx512_bfw(request,response);
- }
+ return xranlib_decompress_avx512_bfw(request,response);
}
int32_t
diff --git a/fhi_lib/lib/src/xran_cp_api.c b/fhi_lib/lib/src/xran_cp_api.c
index 92a1edf..47e4afb 100644
--- a/fhi_lib/lib/src/xran_cp_api.c
+++ b/fhi_lib/lib/src/xran_cp_api.c
@@ -25,7 +25,11 @@
* @author Intel Corporation
*
**/
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include <rte_branch_prediction.h>
#include <rte_malloc.h>
@@ -839,7 +843,11 @@ xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *p
| (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
| (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
data_fourth_byte = params->beamIdAP1;
+#if defined(__arm__) || defined(__aarch64__)
+ ext3_f->data_field.data_field1 = (int32x4_t){data_first_byte, data_second_byte, data_third_byte, data_fourth_byte};
+#else
ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte);
+#endif
/* convert byte order */
tmp = (uint64_t *)ext3_f;
diff --git a/fhi_lib/lib/src/xran_cp_proc.c b/fhi_lib/lib/src/xran_cp_proc.c
index 52c9e72..d1e7dad 100644
--- a/fhi_lib/lib/src/xran_cp_proc.c
+++ b/fhi_lib/lib/src/xran_cp_proc.c
@@ -35,7 +35,10 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
@@ -640,7 +643,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx)
{
timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
- if ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME(xran_fs_get_tti_interval(mu)) >> 1)))
+ if (startSymId > 0 && ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME(xran_fs_get_tti_interval(mu)) >> 1))))
timeOffset += 16;
}
else
diff --git a/fhi_lib/lib/src/xran_delay_measurement.c b/fhi_lib/lib/src/xran_delay_measurement.c
index d8ffe60..b7b4c41 100644
--- a/fhi_lib/lib/src/xran_delay_measurement.c
+++ b/fhi_lib/lib/src/xran_delay_measurement.c
@@ -23,7 +23,10 @@
* @author Intel Corporation
**/
#define _GNU_SOURCE
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <assert.h>
#include <err.h>
#include <arpa/inet.h>
diff --git a/fhi_lib/lib/src/xran_dev.c b/fhi_lib/lib/src/xran_dev.c
index 5956ca4..675328d 100644
--- a/fhi_lib/lib/src/xran_dev.c
+++ b/fhi_lib/lib/src/xran_dev.c
@@ -35,7 +35,10 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 256fa1d..a9fd164 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -36,7 +36,11 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include <numa.h>
#include <rte_common.h>
#include <rte_eal.h>
@@ -122,6 +126,25 @@ int32_t xran_pkt_gen_desc_free(struct cp_up_tx_desc *p_desc);
int32_t xran_pkt_gen_process_ring(struct rte_ring *r);
int32_t xran_dl_pkt_ring_processing_func(void* args);
+void *mm_allocate_handle(size_t size, size_t alignment) {
+ void *ptr = NULL;
+#if defined(__arm__) || defined(__aarch64__)
+ // ARM-specific memory allocation
+ if (posix_memalign(&ptr, alignment, size) != 0) {
+ fprintf(stderr, "posix_memalign: allocation error\n");
+ return NULL;
+ }
+#else
+ // Intel-specific memory allocation
+ ptr = _mm_malloc(size, alignment);
+ if (ptr == NULL) {
+ fprintf(stderr, "_mm_malloc: allocation error\n");
+ return NULL;
+ }
+#endif
+ return ptr;
+}
+
void
xran_updateSfnSecStart(void)
{
@@ -334,8 +357,8 @@ int32_t xran_init_prach_lte(struct xran_fh_config* pConf, struct xran_device_ctx
pDevCtx->prach_start_symbol[0], pDevCtx->prach_last_symbol[0]);
}
- pPrachCPConfig->prachEaxcOffset = xran_get_num_eAxc(pDevCtx);
- print_dbg("PRACH: eAxC_offset %d\n", pPrachCPConfig->prachEaxcOffset);
+ pPrachCPConfig->prachEaxcOffset = pPRACHConfig->prachEaxcOffset;
+ print_dbg("PRACH: prachEaxcOffset %d\n", pPrachCPConfig->prachEaxcOffset);
/* Save some configs for app */
pPRACHConfig->startSymId = pPrachCPConfig->startSymId;
pPRACHConfig->lastSymId = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol * pPrachCPConfig->occassionsInPrachSlot - 1;
@@ -611,6 +634,11 @@ void xran_process_nbiot_prach_cp(struct xran_device_ctx * pDevCtx, uint8_t mu)
uint8_t seqid = xran_get_cp_seqid(pDevCtx, XRAN_DIR_UL, ccId, portId);
uint16_t beam_id = xran_get_beamid(pDevCtx, XRAN_DIR_UL, ccId, portId, 0);
+ uint8_t bufId = tti % XRAN_N_FE_BUF_LEN;
+ struct xran_buffer_list *pBufList = &(pDevCtx->perMu[mu].sFrontHaulRxPrbMapBbuIoBufCtrl[bufId][ccId][antId].sBufferList);
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
+ beam_id = pPrbElm->nBeamIndex;
ret = generate_cpmsg_prach(pDevCtx, &params, sect_geninfo, mbuf, pDevCtx,
frameId, sfId, 0, tti,
beam_id, ccId, portId, 0, seqid, mu, sym_id);
@@ -1880,6 +1908,10 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, ccId, portId);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, ccId, portId, slotId);
+ pBufList = &(pDevCtx->perMu[mu].sFrontHaulRxPrbMapBbuIoBufCtrl[bufId][ccId][antId].sBufferList);
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
+ beam_id = pPrbElm->nBeamIndex;
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, pDevCtx,
frameId, sfId, slotId, tti,
beam_id, ccId, portId, occasionid, seqid, mu, 0);
@@ -2128,6 +2160,10 @@ void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, ccId, portId);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, ccId, portId, slotId);
+ pBufList = &(pDevCtx->perMu[mu].sFrontHaulRxPrbMapBbuIoBufCtrl[bufId][ccId][antId].sBufferList);
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
+ beam_id = pPrbElm->nBeamIndex;
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, pDevCtx,
frameId, sfId, slotId, tti,
beam_id, ccId, portId, occasionid, seqid, mu, 0);
@@ -2309,16 +2345,21 @@ int32_t xran_handle_rx_pkts(struct rte_mbuf* pkt_q[], uint16_t xport_id, struct
// ECPRI payload validation
if(likely(sysCfg->rru_workaround == 0))
{
- if(unlikely(expected_ecpri_payload != (rte_pktmbuf_pkt_len(pkt) - sizeof(union xran_ecpri_cmn_hdr))))
- {
- ++p_dev_ctx->fh_counters.rx_err_ecpri;
- ++p_dev_ctx->fh_counters.rx_err_drop;
- ++p_dev_ctx->fh_counters.rx_counter;
- rte_pktmbuf_free(pkt);
- continue;
+ uint16_t size_tail = (rte_pktmbuf_pkt_len(pkt) - sizeof(union xran_ecpri_cmn_hdr)) - expected_ecpri_payload;
+ if(size_tail > 0) {
+ int trim_ret = rte_pktmbuf_trim(pkt, size_tail);
+ if(unlikely(trim_ret != 0))
+ {
+ ++p_dev_ctx->fh_counters.rx_err_ecpri;
+ ++p_dev_ctx->fh_counters.rx_err_drop;
+ ++p_dev_ctx->fh_counters.rx_counter;
+ rte_pktmbuf_free(pkt);
+ continue;
+ }
}
}
pkt_data[num_data++] = pkt;
+ uint8_t *pkt_bytes = rte_pktmbuf_mtod(pkt, uint8_t*);
break;
// For RU emulation
case ECPRI_RT_CONTROL_DATA:
@@ -3663,8 +3704,7 @@ ring_processing_func_per_port(void* args)
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) {
if (ctx->vf2xran_port[i] == portId) {
for(qi = 0; qi < ctx->rxq_per_port[portId]; qi++){
- if (process_ring(ctx->rx_ring[i][qi], i, qi))
- return 0;
+ process_ring(ctx->rx_ring[i][qi], i, qi);
}
}
}
@@ -3708,7 +3748,7 @@ xran_status_t xran_update_worker_info(struct xran_worker_info_s *p_worker_info,
continue;
}
- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64);
+ pThCtx = (struct xran_worker_th_ctx*) mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64);
if(pThCtx == NULL)
{
print_err("pThCtx allocation error\n");
@@ -3838,8 +3878,6 @@ int32_t xran_spawn_workers(void)
}
}
- icx_cpu = _may_i_use_cpu_feature(_FEATURE_AVX512IFMA52);
-
printf("ORAN operating mode: O-%s\n", (xran_get_syscfg_appmode() == ID_O_DU) ?"DU":"RU");
printf(" Num of configured cores: %d%s\n", total_num_cores, icx_cpu?" (Xeon SP Gen3 or later)":"");
printf(" Num of configured RUs : %d\n", numRUs);
@@ -5018,14 +5056,13 @@ int32_t xran_start(void *pHandle)
return 0;
}
-int32_t xran_activate_cc(int32_t port_id, int32_t cc_id)
+int32_t xran_activate_cc(void *pHandle, int32_t cc_id)
{
- struct xran_device_ctx *pDevCtx;
+ struct xran_device_ctx *pDevCtx = (struct xran_device_ctx *)pHandle;
if(cc_id >= XRAN_MAX_SECTOR_NR)
return(-1);
- pDevCtx = xran_dev_get_ctx_by_id(port_id);
if(pDevCtx)
{
rte_spinlock_lock(&pDevCtx->spinLock);
@@ -5040,6 +5077,7 @@ int32_t xran_activate_cc(int32_t port_id, int32_t cc_id)
}
else
{
+ int32_t port_id = pDevCtx->xran_port_id;
printf("Invalid port(RU) index - %d\n", port_id);
return(-1);
}
@@ -5048,14 +5086,13 @@ int32_t xran_activate_cc(int32_t port_id, int32_t cc_id)
return(0);
}
-int32_t xran_deactivate_cc(int32_t port_id, int32_t cc_id)
+int32_t xran_deactivate_cc(void *pHandle, int32_t cc_id)
{
- struct xran_device_ctx *pDevCtx;
+ struct xran_device_ctx *pDevCtx = (struct xran_device_ctx *)pHandle;
if(cc_id >= XRAN_MAX_SECTOR_NR)
return(-1);
- pDevCtx = xran_dev_get_ctx_by_id(port_id);
if(pDevCtx)
{
rte_spinlock_lock(&pDevCtx->spinLock);
@@ -5070,6 +5107,7 @@ int32_t xran_deactivate_cc(int32_t port_id, int32_t cc_id)
}
else
{
+ int32_t port_id = pDevCtx->xran_port_id;
printf("Invalid port(RU) index - %d\n", port_id);
return(-1);
}
diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c
index 83d43e8..ff2321d 100644
--- a/fhi_lib/lib/src/xran_mem_mgr.c
+++ b/fhi_lib/lib/src/xran_mem_mgr.c
@@ -35,7 +35,11 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
diff --git a/fhi_lib/lib/src/xran_mod_compression.cpp b/fhi_lib/lib/src/xran_mod_compression.cpp
index c313beb..8408a42 100644
--- a/fhi_lib/lib/src/xran_mod_compression.cpp
+++ b/fhi_lib/lib/src/xran_mod_compression.cpp
@@ -749,10 +749,7 @@ int xranlib_5gnr_mod_compression(const struct xranlib_5gnr_mod_compression_reque
#ifdef C_Module_Used
return (xranlib_5gnr_mod_compression_c(request, response));
#else
- if(XRANLIB_COMPAND_CHECK_CPU_CAPABILITY())
- return (xranlib_5gnr_mod_compression_snc(request, response));
- else
- return (xranlib_5gnr_mod_compression_avx512(request, response));
+ return (xranlib_5gnr_mod_compression_avx512(request, response));
#endif
}
diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c
index 4ccd00e..b3e27e8 100644
--- a/fhi_lib/lib/src/xran_rx_proc.c
+++ b/fhi_lib/lib/src/xran_rx_proc.c
@@ -35,7 +35,11 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c
index 387cef8..f4a566f 100644
--- a/fhi_lib/lib/src/xran_timer.c
+++ b/fhi_lib/lib/src/xran_timer.c
@@ -32,7 +32,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include "xran_timer.h"
#include "xran_main.h"
diff --git a/fhi_lib/lib/src/xran_transport.c b/fhi_lib/lib/src/xran_transport.c
index 70337d6..645b2ef 100644
--- a/fhi_lib/lib/src/xran_transport.c
+++ b/fhi_lib/lib/src/xran_transport.c
@@ -27,7 +27,10 @@
#include <stdint.h>
#include <endian.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_config.h>
diff --git a/fhi_lib/lib/src/xran_tx_proc.c b/fhi_lib/lib/src/xran_tx_proc.c
index 2d05893..08e9952 100644
--- a/fhi_lib/lib/src/xran_tx_proc.c
+++ b/fhi_lib/lib/src/xran_tx_proc.c
@@ -35,7 +35,11 @@
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
+#if defined(__arm__) || defined(__aarch64__)
+#include <arm_neon.h>
+#else
#include <immintrin.h>
+#endif
#include <rte_common.h>
#include <rte_eal.h>
diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c
index f3b846e..3eda2de 100644
--- a/fhi_lib/lib/src/xran_up_api.c
+++ b/fhi_lib/lib/src/xran_up_api.c
@@ -25,7 +25,10 @@
*
**/
#include <inttypes.h>
+#if defined(__arm__) || defined(__aarch64__)
+#else
#include <immintrin.h>
+#endif
#include <rte_mbuf.h>
#include "xran_fh_o_du.h"
@@ -318,6 +321,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
uint8_t *subframe_id,
uint8_t *slot_id,
uint8_t *symb_id,
+ uint8_t *filter_id,
union ecpri_seq_id *seq_id,
uint16_t *num_prbu,
uint16_t *start_prbu,
@@ -328,7 +332,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
uint8_t *iqWidth,
- uint8_t oxu_port_id)
+ uint8_t oxu_port_id,
+ uint8_t *is_prach)
{
#if XRAN_MLOG_VAR
uint32_t mlogVar[10];
@@ -362,6 +367,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
return 0; /* packet too short */
radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value);
+ *is_prach = (radio_hdr->data_feature.filter_id > 0);
if (frame_id)
*frame_id = radio_hdr->frame_id;
@@ -375,6 +381,9 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
if (symb_id)
*symb_id = radio_hdr->sf_slot_sym.symb_id;
+ if (filter_id)
+ *filter_id = radio_hdr->data_feature.filter_id;
+
/* Process data section hdr */
struct data_section_hdr *data_hdr =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));

View File

@@ -63,7 +63,9 @@ RUN rm -f /etc/rhsm-host && \
gcc-toolset-13-gcc-c++ \
# python3-pip and pyyaml are used for conf template generation
python3-pip && \
pip3 install --ignore-installed pyyaml && \
pip3 install --ignore-installed \
pyyaml \
pyelftools && \
echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf

View File

@@ -38,7 +38,8 @@ RUN apt-get update && \
wget \
xz-utils \
pkg-config \
libnuma-dev && \
libnuma-dev \
python3-pyelftools && \
rm -rf /var/lib/apt/lists/*
RUN rm -Rf /oai-ran
@@ -46,20 +47,20 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
meson build && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-22.11.7.tar.xz && \
tar -xf dpdk-22.11.7.tar.xz && \
cd dpdk-stable-22.11.7 && \
meson build -Dplatform=generic && \
ninja -C build && \
ninja install -C build
## Build Fronthaul library
RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-22.11.7/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
## Build Arm RAN Acceleration Library
RUN git clone https://git.gitlab.arm.com/networking/ral.git /opt/ral && \

View File

@@ -33,9 +33,9 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-22.11.7.tar.xz && \
tar -xf dpdk-22.11.7.tar.xz && \
cd dpdk-stable-22.11.7 && \
meson build && \
ninja -C build && \
ninja install -C build
@@ -43,10 +43,10 @@ RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
## Build Fronthaul library
RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-22.11.7/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
FROM ran-base AS ran-build-fhi72
ARG E2AP_VERSION=E2AP_V3

View File

@@ -38,7 +38,8 @@ RUN apt-get update && \
wget \
xz-utils \
pkg-config \
libnuma-dev && \
libnuma-dev \
python3-pyelftools && \
rm -rf /var/lib/apt/lists/*
RUN rm -Rf /oai-ran
@@ -46,9 +47,9 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-22.11.7.tar.xz && \
tar -xf dpdk-22.11.7.tar.xz && \
cd dpdk-stable-22.11.7 && \
meson build && \
ninja -C build && \
ninja install -C build
@@ -56,10 +57,10 @@ RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
## Build Fronthaul library
RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-22.11.7/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
FROM ran-base AS ran-build-fhi72
## Build and install OAI

View File

@@ -59,6 +59,7 @@ RUN rm -f /etc/rhsm-host && \
python3-pip \
net-tools \
iputils \
libatomic \
yaml-cpp-devel && \
pip3 install six && \
pip3 install requests && \

View File

@@ -36,6 +36,7 @@ ENV TZ=Europe/Paris
RUN dnf update -y && \
dnf install -y \
procps-ng \
libatomic \
libXpm \
libX11 \
lksctp-tools \

View File

@@ -59,6 +59,7 @@ RUN apt-get update && \
python3 \
python3-six \
python3-requests \
libatomic1 \
libyaml-cpp-dev && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \

View File

@@ -376,9 +376,6 @@ int stop_L1(module_id_t gnb_id)
if (RC.nb_nr_L1_inst > 0)
stop_gNB(RC.nb_nr_L1_inst);
if (RC.nb_RU > 0)
stop_RU(RC.nb_RU);
/* stop trx devices, multiple carrier currently not supported by RU */
if (ru->rfdevice.trx_get_stats_func) {
ru->rfdevice.trx_get_stats_func(&ru->rfdevice);
@@ -396,6 +393,9 @@ int stop_L1(module_id_t gnb_id)
LOG_I(GNB_APP, "turned off RU ifdevice\n");
}
if (RC.nb_RU > 0)
stop_RU(RC.nb_RU);
/* release memory used by the RU/gNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
for (int inst = 0; inst < RC.nb_RU; inst++) {

View File

@@ -17,14 +17,17 @@ add_library(oran_fhlib_5g MODULE
)
set(F_VERSION 6.1.8)
set(K_VERSION 11.1.1)
find_package(xran REQUIRED)
if(xran_VERSION MATCHES "5.*")
message(FATAL_ERROR "xran E release not supported starting from tag 2026.w08.\nPlease switch to F version ${F_VERSION}")
elseif(xran_VERSION VERSION_EQUAL F_VERSION)
target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE)
elseif(xran_VERSION VERSION_EQUAL K_VERSION)
target_compile_definitions(oran_fhlib_5g PRIVATE K_RELEASE)
else()
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed ${F_VERSION} (F release)")
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed ${F_VERSION} (F release) or ${K_VERSION} (K release)")
endif()
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress

View File

@@ -10,6 +10,8 @@ if(xran_VERSION MATCHES "5.*")
message(FATAL_ERROR "xran E release not supported starting from tag 2026.w08.\nPlease switch to F version ${F_VERSION}")
elseif(xran_VERSION VERSION_EQUAL F_VERSION)
target_compile_definitions(oran_fhlib_5g_mplane PRIVATE F_RELEASE)
elseif(xran_VERSION VERSION_EQUAL K_VERSION)
target_compile_definitions(oran_fhlib_5g_mplane PRIVATE K_RELEASE)
endif()
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress

View File

@@ -52,14 +52,25 @@
// Declare variable useful for the send buffer function
volatile bool first_call_set = false;
int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id);
int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id
#if defined K_RELEASE
, uint8_t mu
#endif
);
#include "common/utils/LOG/log.h"
#ifndef USE_POLLING
extern notifiedFIFO_t oran_sync_fifo;
atomic_int xran_queue_length = 0;
#if defined K_RELEASE
extern notifiedFIFO_t oran_sync_fifo_prach;
#endif
#else
volatile oran_sync_info_t oran_sync_info = {0};
#if defined K_RELEASE
volatile oran_sync_info_t oran_sync_info_prach = {0};
volatile bool prach_rx_awaiting = false;
#endif
#endif
/** @details xran-specific callback, called when all packets for given CC and
@@ -67,7 +78,11 @@ volatile oran_sync_info_t oran_sync_info = {0};
* timing information and unblock another thread in xran_fh_rx_read_slot()
* through either a message queue, or writing in global memory with polling, on
* a full slot boundary. */
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status
#if defined K_RELEASE
, uint8_t mu
#endif
)
{
struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag;
@@ -77,9 +92,13 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
const struct xran_fh_init *fh_init = get_xran_fh_init();
int num_ports = fh_init->xran_ports;
#if defined K_RELEASE
const int slots_in_sf = 1 << mu;
#elif defined F_RELEASE
/* assuming all RUs have the same numerology */
const struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
const int slots_in_sf = 1 << fh_cfg->frame_conf.nNumerology;
#endif
const int sf_in_frame = 10;
static int rx_RU[XRAN_PORTS_NUM][160] = {0};
@@ -94,7 +113,6 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
LOG_D(HW, "rx_callback at %4d.%3d (subframe %d), rx_sym %d ru_id %d\n", frame, slot, subframe, rx_sym, ru_id);
if (rx_sym == 7) { // in F release this value is defined as XRAN_FULL_CB_SYM (full slot (offset + 7))
#if defined F_RELEASE
for (int ru_idx = 0; ru_idx < num_ports; ru_idx++) {
struct xran_fh_config *fh_config = get_xran_fh_config(ru_idx);
oran_buf_list_t *bufs = get_xran_buffers(ru_idx);
@@ -103,6 +121,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
#if defined F_RELEASE
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
LOG_D(HW, "cb pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) {
@@ -110,10 +129,10 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
pRbElm->nSecDesc[sym_id] = 0; // number of section descriptors per symbol; M-plane info <supported-section-types>
}
}
#endif
}
}
}
#endif
// if xran did not call xran_physide_dl_tti callback, it's not ready yet.
// wait till first callback to advance counters, because otherwise users
// would see periodic output with only "0" in stats counters
@@ -138,6 +157,26 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
info->tti = tti;
info->sl = slot2;
info->f = frame;
#if defined K_RELEASE
info->mu = mu;
oran_buf_list_t *bufs = get_xran_buffers(ru_id);
struct xran_fh_config *fh_config = get_xran_fh_config(ru_id);
for (uint16_t cc_id = 0; cc_id < 1 /* fh_config->nCC */; cc_id++) { // OAI does not support multiple CC yet.
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
// struct xran_prb_map *pRbMapPrach = (struct xran_prb_map *)bufs->prachdstdecomp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
// AssertFatal(pRbMapPrach != NULL, "(%d:%d:%d)pRbMapPrach == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
info->nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
// AssertFatal(pRbMapPrach->sFrontHaulRxPacketCtrl[sym_id].nRxPkt <= 1, "PRACH segmentation is not supported\n");
// pRbMapPrach->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
}
}
}
#endif
LOG_D(HW, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot);
atomic_fetch_add(&xran_queue_length, 1);
pushNotifiedFIFO(&oran_sync_fifo, req);
@@ -146,6 +185,26 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
oran_sync_info.tti = tti;
oran_sync_info.sl = slot2;
oran_sync_info.f = frame;
#if defined K_RELEASE
oran_sync_info.mu = mu;
oran_buf_list_t *bufs = get_xran_buffers(ru_id);
struct xran_fh_config *fh_config = get_xran_fh_config(ru_id);
for (uint16_t cc_id = 0; cc_id < 1 /* fh_config->nCC */; cc_id++) { // OAI does not support multiple CC yet.
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
// struct xran_prb_map *pRbMapPrach = (struct xran_prb_map *)bufs->prachdstdecomp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
// AssertFatal(pRbMapPrach != NULL, "(%d:%d:%d)pRbMapPrach == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
oran_sync_info.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
// AssertFatal(pRbMapPrach->sFrontHaulRxPacketCtrl[sym_id].nRxPkt <= 1, "PRACH segmentation is not supported\n");
// pRbMapPrach->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
}
}
}
#endif
#endif
} else
LOG_E(HW, "Cannot Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
@@ -154,9 +213,112 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
} // rx_sym == 7
}
void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status
#if defined K_RELEASE
, uint8_t mu
#endif
)
{
#if defined K_RELEASE
struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag;
static int32_t last_slot = -1;
// static int32_t last_frame = -1;
const struct xran_fh_init *fh_init = get_xran_fh_init();
int num_ports = fh_init->xran_ports;
const int slots_in_sf = 1 << mu;
const int sf_in_frame = 10;
static int rx_RU[XRAN_PORTS_NUM][160] = {0};
uint32_t tti = callback_tag->slotiId;
uint32_t frame = XranGetFrameNum(tti, 0, sf_in_frame, slots_in_sf);
uint32_t subframe = XranGetSubFrameNum(tti, slots_in_sf, sf_in_frame);
uint32_t slot = XranGetSlotNum(tti, slots_in_sf);
uint32_t rx_sym = callback_tag->symbol & 0xFF;
uint32_t ru_id = callback_tag->oXuId;
LOG_D(HW, "prach_rx_callback at %4d.%3d (subframe %d), rx_sym %d ru_id %d\n", frame, slot, subframe, rx_sym, ru_id);
// if xran did not call xran_physide_dl_tti callback, it's not ready yet.
// wait till first callback to advance counters, because otherwise users
// would see periodic output with only "0" in stats counters
if (!first_call_set)
return;
uint32_t slot2 = slot + (subframe * slots_in_sf);
rx_RU[ru_id][slot2] = 1;
// if (last_frame > 0 && frame > 0
// && ((slot2 > 0 && last_frame != frame) || (slot2 == 0 && last_frame != ((1024 + frame - 1) & 1023))))
// LOG_E(HW, "Jump in frame counter last_frame %d => %d, slot %d\n", last_frame, frame, slot2);
for (int i = 0; i < num_ports; i++) {
if (rx_RU[i][slot2] == 0)
return;
}
for (int i = 0; i < num_ports; i++)
rx_RU[i][slot2] = 0;
if (last_slot == -1 || slot2 != last_slot) {
#ifndef USE_POLLING
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(oran_sync_info_t), 0, &oran_sync_fifo_prach, NULL);
oran_sync_info_t *info = NotifiedFifoData(req);
info->tti = tti;
info->sl = slot2;
info->f = frame;
info->mu = mu;
#else
LOG_D(HW, "Writing PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
oran_sync_info_prach.tti = tti;
oran_sync_info_prach.sl = slot2;
oran_sync_info_prach.f = frame;
oran_sync_info_prach.mu = mu;
#endif
int32_t ntti = (tti + XRAN_N_FE_BUF_LEN - 1) % XRAN_N_FE_BUF_LEN;
struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag;
uint32_t tti = callback_tag->slotiId;
uint32_t ru_id = callback_tag->oXuId;
oran_buf_list_t *bufs = get_xran_buffers(ru_id);
struct xran_fh_config *fh_config = get_xran_fh_config(ru_id);
for (uint16_t cc_id = 0; cc_id < 1 /* fh_config->nCC */; cc_id++) { // OAI does not support multiple CC yet.
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->prachdstdecomp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMapPrach == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
struct xran_prb_map *pRbMap_prev = (struct xran_prb_map *)bufs->prachdstdecomp[ant_id][ntti].pBuffers->pData;
AssertFatal(pRbMap_prev != NULL, "(%d:%d:%d)pRbMapPrach == NULL. Aborting.\n", cc_id, ntti, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
AssertFatal(pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt <= 1, "PRACH segmentation is not supported\n");
#ifndef USE_POLLING
info->nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
#else
oran_sync_info_prach.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
#endif
pRbMap_prev->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0; // Clear nRxPkt of previous slot.
}
}
}
#ifndef USE_POLLING
LOG_D(HW, "Push PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot);
pushNotifiedFIFO(&oran_sync_fifo_prach, req);
#else
prach_rx_awaiting = true;
#endif
} else
LOG_E(HW, "Cannot Push PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
last_slot = slot2;
// last_frame = frame;
#elif defined F_RELEASE
rte_pause();
#endif
}
/** @details Only used to unblock timing in oai_xran_fh_rx_callback() on first
* call. */
int oai_physide_dl_tti_call_back(void *param)
int oai_physide_dl_tti_call_back(void *param
#if defined K_RELEASE
, uint8_t mu
#endif
)
{
if (!first_call_set)
LOG_I(HW, "first_call set from phy cb\n");
@@ -169,8 +331,59 @@ int oai_physide_dl_tti_call_back(void *param)
* @details Reads PRACH data from xran-specific buffers and, if I/Q compression
* (bitwidth < 16 bits) is configured, uncompresses the data. Places PRACH data
* in OAI buffer. */
static int read_prach_data(ru_info_t *ru, int frame, int slot)
static int read_prach_data(ru_info_t *ru
#if defined F_RELEASE
, int frame, int slot
#endif
)
{
#if defined K_RELEASE
#ifndef USE_POLLING
// pull next even from oran_sync_fifo_prach if any
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo_prach);
if (res == NULL) {
return (0);
}
notifiedFIFO_elt_t *f;
while ((f = pollNotifiedFIFO(&oran_sync_fifo_prach)) != NULL) {
oran_sync_info_t *old_info = NotifiedFifoData(res);
oran_sync_info_t *new_info = NotifiedFifoData(f);
LOG_E(HW, "Detected double PRACH sync message %d.%d => %d.%d\n", old_info->f, old_info->sl, new_info->f, new_info->sl);
delNotifiedFIFO_elt(res);
res = f;
}
oran_sync_info_t *info = NotifiedFifoData(res);
int slot = info->sl;
int frame = info->f;
uint8_t mu = info->mu;
delNotifiedFIFO_elt(res);
#else
#error "POLLING is not supported for K release unless you know how to fix the race condition on prach_rx_awaiting"
if (!prach_rx_awaiting) {
return (0);
} else {
prach_rx_awaiting = false;
}
int slot = oran_sync_info_prach.sl;
int frame = oran_sync_info_prach.f;
uint8_t mu = oran_sync_info_prach.mu;
uint32_t tti_in = oran_sync_info_prach.tti;
static int last_slot = -1;
LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot);
int cnt = 0;
// while (*slot == last_slot) {
while (tti_in == oran_sync_info_prach.tti) {
//*slot = oran_sync_info.sl;
cnt++;
}
LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot);
last_slot = *slot;
#endif
#endif
/* calculate tti and subframe_id from frame, slot num */
int sym_idx = 0;
@@ -181,6 +394,17 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
int prach_start_sym = prach_info.start_symbol;
int prach_end_sym = prach_info.N_dur + prach_start_sym;
struct xran_ru_config *ru_conf = &fh_cfg->ru_conf;
#if defined K_RELEASE
int slots_per_frame = 10 << mu;
int slots_per_subframe = 1 << mu;
int tti = slots_per_frame * (frame) + (slot);
uint32_t subframe = slot / slots_per_subframe;
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
uint32_t is_prach_frame = (frame % prach_info.x == prach_info.y);
uint32_t is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (slot % slots_per_subframe), mu);
#elif defined F_RELEASE
int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology;
int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology;
@@ -189,22 +413,45 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
uint32_t is_prach_frame = (frame % prach_info.x == prach_info.y);
uint32_t is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (slot % slots_per_subframe));
#endif
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
/* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */
if (is_prach_slot) {
if (!ru->prach_buf) {
LOG_W(HW, "we get rach data from ru, but it is not scheduled %d.%d\n", frame, slot);
return -1;
}
for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) {
for (int aa = 0; aa < ru->nb_rx; aa++) {
for (int aa = 0; aa < ru->nb_rx; aa++) {
for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) {
int16_t *dst, *src;
int idx = 0;
oran_buf_list_t *bufs = get_xran_buffers(aa / nb_rx_per_ru);
// hardcoded to use only first prach occasion
dst = (int16_t *)ru->prach_buf[0][aa];
#if defined K_RELEASE
struct xran_prb_map * pPrbMap = (struct xran_prb_map *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_rx_packet_ctl *p_rx_packet_ctl = &pPrbMap->sFrontHaulRxPacketCtrl[sym_idx];
if (p_rx_packet_ctl->nRxPkt == 0) {
//LOG_E(HW, "read_prach %d.%d.%d saa = %d: nRxPkt = 0!\n", frame, slot, sym_idx, aa); // comment out as this happens at the beginning
memset(&dst[sym_idx], 0, 139 * 2 * sizeof(*dst));
continue;
} else if (p_rx_packet_ctl->nRxPkt > 1) { // protection
LOG_E(HW, "read_prach %d.%d.%d saa = %d: nRxPkt = %d!\n", frame, slot, sym_idx, aa, p_rx_packet_ctl->nRxPkt);
memset(&dst[sym_idx], 0, 139 * 2 * sizeof(*dst));
continue;
} else {
src = (int16_t *)p_rx_packet_ctl->pData[0];
if (src == NULL) { // protection
LOG_E(HW, "read_prach %d.%d.%d saa = %d: src = NULL!!\n", frame, slot, sym_idx, aa);
memset(&dst[sym_idx], 0, 139 * 2 * sizeof(*dst));
continue;
}
}
#elif defined F_RELEASE
src = (int16_t *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx].pData;
#endif
/* convert Network order to host order */
if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) {
if (sym_idx == prach_start_sym) {
@@ -285,11 +532,14 @@ static bool is_tdd_dl_symbol(const struct xran_frame_config *frame_conf, int slo
return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 0 /* DL */;
}
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
/** @brief Check if current slot is guard/mixed */
static bool is_tdd_guard_slot(const struct xran_frame_config *frame_conf, int slot)
{
return (is_tdd_dl_symbol(frame_conf, slot, 0) && is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1));
}
#endif
/** @brief Check if current slot is DL or guard/mixed without UL (i.e., current
* slot is not UL). */
@@ -348,10 +598,16 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
*slot = info->sl;
*frame = info->f;
#if defined K_RELEASE
uint8_t mu = info->mu;
#endif
delNotifiedFIFO_elt(res);
#else
*slot = oran_sync_info.sl;
*frame = oran_sync_info.f;
#if defined K_RELEASE
uint8_t mu = oran_sync_info.mu;
#endif
uint32_t tti_in = oran_sync_info.tti;
static int last_slot = -1;
@@ -368,14 +624,26 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
// return(0);
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
#if defined K_RELEASE
int slots_per_frame = 10 << mu;
#elif defined F_RELEASE
int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology;
#endif
int tti = slots_per_frame * (*frame) + (*slot);
read_prach_data(ru, *frame, *slot);
read_prach_data(ru
#if defined F_RELEASE
, *frame, *slot
#endif
);
const struct xran_fh_init *fh_init = get_xran_fh_init();
#if defined K_RELEASE
int fftsize = 1 << fh_cfg->perMu[mu].nULFftSize;
#elif defined F_RELEASE
int fftsize = 1 << fh_cfg->nULFftSize;
#endif
int slot_offset_rxdata = 3 & (*slot);
uint32_t slot_size = 4 * 14 * fftsize;
@@ -409,13 +677,39 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
int start_totalRB = pRbMap->prbMap[0].nRBStart;
int32_t local_dst[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64)));
#if defined K_RELEASE
// TODO Shall we use the struct xran_prb_elm with K_RELEASE or not?
struct xran_prb_elm *pRbElm = &pRbMap->prbMap[0];
struct xran_rx_packet_ctl *p_rx_packet_ctl = &pRbMap->sFrontHaulRxPacketCtrl[sym_idx];
uint32_t one_rb_size =
(((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1));
#ifndef USE_POLLING
int32_t nRxPkt = RTE_MAX(p_rx_packet_ctl->nRxPkt, info->nRxPkt[cc_id][ant_id][sym_idx]);
#else
int32_t nRxPkt = RTE_MAX(p_rx_packet_ctl->nRxPkt, oran_sync_info.nRxPkt[cc_id][ant_id][sym_idx]);
#endif
LOG_D(HW, "nRxPkt %d\n", nRxPkt);
for (int pkt_idx = 0; pkt_idx < nRxPkt; pkt_idx++) {
uint8_t *pData;
if (fh_init->mtu < p_rx_packet_ctl->nRBSize[pkt_idx] * one_rb_size)
pData = bufs->dst[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN]
.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT]
.pData;
else
pData = p_rx_packet_ctl->pData[pkt_idx];
int numRB = p_rx_packet_ctl->nRBSize[pkt_idx];
int startRB = p_rx_packet_ctl->nRBStart[pkt_idx];
// num_prbu & start_prbu are for UL U-plane only
LOG_D(HW, "p_rx_packet_ctl[%d] startRB[%d]:numRB[%d]\n", pkt_idx, startRB, numRB);
{
{
#elif defined F_RELEASE
LOG_D(HW, "[%d.%d] pRbMap->nPrbElm %d\n", *frame, *slot, pRbMap->nPrbElm);
for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
int numRB, startRB;
uint8_t *pData;
struct xran_section_desc *p_sec_desc = NULL;
struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm];
#if defined F_RELEASE
// UP_nRBSize & UP_nRBStart are for DL U-plane only
LOG_D(HW, "[%d.%d] idxElm[%d] startSym[%d]:numSym[%d] UP_startRB[%d]:UP_numRB[%d] sym_idx[%d] ant_id[%d] pRbElm->nRBStart[%d]:pRbElm->nRBSize[%d]\n", *frame, *slot, idxElm, pRbElm->nStartSymb, pRbElm->numSymb, pRbElm->UP_nRBStart, pRbElm->UP_nRBSize, sym_idx, ant_id, pRbElm->nRBStart, pRbElm->nRBSize);
for (int idxDesc = 0; idxDesc < XRAN_MAX_FRAGMENT; idxDesc++) {
@@ -511,6 +805,18 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
x_counters[o_xu_id].rx_pusch_packets[rxant],
rxant,
x_counters[o_xu_id].rx_prach_packets[rxant]);
#if defined K_RELEASE
LOG_I(HW,
"[%s%d][drop errors %7d ecpri errors %7d cp errors %7d up errors %7d pusch errors %7d prach errors %7d]\n",
"o_du",
o_xu_id,
x_counters[o_xu_id].rx_err_drop,
x_counters[o_xu_id].rx_err_ecpri,
x_counters[o_xu_id].rx_err_cp,
x_counters[o_xu_id].rx_err_up,
x_counters[o_xu_id].rx_err_pusch,
x_counters[o_xu_id].rx_err_prach);
#endif
if (x_counters[o_xu_id].rx_counter > old_rx_counter[o_xu_id])
old_rx_counter[o_xu_id] = x_counters[o_xu_id].rx_counter;
if (x_counters[o_xu_id].tx_counter > old_tx_counter[o_xu_id])
@@ -534,7 +840,12 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
const struct xran_fh_init *fh_init = get_xran_fh_init();
const struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
#if defined K_RELEASE
uint8_t mu_number = fh_cfg->mu_number[0];
int fftsize = 1 << fh_cfg->perMu[mu_number].nDLFftSize;
#elif defined F_RELEASE
int fftsize = 1 << fh_cfg->nDLFftSize;
#endif
int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports;
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
@@ -563,12 +874,15 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
for (uint32_t idxElm = 0; idxElm < pPrbMap->nPrbElm; idxElm++) {
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[idxElm];
int numRB, startRB;
#if defined F_RELEASE
numRB = pRbElm->UP_nRBSize;
startRB = pRbElm->UP_nRBStart;
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
struct xran_section_desc *p_sec_desc = &pRbElm->sec_desc[sym_idx][0];
#endif
LOG_D(HW, "pPrbMap[%d] : PRBstart %d nPRBs %d\n", idxElm, startRB, numRB);
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx.
if (fh_cfg->RunSlotPrbMapBySymbolEnable) {
if (sym_idx >= pRbElm->nStartSymb && sym_idx < pRbElm->nStartSymb + pRbElm->numSymb) {
@@ -581,6 +895,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
pRbElm->nBeamIndex = 0;
}
} else {
#endif
if (first) {
// ant_id / no of antenna per beam gives the beam_nb
pRbElm->nBeamIndex =
@@ -592,7 +907,10 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
first = 0;
}
}
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
}
#endif
}
}
}
@@ -607,6 +925,8 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
continue;
}
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable. Set nPrbElm if beam_id = -1 for all downlink symbols
if (fh_cfg->RunSlotPrbMapBySymbolEnable) {
bool beam_used = false;
@@ -633,6 +953,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
continue;
}
}
#endif
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
@@ -677,15 +998,19 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
// => seems that the RUs don't check for E-bit
#if defined F_RELEASE
p_sec_desc = &p_prbMapElm->sec_desc[sym_idx][0];
#elif K_RELEASE
p_sec_desc = &p_prbMapElm->sec_desc[sym_idx];
#endif
int16_t startRB = p_prbMapElm->UP_nRBStart;
int16_t numRB = p_prbMapElm->UP_nRBSize;
#endif
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx.
if (fh_cfg->RunSlotPrbMapBySymbolEnable) {
/* skip, if not scheduled */
@@ -700,6 +1025,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
if (p_prbMapElm->nBeamIndex == -1)
p_prbMapElm->nBeamIndex = 0;
} else {
#endif
if (sym_idx == 0) {
// ant_id / no of antenna per beam gives the beam_nb
p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT];
@@ -707,7 +1033,10 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
if (p_prbMapElm->nBeamIndex == -1)
p_prbMapElm->nBeamIndex = 0;
}
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
}
#endif
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);

View File

@@ -29,11 +29,29 @@ typedef struct {
uint32_t tti;
uint32_t sl;
uint32_t f;
#if defined K_RELEASE
uint8_t mu;
int32_t nRxPkt[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
#endif
} oran_sync_info_t;
/** @brief xran callback for fronthaul RX, see xran_5g_fronthault_config(). */
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status);
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status
#if defined K_RELEASE
, uint8_t mu
#endif
);
/** @brief xran callback for fronthaul PRACH RX, see xran_5g_prach_req(). */
void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status
#if defined K_RELEASE
, uint8_t mu
#endif
);
/** @brief xran callback for time alignment, see xran_reg_physide_cb(). */
int oai_physide_dl_tti_call_back(void *param);
int oai_physide_dl_tti_call_back(void *param
#if defined K_RELEASE
, uint8_t mu
#endif
);
#endif /* OAIORAN_H */

View File

@@ -124,11 +124,9 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
io_cfg->one_vf_cu_plane);
print_fh_eowd_cmn(io_cfg->id, &io_cfg->eowd_cmn[io_cfg->id]);
printf("eowd_port (filled within xran library)\n");
#if defined F_RELEASE
printf("\
bbu_offload %d\n",
io_cfg->bbu_offload);
#endif
}
static void print_fh_init_eaxcid_conf(const struct xran_eaxcid_config *eaxcid_conf)
@@ -170,7 +168,11 @@ void print_fh_init(const struct xran_fh_init *fh_init)
{
printf("xran_fh_init:\n");
print_fh_init_io_cfg(&fh_init->io_cfg);
#if defined K_RELEASE
print_fh_init_eaxcid_conf(&fh_init->eAxCId_conf[0]);
#elif defined F_RELEASE
print_fh_init_eaxcid_conf(&fh_init->eAxCId_conf);
#endif
printf("\
xran_ports %d\n\
dpdkBasebandFecMode %d\n\
@@ -189,34 +191,58 @@ void print_fh_init(const struct xran_fh_init *fh_init)
printf("\
totalBfWeights %d\n",
fh_init->totalBfWeights);
#if defined F_RELEASE
printf("\
mlogxranenable %d\n\
dlCpProcBurst %d\n",
fh_init->mlogxranenable,
fh_init->dlCpProcBurst);
#endif
}
static void print_prach_config(const struct xran_prach_config *prach_conf)
{
printf("\
prach_config:\n\
nPrachConfIdx %d\n\
nPrachSubcSpacing %d\n\
nPrachZeroCorrConf %d\n\
nPrachRestrictSet %d\n\
nPrachRootSeqIdx %d\n\
nPrachFreqStart %d\n\
nPrachFreqOffset %d\n\
nPrachFilterIdx %d\n\
startSymId %d\n\
lastSymId %d\n\
startPrbc %d\n\
numPrbc %d\n\
timeOffset %d\n\
freqOffset %d\n\
eAxC_offset %d\n",
"
#if defined K_RELEASE
" prach_config:\n\
nPrachConfIdx %d\n\
nPrachSubcSpacing %d\n\
nPrachZeroCorrConf %d\n\
nPrachRestrictSet %d\n\
nPrachRootSeqIdx %d\n\
nPrachFreqStart %d\n\
nPrachFreqOffset %d\n\
nPrachFilterIdx %d\n\
startSymId %d\n\
lastSymId %d\n\
startPrbc %d\n\
numPrbc %d\n\
timeOffset %d\n\
freqOffset %d\n\
prachEaxcOffset %d\n\
nprachformat %d\n\
periodicity %d\n\
startTime %d\n\
suboffset %d\n\
numSubCarriers %d\n\
nRep %d\n",
#elif defined F_RELEASE
" prach_config:\n\
nPrachConfIdx %d\n\
nPrachSubcSpacing %d\n\
nPrachZeroCorrConf %d\n\
nPrachRestrictSet %d\n\
nPrachRootSeqIdx %d\n\
nPrachFreqStart %d\n\
nPrachFreqOffset %d\n\
nPrachFilterIdx %d\n\
startSymId %d\n\
lastSymId %d\n\
startPrbc %d\n\
numPrbc %d\n\
timeOffset %d\n\
freqOffset %d\n\
eAxC_offset %d\n",
#endif
prach_conf->nPrachConfIdx,
prach_conf->nPrachSubcSpacing,
prach_conf->nPrachZeroCorrConf,
@@ -231,33 +257,55 @@ static void print_prach_config(const struct xran_prach_config *prach_conf)
prach_conf->numPrbc,
prach_conf->timeOffset,
prach_conf->freqOffset,
prach_conf->eAxC_offset);
#if defined F_RELEASE
#if defined K_RELEASE
prach_conf->prachEaxcOffset,
prach_conf->nprachformat,
prach_conf->periodicity,
prach_conf->startTime,
prach_conf->suboffset,
prach_conf->numSubCarriers,
prach_conf->nRep
#elif defined F_RELEASE
prach_conf->eAxC_offset
#endif
);
printf("\
nPrachConfIdxLTE %d\n",
prach_conf->nPrachConfIdxLTE);
#endif
}
static void print_srs_config(const struct xran_srs_config *srs_conf)
{
printf("\
srs_config:\n\
symbMask %04x\n\
eAxC_offset %d\n",
symbMask %04x\n"
#if defined K_RELEASE
" srsEaxcOffset %d\n",
#elif defined F_RELEASE
" eAxC_offset %d\n",
#endif
srs_conf->symbMask,
srs_conf->eAxC_offset);
#if defined K_RELEASE
srs_conf->srsEaxcOffset
#elif defined F_RELEASE
srs_conf->eAxC_offset
#endif
);
}
static void print_frame_config(const struct xran_frame_config *frame_conf)
{
printf("\
frame_conf:\n\
nFrameDuplexType %s\n\
nNumerology %d\n\
nTddPeriod %d\n",
nFrameDuplexType %s\n"
#if defined F_RELEASE
" nNumerology %d\n"
#endif
" nTddPeriod %d\n",
frame_conf->nFrameDuplexType == XRAN_TDD ? "TDD" : "FDD",
#if defined F_RELEASE
frame_conf->nNumerology,
#endif
frame_conf->nTddPeriod);
for (int i = 0; i < frame_conf->nTddPeriod; ++i) {
printf(" sSlotConfig[%d]: ", i);
@@ -269,7 +317,11 @@ static void print_frame_config(const struct xran_frame_config *frame_conf)
}
}
static void print_ru_config(const struct xran_ru_config *ru_conf)
static void print_ru_config(
#if defined K_RELEASE
uint8_t mu_number,
#endif
const struct xran_ru_config *ru_conf)
{
printf("\
ru_config:\n\
@@ -279,9 +331,13 @@ static void print_ru_config(const struct xran_ru_config *ru_conf)
iqWidth %d\n\
compMeth %d\n\
iqWidth_PRACH %d\n\
compMeth_PRACH %d\n\
fftSize %d\n\
byteOrder %s\n\
compMeth_PRACH %d\n"
#if defined K_RELEASE
" fftSize[mu_number] %d\n"
#elif defined F_RELEASE
" fftSize %d\n"
#endif
" byteOrder %s\n\
iqOrder %s\n\
xran_max_frame %d\n",
ru_conf->xranTech == XRAN_RAN_5GNR ? "NR" : "LTE",
@@ -291,27 +347,106 @@ static void print_ru_config(const struct xran_ru_config *ru_conf)
ru_conf->compMeth,
ru_conf->iqWidth_PRACH,
ru_conf->compMeth_PRACH,
#if defined K_RELEASE
ru_conf->fftSize[mu_number],
#elif defined F_RELEASE
ru_conf->fftSize,
#endif
ru_conf->byteOrder == XRAN_NE_BE_BYTE_ORDER ? "network/BE" : "CPU/LE",
ru_conf->iqOrder == XRAN_I_Q_ORDER ? "I_Q" : "Q_I",
ru_conf->xran_max_frame);
}
#if defined K_RELEASE
void print_fh_per_mu_cfg(const struct xran_fh_per_mu_cfg *perMu)
{
printf("\
perMu:\n\
nDLBandwidth %d\n\
nULBandwidth %d\n",
perMu->nDLBandwidth,
perMu->nULBandwidth);
print_prach_config(&perMu->prach_conf);
printf("\
freqOffset %d\n\
nDLFftSize %d\n\
nULFftSize %d\n\
eaxcOffset %d\n\
nDLRBs %d\n\
nULRBs %d\n\
Tadv_cp_dl %d\n\
T2a_min_cp_dl %d\n\
T2a_max_cp_dl %d\n\
T2a_min_cp_ul %d\n\
T2a_max_cp_ul %d\n\
T2a_min_up %d\n\
T2a_max_up %d\n\
Ta3_min %d\n\
Ta3_max %d\n\
T1a_min_cp_dl %d\n\
T1a_max_cp_dl %d\n\
T1a_min_cp_ul %d\n\
T1a_max_cp_ul %d\n\
T1a_min_up %d\n\
T1a_max_up %d\n\
Ta4_min %d\n\
Ta4_max %d\n\
prachEnable %d\n\
prachConfigIndex %d\n\
prachConfigIndexLTE %d\n\
nbIotUlScs %d\n\
adv_tx_time %d\n",
perMu->freqOffset,
perMu->nDLFftSize,
perMu->nULFftSize,
perMu->eaxcOffset,
perMu->nDLRBs,
perMu->nULRBs,
perMu->Tadv_cp_dl,
perMu->T2a_min_cp_dl,
perMu->T2a_max_cp_dl,
perMu->T2a_min_cp_ul,
perMu->T2a_max_cp_ul,
perMu->T2a_min_up,
perMu->T2a_max_up,
perMu->Ta3_min,
perMu->Ta3_max,
perMu->T1a_min_cp_dl,
perMu->T1a_max_cp_dl,
perMu->T1a_min_cp_ul,
perMu->T1a_max_cp_ul,
perMu->T1a_min_up,
perMu->T1a_max_up,
perMu->Ta4_min,
perMu->Ta4_max,
perMu->prachEnable,
perMu->prachConfigIndex,
perMu->prachConfigIndexLTE,
perMu->nbIotUlScs,
perMu->adv_tx_time);
}
#endif
void print_fh_config(const struct xran_fh_config *fh_config)
{
printf("xran_fh_config:\n");
printf("\
dpdk_port %d\n\
sector_id %d\n\
nCC %d\n\
neAxc %d\n\
neAxcUl %d\n\
nAntElmTRx %d\n\
nDLFftSize %d\n\
nAntElmTRx %d\n"
#if defined F_RELEASE
" nDLFftSize %d\n\
nULFftSize %d\n\
nDLRBs %d\n\
nULRBs %d\n\
nDLAbsFrePointA %d\n\
nULRBs %d\n"
#endif
" nDLAbsFrePointA %d\n\
nULAbsFrePointA %d\n\
nDLCenterFreqARFCN %d\n\
nULCenterFreqARFCN %d\n\
@@ -323,17 +458,23 @@ void print_fh_config(const struct xran_fh_config *fh_config)
fh_config->neAxc,
fh_config->neAxcUl,
fh_config->nAntElmTRx,
#if defined F_RELEASE
fh_config->nDLFftSize,
fh_config->nULFftSize,
fh_config->nDLRBs,
fh_config->nULRBs,
#endif
fh_config->nDLAbsFrePointA,
fh_config->nULAbsFrePointA,
fh_config->nDLCenterFreqARFCN,
fh_config->nULCenterFreqARFCN,
fh_config->ttiCb,
fh_config->ttiCbParam);
#if defined K_RELEASE
uint8_t mu_number = fh_config->mu_number[0];
print_fh_per_mu_cfg(&fh_config->perMu[mu_number]);
#endif
#if defined F_RELEASE
printf("\
Tadv_cp_dl %d\n\
T2a_min_cp_dl %d\n\
@@ -369,45 +510,49 @@ void print_fh_config(const struct xran_fh_config *fh_config)
fh_config->T1a_max_up,
fh_config->Ta4_min,
fh_config->Ta4_max);
#endif
printf("\
enableCP %d\n\
prachEnable %d\n\
srsEnable %d\n\
enableCP %d\n"
#if defined F_RELEASE
" prachEnable %d\n"
#endif
" srsEnable %d\n\
puschMaskEnable %d\n\
puschMaskSlot %d\n\
cp_vlan_tag %d\n\
up_vlan_tag %d\n\
debugStop %d\n\
debugStopCount %d\n\
DynamicSectionEna %d\n\
GPS_Alpha %d\n\
GPS_Beta %d\n",
fh_config->enableCP,
#if defined F_RELEASE
fh_config->prachEnable,
#endif
fh_config->srsEnable,
fh_config->puschMaskEnable,
fh_config->puschMaskSlot,
fh_config->cp_vlan_tag,
fh_config->up_vlan_tag,
fh_config->debugStop,
fh_config->debugStopCount,
fh_config->DynamicSectionEna,
fh_config->GPS_Alpha,
fh_config->GPS_Beta);
#if defined F_RELEASE
printf("\
srsEnableCp %d\n\
SrsDelaySym %d\n",
fh_config->srsEnableCp,
fh_config->SrsDelaySym);
#endif
#if defined F_RELEASE
print_prach_config(&fh_config->prach_conf);
#endif
print_srs_config(&fh_config->srs_conf);
print_frame_config(&fh_config->frame_conf);
print_ru_config(&fh_config->ru_conf);
print_ru_config(
#if defined K_RELEASE
mu_number,
#endif
&fh_config->ru_conf);
printf("\
bbdev_enc %p\n\
@@ -429,17 +574,31 @@ void print_fh_config(const struct xran_fh_config *fh_config)
fh_config->max_sections_per_slot,
fh_config->max_sections_per_symbol);
#if defined F_RELEASE
printf("\
RunSlotPrbMapBySymbolEnable %d\n\
LiteOnIgnoreUPSectionIdEnable %d\n\
dssEnable %d\n\
RunSlotPrbMapBySymbolEnable %d\n"
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
" LiteOnIgnoreUPSectionIdEnable %d\n"
#endif
" dssEnable %d\n\
dssPeriod %d\n\
technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n",
fh_config->RunSlotPrbMapBySymbolEnable,
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
fh_config->LiteOnIgnoreUPSectionIdEnable,
#endif
fh_config->dssEnable,
fh_config->dssPeriod);
#if defined K_RELEASE
printf("\
numMUs %d\n\
mu_number[0] %d\n\
nNumerology[0] %d\n",
fh_config->numMUs,
fh_config->mu_number[0],
fh_config->nNumerology[0]);
#endif
}
@@ -531,6 +690,10 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in
io_cfg->io_sleep = 0; // enable sleep on PMD cores; 0 -> no sleep
io_cfg->nEthLinePerPort = *gpd(fhip, nump, ORAN_CONFIG_NETHPERPORT)->uptr; // 1, 2, 3 total number of links per O-RU (Fronthaul Ethernet link)
io_cfg->nEthLineSpeed = *gpd(fhip, nump, ORAN_CONFIG_NETHSPEED)->uptr; // 10G,25G,40G,100G speed of Physical connection on O-RU
#if defined K_RELEASE
io_cfg->num_mbuf_alloc = NUM_MBUFS; // number of mbuf allocated by DPDK (optimal is n = (2^q - 1))
io_cfg->num_mbuf_vf_alloc = NUM_MBUFS_VF; // number of mbuf allocated by DPDK (optimal is n = (2^q - 1))
#endif
io_cfg->one_vf_cu_plane = (io_cfg->num_vfs == num_rus); // C-plane and U-plane use one VF
/* eCPRI One-Way Delay Measurements common settings for O-DU and O-RU;
@@ -556,9 +719,7 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in
/* eCPRI OWDM per port variables for O-DU; this parameter is filled within xran library */
// eowd_port[0][XRAN_VF_MAX]
#if defined F_RELEASE
io_cfg->bbu_offload = 0; // enable packet handling on BBU cores
#endif
return true;
}
@@ -595,7 +756,7 @@ static bool set_fh_eaxcid_conf_mplane(struct xran_eaxcid_config *eaxcid_conf, en
return true;
}
#else
static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat)
static bool __attribute__((unused)) set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat)
{
/* CUS specification, section 3.1.3.1.6
DU_port_ID - used to differentiate processing units at O-DU (e.g., different baseband cards).
@@ -686,7 +847,11 @@ static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xra
fh_init->xran_ports = num_rus; // since we use xran as O-DU, xran_ports is set to the number of RUs
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus))
return false;
#if defined K_RELEASE
if (!set_fh_eaxcid_conf_mplane(&fh_init->eAxCId_conf[0], xran_cat, ru_session_list))
#elif defined F_RELEASE
if (!set_fh_eaxcid_conf_mplane(&fh_init->eAxCId_conf, xran_cat, ru_session_list))
#endif
return false;
/* 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. Based on the MTU size, xran calculates the number
@@ -711,8 +876,13 @@ static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xra
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus))
return false;
#if defined K_RELEASE
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf[0], xran_cat))
return false;
#elif defined F_RELEASE
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, xran_cat))
return false;
#endif
/* 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. Based on the MTU size, xran calculates the number
of DL fragments (nPrbElm) needed for transmission of one symbol. */
@@ -756,11 +926,9 @@ static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xra
fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr);
fh_init->totalBfWeights = 0; // only used if id = O_RU (for emulation); C-plane extension types; section 5.4.6 of CUS spec
#if defined F_RELEASE
fh_init->mlogxranenable = 0; // enable mlog; 0 -> disabled
fh_init->dlCpProcBurst = 0; /* 1 -> DL CP processing will be done on single symbol,
0 -> DL CP processing will be spread across all allowed symbols and multiple cores to reduce burstiness */
#endif
return true;
}
@@ -777,8 +945,13 @@ static bool set_fh_prach_config(void *mplane_api,
const uint32_t max_num_ant,
const paramdef_t *prachp,
int nprach,
struct xran_prach_config *prach_config,
bool liteon_prach_eAxC_offset)
struct xran_prach_config *prach_config
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
,
bool liteon_prach_eAxC_offset
#endif
)
{
const split7_config_t *s7cfg = &oai0->split7;
@@ -790,7 +963,7 @@ static bool set_fh_prach_config(void *mplane_api,
prach_config->nPrachRootSeqIdx = 0; // PRACH Root Sequence Index; should be saved from config file; 1 = 839, 2 = 139; not used in xran
prach_config->nPrachFreqStart = s7cfg->prach_freq_start; // PRACH frequency start (MSG1)
prach_config->nPrachFreqOffset = (s7cfg->prach_freq_start * 12 - oai0->num_rb_dl * 6) * 2; // PRACH frequency offset
prach_config->nPrachFilterIdx = 0; /* PRACH filter index; not used in xran;
prach_config->nPrachFilterIdx = XRAN_FILTERINDEX_PRACH_ABC; /* PRACH filter index; not used in xran;
in E release hardcoded to XRAN_FILTERINDEX_PRACH_ABC (preamble format A1~3, B1~4, C0, C2)
in F release properly calculated */
@@ -801,9 +974,7 @@ static bool set_fh_prach_config(void *mplane_api,
prach_config->numPrbc = 0;
prach_config->timeOffset = 0;
prach_config->freqOffset = 0;
#if defined F_RELEASE
prach_config->nPrachConfIdxLTE = 0; // used only if DSS enabled and technology is XRAN_RAN_LTE
#endif
/* xran defines PDSCH eAxC IDs as [0...Ntx-1];
xran defines PUSCH eAxC IDs as [0...Nrx-1];
@@ -812,13 +983,22 @@ static bool set_fh_prach_config(void *mplane_api,
Please note that this approach only applies to the RUs that support this functionality, e.g. LITEON RU. */
#ifdef OAI_MPLANE
xran_mplane_t *xran_mplane = (xran_mplane_t *)mplane_api;
#if defined K_RELEASE
prach_config->prachEaxcOffset = xran_mplane->prach_offset;
#elif defined F_RELEASE
prach_config->eAxC_offset = xran_mplane->prach_offset;
#endif
#else
uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
// TODO Fix K Release for LiteON FR2 RU
#if defined K_RELEASE
prach_config->prachEaxcOffset = (offset != 0) ? offset : max_num_ant;
#elif defined F_RELEASE
if (liteon_prach_eAxC_offset)
prach_config->eAxC_offset = offset;
else
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
#endif
#endif
g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr;
@@ -830,8 +1010,10 @@ static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame
{
const split7_config_t *s7cfg = &oai0->split7;
frame_config->nFrameDuplexType = oai0->duplex_mode == duplex_mode_TDD ? XRAN_TDD : XRAN_FDD; // Frame Duplex type: 0 -> FDD, 1 -> TDD
#if defined F_RELEASE
frame_config->nNumerology = oai0->nr_scs_for_raster; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz
3 -> 120kHz, 4 -> 240kHz */
#endif
if (frame_config->nFrameDuplexType == XRAN_FDD)
return true;
@@ -848,7 +1030,11 @@ static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame
return true;
}
static bool set_fh_ru_config(void *mplane_api, const paramdef_t *rup, uint16_t fftSize, int nru, enum xran_category xran_cat, struct xran_ru_config *ru_config)
static bool set_fh_ru_config(void *mplane_api, const paramdef_t *rup, uint16_t fftSize, int nru, enum xran_category xran_cat
#if defined K_RELEASE
, uint8_t mu_number
#endif
, struct xran_ru_config *ru_config)
{
ru_config->xranTech = XRAN_RAN_5GNR; // 5GNR or LTE
ru_config->xranCat = xran_cat; // mode: Catergory A or Category B
@@ -867,7 +1053,11 @@ static bool set_fh_ru_config(void *mplane_api, const paramdef_t *rup, uint16_t f
ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method for PRACH
AssertFatal(fftSize > 0, "FFT size cannot be 0\n");
#if defined K_RELEASE
ru_config->fftSize[mu_number] = fftSize; // FFT Size
#elif defined F_RELEASE
ru_config->fftSize = fftSize; // FFT Size
#endif
ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER; // order of bytes in int16_t in buffer; big or little endian
ru_config->iqOrder = XRAN_I_Q_ORDER; // order of IQs in the buffer
ru_config->xran_max_frame = 0; // max frame number supported; if not specified, default of 1023 is used
@@ -890,6 +1080,83 @@ static bool set_maxmin_pd(const paramdef_t *pd, int num, const char *name, uint1
return true;
}
#if defined K_RELEASE
static bool set_fh_per_mu_cfg(void *mplane_api, int ru_idx, int num_rus, const openair0_config_t *oai0, struct xran_fh_per_mu_cfg *perMu)
{
char aprefix[MAX_OPTNAME_SIZE] = {0};
paramdef_t FHconfigs[] = ORAN_FH_DESC;
paramlist_def_t FH_ConfigList = {CONFIG_STRING_ORAN_FH};
sprintf(aprefix, "%s", CONFIG_STRING_ORAN);
const int nfh = sizeofArray(FHconfigs);
config_getlist(config_get_if(), &FH_ConfigList, FHconfigs, nfh, aprefix);
if (FH_ConfigList.numelt == 0) {
printf("No configuration section \"%s\" found inside \"%s\": cannot initialize fhi_lib!\n", CONFIG_STRING_ORAN_FH, aprefix);
return false;
}
paramdef_t *fhp = FH_ConfigList.paramarray[ru_idx];
paramdef_t prachp[] = ORAN_PRACH_DESC;
int nprach = sizeofArray(prachp);
sprintf(aprefix, "%s.%s.[%d].%s", CONFIG_STRING_ORAN, CONFIG_STRING_ORAN_FH, ru_idx, CONFIG_STRING_ORAN_PRACH);
int ret = config_get(config_get_if(), prachp, nprach, aprefix);
if (ret < 0) {
printf("No configuration section \"%s\": cannot initialize fhi_lib!\n", aprefix);
return false;
}
perMu->nDLBandwidth = 0; // Carrier bandwidth for in MHz. Value: 5->400. Not used in K release
perMu->nULBandwidth = 0; // Carrier bandwidth for in MHz. Value: 5->400. Not used in K release
if (!set_fh_prach_config(mplane_api, oai0, RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus), prachp, nprach, &perMu->prach_conf))
return false;
perMu->freqOffset = 0;
perMu->nDLFftSize = oai0->split7.fftSize; // DL FFT size
perMu->nULFftSize = oai0->split7.fftSize; // UL FFT size
perMu->eaxcOffset = 0; // Starting value of Eaxc for PDSCH, PUSCH packets (Absolute value) of this numerology. Should be unique across all numerologies for the RU
perMu->nDLRBs = oai0->num_rb_dl; // DL PRB
perMu->nULRBs = oai0->num_rb_dl; // UL PRB
/* DU delay profile */
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &perMu->T1a_min_cp_dl, &perMu->T1a_max_cp_dl)) // E - min not used in xran, max yes; F - both min and max are used in xran
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_UL, &perMu->T1a_min_cp_ul, &perMu->T1a_max_cp_ul)) // both E and F - min not used in xran, max yes
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_UP, &perMu->T1a_min_up, &perMu->T1a_max_up)) // both E and F - min not used in xran, max yes
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &perMu->Ta4_min, &perMu->Ta4_max)) // both E and F - min not used in xran, max yes
return false;
perMu->prachEnable = 1; // enable PRACH
const split7_config_t *s7cfg = &oai0->split7;
perMu->prachConfigIndex = s7cfg->prach_index; // TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
perMu->prachConfigIndexLTE = 0; // PRACH Configuration Index for LTE in dss case
perMu->nbIotUlScs = XRAN_NBIOT_UL_SCS_15; /* Applicable only for NB-IOT (mu=4). NBIOT supports asymmetric SCS usage in
downlink and uplink directions. xran library will use this parameter to derive
slot-duration for UL NB-IOT:
XRAN_NBIOT_UL_SCS_15: slot-duration=1ms
XRAN_NBIOT_UL_SCS_3_75: slot-duration=2ms */
perMu->adv_tx_time = 0; // Time by which the packet should be transmitted in advance (microseconds)
return true;
}
xran_active_numerologies_per_tti activeMUs;
static bool set_activeMUs(xran_active_numerologies_per_tti *p_activeMUs, uint8_t mu)
{
for (int i = 0; i < XRAN_N_FE_BUF_LEN; i++) {
for (int j = 0; j < XRAN_MAX_NUM_MU; j++) {
p_activeMUs->numerology[i][j] = false;
}
p_activeMUs->numerology[i][mu] = true;
}
return true;
}
#endif
static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_category xran_cat, const openair0_config_t *oai0, struct xran_fh_config *fh_config)
{
AssertFatal(num_rus == 1 || num_rus == 2, "only support 1 or 2 RUs as of now\n");
@@ -902,9 +1169,10 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
DevAssert(oai0->rx_freq[0] > 0);
for (int i = 1; i < oai0->rx_num_channels; ++i)
DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]);
char aprefix[MAX_OPTNAME_SIZE] = {0};
#if defined F_RELEASE
paramdef_t FHconfigs[] = ORAN_FH_DESC;
paramlist_def_t FH_ConfigList = {CONFIG_STRING_ORAN_FH};
char aprefix[MAX_OPTNAME_SIZE] = {0};
sprintf(aprefix, "%s", CONFIG_STRING_ORAN);
const int nfh = sizeofArray(FHconfigs);
config_getlist(config_get_if(), &FH_ConfigList, FHconfigs, nfh, aprefix);
@@ -913,6 +1181,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
return false;
}
paramdef_t *fhp = FH_ConfigList.paramarray[ru_idx];
#endif
paramdef_t rup[] = ORAN_RU_DESC;
int nru = sizeofArray(rup);
@@ -922,6 +1191,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
printf("No configuration section \"%s\": cannot initialize fhi_lib!\n", aprefix);
return false;
}
#if defined F_RELEASE
paramdef_t prachp[] = ORAN_PRACH_DESC;
int nprach = sizeofArray(prachp);
sprintf(aprefix, "%s.%s.[%d].%s", CONFIG_STRING_ORAN, CONFIG_STRING_ORAN_FH, ru_idx, CONFIG_STRING_ORAN_PRACH);
@@ -930,6 +1200,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
printf("No configuration section \"%s\": cannot initialize fhi_lib!\n", aprefix);
return false;
}
#endif
memset(fh_config, 0, sizeof(*fh_config));
@@ -937,12 +1208,18 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->sector_id = 0; // Band sector ID for FH; not used in xran
fh_config->nCC = 1; // number of Component carriers supported on FH; M-plane info
fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH)
#if defined K_RELEASE
fh_config->neAxcUl = oai0->rx_num_channels / num_rus; // number of eAxc supported on one CC for UL direction = PUSCH
#elif defined F_RELEASE
fh_config->neAxcUl = 0; // number of eAxc supported on one CC for UL direction = PUSCH; used only if XRAN_CATEGORY_B
#endif
fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B
#if defined F_RELEASE
fh_config->nDLFftSize = oai0->split7.fftSize; // DL FFT size; not used in xran
fh_config->nULFftSize = oai0->split7.fftSize; // UL FFT size; not used in xran
fh_config->nDLRBs = oai0->num_rb_dl; // DL PRB; used in oaioran.c/oran-init.c; not used in xran, neither in E nor in F release
fh_config->nULRBs = oai0->num_rb_dl; // UL PRB; used in oaioran.c/oran-init.c; in xran E release not used so the patch fixes it, but in xran F release this value is properly used
#endif
fh_config->nDLAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
fh_config->nULAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
fh_config->nDLCenterFreqARFCN = 0; // center frequency for DL in NR-ARFCN; not used in xran
@@ -950,6 +1227,13 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->ttiCb = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
fh_config->ttiCbParam = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
#if defined K_RELEASE
uint8_t mu_number = oai0->nr_scs_for_raster;
if(!set_fh_per_mu_cfg(mplane_api, ru_idx, num_rus, oai0, &fh_config->perMu[mu_number]))
return false;
#endif
#if defined F_RELEASE
/* DU delay profile */
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &fh_config->T1a_min_cp_dl, &fh_config->T1a_max_cp_dl)) // E - min not used in xran, max yes; F - both min and max are used in xran
return false;
@@ -959,37 +1243,58 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &fh_config->Ta4_min, &fh_config->Ta4_max)) // both E and F - min not used in xran, max yes
return false;
#endif
fh_config->enableCP = 1; // enable C-plane
#if defined F_RELEASE
fh_config->prachEnable = 1; // enable PRACH
#endif
fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B
// For LiteOn E release, no need to take care of prach eAxC_offset. xran lib is hacked to handle it.
bool liteon_prach_eAxC_offset = false;
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
bool liteon_prach_eAxC_offset = false;
#endif
fh_config->srsEnableCp = 0; // enable SRS CP; used only if XRAN_CATEGORY_B
fh_config->SrsDelaySym = 0; // number of SRS delay symbols; used only if XRAN_CATEGORY_B
// TODO Fix K Release for LiteON FR2 RU
#if defined F_RELEASE
fh_config->RunSlotPrbMapBySymbolEnable = *gpd(fhp, nfh, ORAN_CONFIG_RunSlotPrbMapBySymbol)->uptr; // enable RunSlotPrbMapBySymbol
fh_config->LiteOnIgnoreUPSectionIdEnable = *gpd(fhp, nfh, ORAN_CONFIG_LiteOnIgnoreUPSectionId)->uptr; // enable LiteOnIgnoreUPSectionId
liteon_prach_eAxC_offset = fh_config->LiteOnIgnoreUPSectionIdEnable;
#endif
fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU
fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU
#if defined K_RELEASE
fh_config->csirsEnable = 0; // enable CSI-RS (Cat B specific)
#elif defined F_RELEASE
fh_config->cp_vlan_tag = 0; // C-plane VLAN tag; not used in xran; needed for M-plane
fh_config->up_vlan_tag = 0; // U-plane VLAN tag; not used in xran; needed for M-plane
#endif
fh_config->debugStop = 0; // enable auto stop; only used if id = O_RU
fh_config->debugStopCount = 0; // enable auto stop after number of Tx packets; not used in xran
fh_config->DynamicSectionEna = 0; // enable dynamic C-Plane section allocation
fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha
fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100
#if defined K_RELEASE
fh_config->numMUs = 1;
fh_config->mu_number[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */
fh_config->nNumerology[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */
#elif defined F_RELEASE
if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf, liteon_prach_eAxC_offset))
return false;
#endif
/* SRS only used if XRAN_CATEGORY_B
Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */
// fh_config->srs_conf = {0};
if (!set_fh_frame_config(oai0, &fh_config->frame_conf))
return false;
if (!set_fh_ru_config(mplane_api, rup, oai0->split7.prach_fftSize, nru, xran_cat, &fh_config->ru_conf))
if (!set_fh_ru_config(mplane_api, rup, oai0->split7.prach_fftSize, nru, xran_cat
#if defined K_RELEASE
, mu_number
#endif
, &fh_config->ru_conf))
return false;
fh_config->bbdev_enc = NULL; // call back to poll BBDev encoder
@@ -1013,10 +1318,13 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->max_sections_per_slot = 0; // not used in xran
fh_config->max_sections_per_symbol = 0; // not used in xran
#if defined F_RELEASE
fh_config->dssEnable = 0; // enable DSS (extension-9)
fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR
// fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled
#if defined K_RELEASE
if (!set_activeMUs(&activeMUs, oai0->nr_scs_for_raster))
return false;
fh_config->activeMUs = &activeMUs;
#endif
return true;

View File

@@ -98,13 +98,46 @@ static struct xran_prb_map get_xran_prb_map(const struct xran_fh_config *f, cons
e->nStartSymb = start_sym;
e->numSymb = num_sym;
e->nRBStart = 0;
#if defined K_RELEASE
uint8_t mu_number = f->mu_number[0];
e->nRBSize = (dir == XRAN_DIR_DL) ? f->perMu[mu_number].nDLRBs : f->perMu[mu_number].nULRBs;
#elif defined F_RELEASE
e->nRBSize = (dir == XRAN_DIR_DL) ? f->nDLRBs : f->nULRBs;
#endif
e->nBeamIndex = 0;
e->compMethod = f->ru_conf.compMeth;
e->iqWidth = f->ru_conf.iqWidth;
#if defined K_RELEASE
memset(&prbmap.sFrontHaulRxPacketCtrl, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT * sizeof(struct xran_rx_packet_ctl));
#endif
return prbmap;
}
#if defined K_RELEASE
static struct xran_prb_map get_xran_prb_map_prach(const struct xran_fh_config *f)
{
struct xran_prb_map prbmap = {
.dir = XRAN_DIR_UL,
.xran_port = 0,
.band_id = 0,
.cc_id = 0,
.ru_port_id = 0,
.tti_id = 0,
.nPrbElm = 1,
};
struct xran_prb_elm *e = &prbmap.prbMap[0];
e->nStartSymb = 0;
e->numSymb = 14;
e->nRBStart = 0;
e->nRBSize = 12;
e->nBeamIndex = 0;
e->compMethod = f->ru_conf.compMeth;
e->iqWidth = f->ru_conf.iqWidth;
memset(&prbmap.sFrontHaulRxPacketCtrl, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT * sizeof(struct xran_rx_packet_ctl));
return prbmap;
}
#endif
static uint32_t next_power_2(uint32_t num)
{
uint32_t power = 2;
@@ -199,10 +232,8 @@ static void oran_allocate_cplane_buffers(void *instHandle,
struct xran_flat_buffer buf[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
uint32_t ant,
uint32_t sect,
#if defined F_RELEASE
uint32_t mtu,
const struct xran_fh_config *fh_config,
#endif
uint32_t size_of_prb_map,
oran_cplane_prb_config *prb_conf)
{
@@ -236,31 +267,26 @@ static void oran_allocate_cplane_buffers(void *instHandle,
// get mixed slot map if in TDD and in mixed slot
if (prb_conf->nTddPeriod != 0 && (j % prb_conf->nTddPeriod) == prb_conf->mixed_slot_index)
src = &prb_conf->mixedSlotMap;
#if defined F_RELEASE
if (fh_config->RunSlotPrbMapBySymbolEnable) {
#if defined K_RELEASE
uint8_t mu_number = fh_config->mu_number[0];
xran_init_PrbMap_by_symbol_from_cfg(src, ptr, mtu, fh_config->perMu[mu_number].nDLRBs);
#elif defined F_RELEASE
xran_init_PrbMap_by_symbol_from_cfg(src, ptr, mtu, fh_config->nDLRBs);
#endif
} else {
xran_init_PrbMap_from_cfg(src, ptr, mtu);
}
#endif
}
}
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %u\n", instHandle, poolPrb, count1);
}
/* callback not actively used */
static void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
{
rte_pause();
}
static void oran_allocate_buffers(void *handle,
int xran_inst,
int num_sectors,
oran_port_instance_t *portInstances,
#if defined F_RELEASE
uint32_t mtu,
#endif
const struct xran_fh_config *fh_config)
{
AssertFatal(num_sectors == 1, "only support one sector at the moment\n");
@@ -289,6 +315,9 @@ static void oran_allocate_buffers(void *handle,
// DL/UL PRB mapping depending on the duplex mode
struct xran_prb_map dlPm = get_xran_prb_map(fh_config, XRAN_DIR_DL, 0, 14);
struct xran_prb_map ulPm = get_xran_prb_map(fh_config, XRAN_DIR_UL, 0, 14);
#if defined K_RELEASE
struct xran_prb_map prachPm = get_xran_prb_map_prach(fh_config);
#endif
struct xran_prb_map dlPmMixed = {0};
struct xran_prb_map ulPmMixed = {0};
uint32_t idx = 0;
@@ -314,7 +343,15 @@ static void oran_allocate_buffers(void *handle,
.mixedSlotMap = ulPmMixed,
};
#if defined F_RELEASE
#if defined K_RELEASE
oran_cplane_prb_config prachConf = {
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
.mixed_slot_index = idx,
.slotMap = prachPm,
.mixedSlotMap = prachPm,
};
#endif
uint32_t size_of_prb_map;
if (fh_config->RunSlotPrbMapBySymbolEnable) {
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[14]
@@ -325,78 +362,106 @@ static void oran_allocate_buffers(void *handle,
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu);
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
}
#if defined K_RELEASE
uint32_t numPrbElmPrach = xran_get_num_prb_elm(&prachPm, mtu);
uint32_t size_of_prb_map_prach = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElmPrach);
#endif
// PDSCH
#if defined K_RELEASE
const uint32_t txBufSize = get_nSW_ToFpga_FTH_TxBufferLen(fh_config->nNumerology[0], fh_config->max_sections_per_slot);
#elif defined F_RELEASE
const uint32_t txBufSize = get_nSW_ToFpga_FTH_TxBufferLen(fh_config->frame_conf.nNumerology, fh_config->max_sections_per_slot);
#endif
oran_allocate_uplane_buffers(pi->instanceHandle, bl->src, bl->bufs.tx, xran_max_antenna_nr, txBufSize);
oran_allocate_cplane_buffers(pi->instanceHandle,
bl->srccp,
bl->bufs.tx_prbmap,
xran_max_antenna_nr,
xran_max_sections_per_slot,
#if defined F_RELEASE
mtu,
fh_config,
#endif
size_of_prb_map,
&dlConf);
// PUSCH
#if defined K_RELEASE
const uint32_t rxBufSize = get_nFpgaToSW_FTH_RxBufferLen(fh_config->nNumerology[0]);
#elif defined F_RELEASE
const uint32_t rxBufSize = get_nFpgaToSW_FTH_RxBufferLen(fh_config->frame_conf.nNumerology);
#endif
oran_allocate_uplane_buffers(pi->instanceHandle, bl->dst, bl->bufs.rx, xran_max_antenna_nr, rxBufSize);
oran_allocate_cplane_buffers(pi->instanceHandle,
bl->dstcp,
bl->bufs.rx_prbmap,
xran_max_antenna_nr,
xran_max_sections_per_slot,
#if defined F_RELEASE
mtu,
fh_config,
#endif
size_of_prb_map,
&ulConf);
// PRACH
const uint32_t prachBufSize = PRACH_PLAYBACK_BUFFER_BYTES;
oran_allocate_uplane_buffers(pi->instanceHandle, bl->prachdst, bl->bufs.prach, xran_max_antenna_nr, prachBufSize);
#if defined K_RELEASE
oran_allocate_cplane_buffers(pi->instanceHandle,
bl->prachdstdecomp,
bl->bufs.prachdecomp,
xran_max_antenna_nr,
xran_max_sections_per_slot,
mtu,
fh_config,
size_of_prb_map_prach,
&prachConf);
#elif defined F_RELEASE
// PRACH decomp buffer does not have separate DPDK-allocated memory pool
// bufs, it points to the same pool as the prach buffer. Unclear to me why
for (uint32_t a = 0; a < xran_max_antenna_nr; ++a) {
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
bl->prachdstdecomp[a][j].pBuffers = &bl->bufs.prachdecomp[a][j][0];
bl->prachdstdecomp[a][j].pBuffers = &bl->bufs.prachdecomp[a][j];
for (uint32_t k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; ++k) {
struct xran_flat_buffer *fb = &bl->prachdstdecomp[a][j].pBuffers[k];
fb->pData = bl->prachdst[a][j].pBuffers[k].pData;
}
}
}
#endif
struct xran_buffer_list *src[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *srccp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *dst[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *dstcp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *prach[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *prachdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *prachdst[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *prachdstdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
for (uint32_t a = 0; a < XRAN_MAX_ANTENNA_NR; ++a) {
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
src[a][j] = &bl->src[a][j];
srccp[a][j] = &bl->srccp[a][j];
dst[a][j] = &bl->dst[a][j];
dstcp[a][j] = &bl->dstcp[a][j];
prach[a][j] = &bl->prachdst[a][j];
prachdecomp[a][j] = &bl->prachdstdecomp[a][j];
prachdst[a][j] = &bl->prachdst[a][j];
prachdstdecomp[a][j] = &bl->prachdstdecomp[a][j];
}
}
#if defined K_RELEASE
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->pusch_tag, fh_config->nNumerology[0]);
xran_5g_prach_req(pi->instanceHandle, prachdst, prachdstdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag, fh_config->nNumerology[0]);
#elif defined F_RELEASE
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->pusch_tag);
xran_5g_prach_req(pi->instanceHandle, prach, prachdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag);
xran_5g_prach_req(pi->instanceHandle, prachdst, prachdstdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag);
#endif
}
int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config)
{
int32_t xret = 0;
#if defined K_RELEASE
xran_mem_mgr_leak_detector_init();
#endif
print_fh_init(xran_fh_init);
xret = xran_init(0, NULL, xran_fh_init, NULL, &gxran_handle);
if (xret != XRAN_STATUS_SUCCESS) {
@@ -419,20 +484,34 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
pi->prach_tag = tag;
pi->pusch_tag = tag;
#if defined F_RELEASE
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
#endif
#if defined K_RELEASE
if ((xret = xran_timingsource_reg_tticb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
printf("xran_timingsource_reg_tticb failed %d\n", xret);
exit(-1);
}
#elif defined F_RELEASE
if ((xret = xran_reg_physide_cb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
printf("xran_reg_physide_cb failed %d\n", xret);
exit(-1);
}
#endif
// retrieve and store prach duration
#if defined K_RELEASE
uint8_t mu = xran_fh_config[o_xu_id].nNumerology[0];
uint8_t idx = xran_fh_config[o_xu_id].perMu[mu].prach_conf.nPrachConfIdx;
#elif defined F_RELEASE
uint8_t idx = xran_fh_config[o_xu_id].prach_conf.nPrachConfIdx;
#endif
const struct xran_frame_config *fc = &xran_fh_config[o_xu_id].frame_conf;
g_prach_info[o_xu_id] = get_nr_prach_occasion_info_from_index(idx,
#if defined K_RELEASE
mu > 2 ? FR2 : FR1,
#elif defined F_RELEASE
fc->nNumerology > 2 ? FR2 : FR1,
#endif
fc->nFrameDuplexType == XRAN_FDD ? duplex_mode_FDD : duplex_mode_TDD);
}

View File

@@ -32,7 +32,7 @@ typedef struct oran_bufs {
struct xran_flat_buffer rx_prbmap[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_flat_buffer prach[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer prachdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer prachdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
} oran_bufs_t;
typedef struct oran_buf_list {

View File

@@ -50,9 +50,13 @@ typedef struct {
int capabilities_sent;
void *oran_priv;
void *mplane_priv;
uint32_t nCC;
} oran_eth_state_t;
notifiedFIFO_t oran_sync_fifo;
#if defined K_RELEASE
notifiedFIFO_t oran_sync_fifo_prach;
#endif
int trx_oran_start(openair0_device_t *device)
{
@@ -61,12 +65,42 @@ int trx_oran_start(openair0_device_t *device)
oran_eth_state_t *s = device->priv;
// Start ORAN
#if defined K_RELEASE
if (xran_timingsource_start() != 0) {
printf("%s:%d:%s: Start timing source failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Start timing source. Done\n");
}
if (xran_start_worker_threads() != 0) {
printf("%s:%d:%s: Start worker thread failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Start worker thread. Done\n");
}
xran_mem_mgr_leak_detector_display(0);
#endif
if (xran_start(s->oran_priv) != 0) {
printf("%s:%d:%s: Start ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Start ORAN. Done\n");
}
#if defined K_RELEASE
for (int32_t cc_id = 0; cc_id < s->nCC; cc_id++) {
if (xran_activate_cc(s->oran_priv, cc_id) != 0) {
printf("%s:%d:%s: Activate CC failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Activate CC. Done\n");
}
}
#endif
return 0;
}
@@ -74,14 +108,32 @@ void trx_oran_end(openair0_device_t *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
#if defined K_RELEASE
xran_shutdown(s->oran_priv);
#endif
xran_close(s->oran_priv);
#if defined K_RELEASE
xran_cleanup();
xran_mem_mgr_leak_detector_destroy();
#endif
}
int trx_oran_stop(openair0_device_t *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
#if defined K_RELEASE
for (int32_t cc_id = 0; cc_id < s->nCC; cc_id++) {
xran_deactivate_cc(s->oran_priv, cc_id);
xran_stop(s->oran_priv);
}
xran_timingsource_stop();
#elif defined F_RELEASE
xran_stop(s->oran_priv);
#endif
#ifdef OAI_MPLANE
printf("[MPLANE] Stopping M-plane.\n");
disconnect_mplane(s->mplane_priv);
@@ -380,11 +432,15 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device_t
// create message queues for ORAN sync
initNotifiedFIFO(&oran_sync_fifo);
#if defined K_RELEASE
initNotifiedFIFO(&oran_sync_fifo_prach);
#endif
eth->e.flags = ETH_RAW_IF4p5_MODE;
eth->e.compression = NO_COMPRESS;
eth->e.if_name = eth_params->local_if_name;
eth->last_msg = (rru_config_msg_type_t)-1;
eth->nCC = fh_config->nCC;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_oran_start;