diff --git a/cmake_targets/tools/MODULES/Findxran.cmake b/cmake_targets/tools/MODULES/Findxran.cmake index 1ade3ac522..369f04753f 100644 --- a/cmake_targets/tools/MODULES/Findxran.cmake +++ b/cmake_targets/tools/MODULES/Findxran.cmake @@ -126,12 +126,9 @@ find_package_handle_standard_args(xran VERSION_VAR xran_VERSION ) -# in proper usage of cmake, include directory should only contain "api", but not header files under "src" directory; -# however, we use xran_dev_get_ctx() and xran_dev_get_ctx_by_id() functions which are defined in xran_common.h; -# since xran_common.h is under "src" directory, we have to include it in ${xran_INCLUDE_DIRS} if(xran_FOUND) set(xran_LIBRARIES ${xran_LIBRARY}) - set(xran_INCLUDE_DIRS ${xran_INCLUDE_DIR} ${xran_INCLUDE_DIR}/../src) + set(xran_INCLUDE_DIRS ${xran_INCLUDE_DIR}) endif() if(xran_FOUND AND NOT TARGET xran::xran) diff --git a/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch b/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch index baa5378673..8d0610892a 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch @@ -1,5 +1,5 @@ diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h -index 7508117..ce17ebd 100644 +index 7508117..318508b 100644 --- a/fhi_lib/app/src/common.h +++ b/fhi_lib/app/src/common.h @@ -28,7 +28,7 @@ @@ -7,12 +7,12 @@ index 7508117..ce17ebd 100644 #include -#define VERSIONX "oran_e_maintenance_release_v1.0" -+#define VERSIONX "oran_e_maintenance_release_v1.5" ++#define VERSIONX "oran_e_maintenance_release_v1.6" #define APP_O_DU 0 #define APP_O_RU 1 diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile -index de141bf..fa2923f 100644 +index de141bf..c2a448d 100644 --- a/fhi_lib/lib/Makefile +++ b/fhi_lib/lib/Makefile @@ -23,12 +23,25 @@ MYCUSTOMSPACE1='------------------------------------------------------------' @@ -50,9 +50,9 @@ index de141bf..fa2923f 100644 -RTE_INC := $(shell PKG_CONFIG_PATH=/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) +ifeq ($(TARGET), x86) -+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) +else ifeq ($(TARGET), armv8) -+RTE_INC := $(pkgconf --cflags-only-I libdpdk) ++RTE_INC := $(shell pkg-config --cflags-only-I libdpdk) +endif API_DIR := $(PROJECT_DIR)/api SRC_DIR := $(PROJECT_DIR)/src @@ -85,7 +85,7 @@ index de141bf..fa2923f 100644 CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ -fdata-sections \ -@@ -112,12 +132,21 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ +@@ -112,14 +132,23 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ -fPIC \ -Wall \ -Wimplicit-function-declaration \ @@ -110,8 +110,11 @@ index de141bf..fa2923f 100644 + -Werror -Wno-unused-variable -std=c++14 +endif - INC := -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) -I$(RTE_INC) +-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 @@ -150,8 +179,13 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS)) diff --git a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch index b8d09cf862..bec423b95e 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch @@ -1,5 +1,5 @@ diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h -index ac5f471..9ebbcab 100644 +index ac5f471..5efcce3 100644 --- a/fhi_lib/app/src/common.h +++ b/fhi_lib/app/src/common.h @@ -28,7 +28,7 @@ @@ -7,12 +7,12 @@ index ac5f471..9ebbcab 100644 #include -#define VERSIONX "oran_f_release_v1.0" -+#define VERSIONX "oran_f_release_v1.3" ++#define VERSIONX "oran_f_release_v1.4" #define APP_O_DU 0 #define APP_O_RU 1 diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile -index eccc4ae..b1b8f4b 100644 +index eccc4ae..a97fdc6 100644 --- a/fhi_lib/lib/Makefile +++ b/fhi_lib/lib/Makefile @@ -23,24 +23,46 @@ MYCUSTOMSPACE1='------------------------------------------------------------' @@ -83,9 +83,9 @@ index eccc4ae..b1b8f4b 100644 RTE_TARGET ?= x86_64-native-linux-icc -RTE_INC := $(shell PKG_CONFIG_PATH=/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) +ifeq ($(TARGET), x86) -+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) +else ifeq ($(TARGET), armv8) -+RTE_INC := $(pkgconf --cflags-only-I libdpdk) ++RTE_INC := $(shell pkg-config --cflags-only-I libdpdk) +endif API_DIR := $(PROJECT_DIR)/api @@ -147,6 +147,15 @@ index eccc4ae..b1b8f4b 100644 ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc) CPP_FLAGS += -fp-model fast=2 -no-prec-div -no-prec-sqrt -fast-transcendentals -restrict +@@ -150,7 +187,7 @@ CPP_FLAGS += -fp-model fast -march=icelake-server -mintrinsic-promote -Wno-unus + 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 @@ -186,8 +223,13 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS)) @@ -164,7 +173,7 @@ index eccc4ae..b1b8f4b 100644 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 bacf597..8bd7c66 100644 +index bacf597..1dd6d66 100644 --- a/fhi_lib/lib/api/xran_fh_o_du.h +++ b/fhi_lib/lib/api/xran_fh_o_du.h @@ -141,7 +141,7 @@ extern "C" { @@ -176,7 +185,15 @@ index bacf597..8bd7c66 100644 #define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */ #define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */ -@@ -1193,6 +1193,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb, +@@ -419,6 +419,7 @@ struct xran_io_cfg { + uint16_t num_rxq; /**< number of RX queues per VF */ + char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */ + char *bbdev_dev[1]; /**< BBDev dev name */ ++ char *bbdev_vfio_vf_token[1]; /**< BBDev dev token */ + int32_t bbdev_mode; /**< DPDK for BBDev */ + uint32_t dpdkIoVaMode; /**< IOVA Mode */ + uint32_t dpdkMemorySize; /**< DPDK max memory allocation */ +@@ -1193,6 +1194,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb, */ int32_t xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond); @@ -259,7 +276,7 @@ index 46e0e1d..409ef4b 100644 int xran_prepare_iq_symbol_portion( struct rte_mbuf *mbuf, diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c -index f5b2fd6..144a65e 100644 +index f5b2fd6..8fb0ec2 100644 --- a/fhi_lib/lib/ethernet/ethdi.c +++ b/fhi_lib/lib/ethernet/ethdi.c @@ -37,7 +37,10 @@ @@ -273,8 +290,37 @@ index f5b2fd6..144a65e 100644 #include #include #include -@@ -325,8 +328,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -185,14 +188,24 @@ static void check_port_link_status(uint8_t portid) + printf("Port %d Link Up - speed %u " + "Mbps - %s\n", (uint8_t)portid, + (unsigned)link.link_speed, ++#if (RTE_VER_YEAR >= 21) ++ (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? ++ ("full-duplex") : ("half-duplex\n") ++#else + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? +- ("full-duplex") : ("half-duplex\n")); ++ ("full-duplex") : ("half-duplex\n") ++#endif ++ ); + else + printf("Port %d Link Down\n", + (uint8_t)portid); + } + /* clear all_ports_up flag if any link down */ ++#if (RTE_VER_YEAR >= 21) ++ if (link.link_status == RTE_ETH_LINK_DOWN) { ++#else + if (link.link_status == ETH_LINK_DOWN) { ++#endif + all_ports_up = 0; + break; + } +@@ -323,10 +336,11 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, + uint64_t nWorkerCore = 1; + uint32_t coreNum = sysconf(_SC_NPROCESSORS_CONF); char bbdev_wdev[32] = ""; ++ char bbdev_vfio_vf_token[64] = ""; char bbdev_vdev[32] = ""; char iova_mode[32] = "--iova-mode=pa"; - char socket_mem[32] = "--socket-mem=8192"; @@ -284,16 +330,36 @@ index f5b2fd6..144a65e 100644 char ring_name[32] = ""; int32_t xran_port = -1; queueid_t qi = 0; -@@ -336,7 +339,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -336,8 +350,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, cpu = sched_getcpu(); node = numa_node_of_cpu(cpu); - char *argv[] = { name, core_mask, "-n2", iova_mode, socket_mem, socket_limit, "--proc-type=auto", +- "--file-prefix", name, "-a0000:00:00.0", bbdev_wdev, bbdev_vdev}; + char *argv[] = { name, core_mask, "-n2", iova_mode, socket_mem, socket_limit, "--proc-type=auto", "--no-telemetry", - "--file-prefix", name, "-a0000:00:00.0", bbdev_wdev, bbdev_vdev}; ++ "--file-prefix", name, "-a0000:00:00.0", bbdev_wdev, bbdev_vdev, bbdev_vfio_vf_token}; if (io_cfg == NULL) -@@ -481,11 +484,13 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, + return 0; +@@ -347,11 +361,17 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, + // hw-accelerated bbdev + printf("hw-accelerated bbdev %s\n", io_cfg->bbdev_dev[0]); + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "-a%s", io_cfg->bbdev_dev[0]); ++ if (io_cfg->bbdev_vfio_vf_token[0] != NULL) { ++ snprintf(bbdev_vfio_vf_token, RTE_DIM(bbdev_vfio_vf_token), "--vfio-vf-token=%s", io_cfg->bbdev_vfio_vf_token[0]); ++ } + } else if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_OFF){ + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "%s", "--vdev=baseband_turbo_sw"); + } else if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_SW){ + printf("software and hw-accelerated bbdev %s\n", io_cfg->bbdev_dev[0]); + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "-a%s", io_cfg->bbdev_dev[0]); ++ if (io_cfg->bbdev_vfio_vf_token[0] != NULL) { ++ snprintf(bbdev_vfio_vf_token, RTE_DIM(bbdev_vfio_vf_token), "--vfio-vf-token=%s", io_cfg->bbdev_vfio_vf_token[0]); ++ } + snprintf(bbdev_vdev, RTE_DIM(bbdev_vdev), "%s", "--vdev=baseband_turbo_sw"); + } else { + rte_panic("Cannot init DPDK incorrect [bbdev_mode %d]\n", io_cfg->bbdev_mode); +@@ -481,11 +501,13 @@ xran_ethdi_init_dpdk_io(char *name, const 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"); @@ -307,7 +373,7 @@ index f5b2fd6..144a65e 100644 } } } else { -@@ -555,7 +560,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -555,7 +577,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, 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"); @@ -317,7 +383,7 @@ index f5b2fd6..144a65e 100644 return 1; diff --git a/fhi_lib/lib/ethernet/ethernet.c b/fhi_lib/lib/ethernet/ethernet.c -index edda598..791256c 100644 +index edda598..77e5ca7 100644 --- a/fhi_lib/lib/ethernet/ethernet.c +++ b/fhi_lib/lib/ethernet/ethernet.c @@ -37,7 +37,10 @@ @@ -331,6 +397,78 @@ index edda598..791256c 100644 #include #include #include +@@ -149,13 +152,22 @@ void xran_init_port(int p_id, uint16_t num_rxq, uint32_t mtu) + static uint16_t nb_txd = BURST_SIZE; + struct rte_ether_addr addr; + struct rte_eth_rxmode rxmode = { ++#if (RTE_VER_YEAR >= 21) ++ .mtu = MAX_RX_LEN, ++#else + .split_hdr_size = 0, + .max_rx_pkt_len = MAX_RX_LEN, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME ++#endif + }; + struct rte_eth_txmode txmode = { ++#if (RTE_VER_YEAR >= 21) ++ .mq_mode = RTE_ETH_MQ_TX_NONE, ++ .offloads = RTE_ETH_TX_OFFLOAD_MULTI_SEGS ++#else + .mq_mode = ETH_MQ_TX_NONE, + .offloads = DEV_TX_OFFLOAD_MULTI_SEGS ++#endif + }; + struct rte_eth_conf port_conf = { + .rxmode = rxmode, +@@ -174,8 +186,13 @@ void xran_init_port(int p_id, uint16_t num_rxq, uint32_t mtu) + uint32_t num_mbufs = 0; + + if (mtu <= 1500) { ++#if (RTE_VER_YEAR >= 21) ++ rxmode.offloads &= ~RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO; ++ rxmode.mtu = RTE_ETHER_MAX_LEN; ++#else + rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; + rxmode.max_rx_pkt_len = RTE_ETHER_MAX_LEN; ++#endif + data_room_size = MBUF_POOL_ELM_SMALL; + } + +@@ -184,10 +201,19 @@ void xran_init_port(int p_id, uint16_t num_rxq, uint32_t mtu) + drv_name = dev_info.driver_name; + printf("initializing port %d for TX, drv=%s\n", p_id, drv_name); + +- if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE){ ++#if (RTE_VER_YEAR >= 21) ++ if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) ++#else ++ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) ++#endif ++ { + printf("set DEV_TX_OFFLOAD_MBUF_FAST_FREE\n"); + port_conf.txmode.offloads |= ++#if (RTE_VER_YEAR >= 21) ++ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; ++#else + DEV_TX_OFFLOAD_MBUF_FAST_FREE; ++#endif + } + + rte_eth_macaddr_get(p_id, &addr); +@@ -293,8 +319,13 @@ void xran_add_eth_hdr_vlan(struct rte_ether_addr *dst, uint16_t ethertype, struc + PANIC_ON(h == NULL, "mbuf prepend of ether_hdr failed"); + + /* Fill in the ethernet header. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_eth_macaddr_get(mb->port, &h->src_addr); /* set source addr */ ++ h->dst_addr = *dst; /* set dst addr */ ++#else + rte_eth_macaddr_get(mb->port, &h->s_addr); /* set source addr */ + h->d_addr = *dst; /* set dst addr */ ++#endif + h->ether_type = rte_cpu_to_be_16(ethertype); /* ethertype too */ + #if 0 + struct rte_ether_addr *s = &h->s_addr; diff --git a/fhi_lib/lib/src/xran_bfp_ref.cpp b/fhi_lib/lib/src/xran_bfp_ref.cpp index e6d3067..8e0abee 100644 --- a/fhi_lib/lib/src/xran_bfp_ref.cpp @@ -565,7 +703,7 @@ index 789c6fd..a768efb 100644 #include #include diff --git a/fhi_lib/lib/src/xran_delay_measurement.c b/fhi_lib/lib/src/xran_delay_measurement.c -index 4c943c8..d9e7983 100644 +index 4c943c8..7db51a8 100644 --- a/fhi_lib/lib/src/xran_delay_measurement.c +++ b/fhi_lib/lib/src/xran_delay_measurement.c @@ -23,7 +23,10 @@ @@ -579,6 +717,155 @@ index 4c943c8..d9e7983 100644 #include #include #include +@@ -572,16 +575,28 @@ int xran_generate_delay_meas(uint16_t port_id, void* handle, uint8_t actionType, + PANIC_ON(h == NULL, "mbuf prepend of ether_hdr failed"); + + /* Fill in the ethernet header. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_eth_macaddr_get(port_id, &h->src_addr); /* set source addr */ ++#else + rte_eth_macaddr_get(port_id, &h->s_addr); /* set source addr */ ++#endif + + if (p_xran_dev_ctx->fh_init.io_cfg.id) + { + // rte_ether_addr_copy( (struct rte_ether_addr *)p_xran_dev_ctx->fh_init.p_o_du_addr[port_id],&h->d_addr); ++#if (RTE_VER_YEAR >= 21) ++ h->dst_addr = ctx->entities[port_id][ID_O_DU]; /* set dst addr */ ++#else + h->d_addr = ctx->entities[port_id][ID_O_DU]; /* set dst addr */ ++#endif + } + else + { ++#if (RTE_VER_YEAR >= 21) ++ h->dst_addr = ctx->entities[port_id][ID_O_RU]; /* set dst addr */ ++#else + h->d_addr = ctx->entities[port_id][ID_O_RU]; /* set dst addr */ ++#endif + // rte_ether_addr_copy( (struct rte_ether_addr *)p_xran_dev_ctx->fh_init.p_o_ru_addr[port_id],&h->d_addr); + } + +@@ -752,7 +767,11 @@ int xran_generate_delay_meas(uint16_t port_id, void* handle, uint8_t actionType, + int8_t *pa = &p_xran_dev_ctx->fh_init.p_o_du_addr[0]; + printf("DST_MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]); + #endif ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy((struct rte_ether_addr *)&p_xran_dev_ctx->fh_init.p_o_du_addr[0], (struct rte_ether_addr *)&h->dst_addr.addr_bytes[0]); ++#else + rte_ether_addr_copy((struct rte_ether_addr *)&p_xran_dev_ctx->fh_init.p_o_du_addr[0], (struct rte_ether_addr *)&h->d_addr.addr_bytes[0]); ++#endif + + } + else +@@ -761,13 +780,25 @@ int xran_generate_delay_meas(uint16_t port_id, void* handle, uint8_t actionType, + int8_t *pb = &p_xran_dev_ctx->fh_init.p_o_ru_addr[0]; + printf("DST_MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pb[0],pb[1],pb[2],pb[3],pb[4],pb[5]); + #endif ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy((struct rte_ether_addr *)&p_xran_dev_ctx->fh_init.p_o_ru_addr[0], (struct rte_ether_addr *)&h->dst_addr.addr_bytes[0]); ++#else + rte_ether_addr_copy((struct rte_ether_addr *)&p_xran_dev_ctx->fh_init.p_o_ru_addr[0], (struct rte_ether_addr *)&h->d_addr.addr_bytes[0]); ++#endif + + } + #ifdef XRAN_OWD_DEBUG_PKTS ++#if (RTE_VER_YEAR >= 21) ++ uint8_t *pc = &h->src_addr.addr_bytes[0]; ++#else + uint8_t *pc = &h->s_addr.addr_bytes[0]; ++#endif + printf(" Src MAC from packet: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pc[0],pc[1],pc[2],pc[3],pc[4],pc[5]); ++#if (RTE_VER_YEAR >= 21) ++ uint8_t *pd = &h->dst_addr.addr_bytes[0]; ++#else + uint8_t *pd = &h->d_addr.addr_bytes[0]; ++#endif + printf(" Dst MAC from packet: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pd[0],pd[1],pd[2],pd[3],pd[4],pd[5]); + #endif + // Copy dest address from above +@@ -862,9 +893,15 @@ int xran_process_delmeas_request(struct rte_mbuf *pkt, void* handle, struct xran + // 11) Fill the ethernet header properly by swapping src and dest addressed from the copied frame + eth_hdr = rte_pktmbuf_mtod(pkt1, struct rte_ether_hdr *); + /* Swap dest and src mac addresses. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy(ð_hdr->dst_addr, &addr); ++ rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); ++ rte_ether_addr_copy(&addr, ð_hdr->src_addr); ++#else + rte_ether_addr_copy(ð_hdr->d_addr, &addr); + rte_ether_addr_copy(ð_hdr->s_addr, ð_hdr->d_addr); + rte_ether_addr_copy(&addr, ð_hdr->s_addr); ++#endif + // Still need to check ol_flags state and update if necessary + // Compute the delay td12 and save + // Still need to define the DB to save the info and run averages +@@ -872,9 +909,17 @@ int xran_process_delmeas_request(struct rte_mbuf *pkt, void* handle, struct xran + // 12) Send the response right away + #ifdef XRAN_OWD_DEBUG_PKTS + struct rte_ether_hdr *h = (struct rte_ether_hdr *)rte_pktmbuf_mtod(pkt1, struct rte_ether_hdr*); ++#if (RTE_VER_YEAR >= 21) ++ uint8_t *pc = &h->src_addr.addr_bytes[0]; ++#else + uint8_t *pc = &h->s_addr.addr_bytes[0]; ++#endif + printf(" Src MAC from packet: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pc[0],pc[1],pc[2],pc[3],pc[4],pc[5]); ++#if (RTE_VER_YEAR >= 21) ++ uint8_t *pd = &h->dst_addr.addr_bytes[0]; ++#else + uint8_t *pd = &h->d_addr.addr_bytes[0]; ++#endif + printf(" Dst MAC from packet: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", pd[0],pd[1],pd[2],pd[3],pd[4],pd[5]); + // printf("EtherType: %04"PRIx16" \n",&h->ether_type); + #endif +@@ -1100,9 +1145,15 @@ int xran_process_delmeas_rem_request(struct rte_mbuf *pkt, void* handle, struct + // 9) Fill the ethernet header properly by swapping src and dest addressed from the copied frame + eth_hdr = rte_pktmbuf_mtod(pkt1, struct rte_ether_hdr *); + /* Swap dest and src mac addresses. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy(ð_hdr->dst_addr, &addr); ++ rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); ++ rte_ether_addr_copy(&addr, ð_hdr->src_addr); ++#else + rte_ether_addr_copy(ð_hdr->d_addr, &addr); + rte_ether_addr_copy(ð_hdr->s_addr, ð_hdr->d_addr); + rte_ether_addr_copy(&addr, ð_hdr->s_addr); ++#endif + // 10) Send the response right away + pdm = (struct xran_ecpri_del_meas_pkt*)rte_pktmbuf_mtod_offset(pkt1, struct xran_ecpri_del_meas_pkt *, sizeof(struct rte_ether_hdr) ); + pdm->cmnhdr.bits.ecpri_payl_size = 10 + powdc->owdm_PlLength; // 10 correponds to the xran_ecpri_delay_meas_pl minus the dummy_bytes field which now allows the user to select the length for this field to be sent +@@ -1177,9 +1228,15 @@ int xran_process_delmeas_rem_request_w_fup(struct rte_mbuf* pkt, void* handle, s + // 7) Fill the ethernet header properly by swapping src and dest addressed from the copied frame + eth_hdr = rte_pktmbuf_mtod(pkt1, struct rte_ether_hdr *); + /* Swap dest and src mac addresses. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy(ð_hdr->dst_addr, &addr); ++ rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); ++ rte_ether_addr_copy(&addr, ð_hdr->src_addr); ++#else + rte_ether_addr_copy(ð_hdr->d_addr, &addr); + rte_ether_addr_copy(ð_hdr->s_addr, ð_hdr->d_addr); + rte_ether_addr_copy(&addr, ð_hdr->s_addr); ++#endif + // 8) Duplicate packet to be used for the follow up packet + pkt2 = rte_pktmbuf_copy(pkt1, _eth_mbuf_pool, 0, UINT32_MAX); + // 9) Record the current timestamp when the request with follow up is being sent +@@ -1283,9 +1340,15 @@ int xran_process_delmeas_follow_up(struct rte_mbuf *pkt, void* handle, struct xr + // 9) Fill the ethernet header properly by swapping src and dest addressed from the copied frame + eth_hdr = rte_pktmbuf_mtod(pkt1, struct rte_ether_hdr *); + /* Swap dest and src mac addresses. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_ether_addr_copy(ð_hdr->dst_addr, &addr); ++ rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); ++ rte_ether_addr_copy(&addr, ð_hdr->src_addr); ++#else + rte_ether_addr_copy(ð_hdr->d_addr, &addr); + rte_ether_addr_copy(ð_hdr->s_addr, ð_hdr->d_addr); + rte_ether_addr_copy(&addr, ð_hdr->s_addr); ++#endif + pdm = (struct xran_ecpri_del_meas_pkt*)rte_pktmbuf_mtod_offset(pkt1, struct xran_ecpri_del_meas_pkt *, sizeof(struct rte_ether_hdr) ); + pdm->cmnhdr.bits.ecpri_payl_size = 10 + powdc->owdm_PlLength; // 10 correponds to the xran_ecpri_delay_meas_pl minus the dummy_bytes field which now allows the user to select the length for this field to be sent + pdm->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(pdm->cmnhdr.bits.ecpri_payl_size); diff --git a/fhi_lib/lib/src/xran_dev.c b/fhi_lib/lib/src/xran_dev.c index 4acade1..c939edc 100644 --- a/fhi_lib/lib/src/xran_dev.c @@ -1377,7 +1664,7 @@ index 72249bc..6b30084 100644 #include diff --git a/fhi_lib/lib/src/xran_tx_proc.c b/fhi_lib/lib/src/xran_tx_proc.c -index 45a17a8..28c5568 100644 +index 45a17a8..85ce6fa 100644 --- a/fhi_lib/lib/src/xran_tx_proc.c +++ b/fhi_lib/lib/src/xran_tx_proc.c @@ -35,7 +35,11 @@ @@ -1392,6 +1679,58 @@ index 45a17a8..28c5568 100644 #include #include +@@ -1514,7 +1518,11 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32 + mb_oran_hdr_ext->buf_addr = ext_buff; + mb_oran_hdr_ext->buf_iova = ((struct rte_mempool_objhdr*)RTE_PTR_SUB(mb_base, rte_mempool_objhdr_size))->iova + RTE_PTR_DIFF(ext_buff, mb_base); + mb_oran_hdr_ext->buf_len = ext_buff_len; ++#if (RTE_VER_YEAR >= 21) ++ mb_oran_hdr_ext->ol_flags |= RTE_MBUF_F_EXTERNAL; ++#else + mb_oran_hdr_ext->ol_flags |= EXT_ATTACHED_MBUF; ++#endif + mb_oran_hdr_ext->shinfo = p_share_data; + mb_oran_hdr_ext->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM, (uint16_t)mb_oran_hdr_ext->buf_len) - rte_ether_hdr_size; + mb_oran_hdr_ext->data_len = (uint16_t)(mb_oran_hdr_ext->data_len + rte_ether_hdr_size); +@@ -1532,8 +1540,13 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32 + + /* Fill in the ethernet header. */ + #ifndef TRANSMIT_BURST ++#if (RTE_VER_YEAR >= 21) ++ rte_eth_macaddr_get(mb_oran_hdr_ext->port, &((struct rte_ether_hdr*)pStart)->src_addr); /* set source addr */ ++ ((struct rte_ether_hdr*)pStart)->dst_addr = eth_ctx->entities[vf_id][ID_O_RU]; /* set dst addr */ ++#else + rte_eth_macaddr_get(mb_oran_hdr_ext->port, &((struct rte_ether_hdr*)pStart)->s_addr); /* set source addr */ + ((struct rte_ether_hdr*)pStart)->d_addr = eth_ctx->entities[vf_id][ID_O_RU]; /* set dst addr */ ++#endif + ((struct rte_ether_hdr*)pStart)->ether_type = ETHER_TYPE_ECPRI_BE; /* ethertype */ + #endif + nPktSize = sizeof(struct rte_ether_hdr) +@@ -1878,7 +1891,11 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s + mb_oran_hdr_ext->buf_addr = ext_buff; + mb_oran_hdr_ext->buf_iova = ((struct rte_mempool_objhdr*)RTE_PTR_SUB(mb_base, rte_mempool_objhdr_size))->iova + RTE_PTR_DIFF(ext_buff, mb_base); + mb_oran_hdr_ext->buf_len = ext_buff_len; ++#if (RTE_VER_YEAR >= 21) ++ mb_oran_hdr_ext->ol_flags |= RTE_MBUF_F_EXTERNAL; ++#else + mb_oran_hdr_ext->ol_flags |= EXT_ATTACHED_MBUF; ++#endif + mb_oran_hdr_ext->shinfo = p_share_data; + mb_oran_hdr_ext->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM, (uint16_t)mb_oran_hdr_ext->buf_len) - rte_ether_hdr_size; + mb_oran_hdr_ext->data_len = (uint16_t)(mb_oran_hdr_ext->data_len + rte_ether_hdr_size); +@@ -1887,8 +1904,13 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s + pStart = (char*)((char*)mb_oran_hdr_ext->buf_addr + mb_oran_hdr_ext->data_off); + + /* Fill in the ethernet header. */ ++#if (RTE_VER_YEAR >= 21) ++ rte_eth_macaddr_get(mb_oran_hdr_ext->port, &((struct rte_ether_hdr*)pStart)->src_addr); /* set source addr */ ++ ((struct rte_ether_hdr*)pStart)->dst_addr = eth_ctx->entities[vf_id][ID_O_RU]; /* set dst addr */ ++#else + rte_eth_macaddr_get(mb_oran_hdr_ext->port, &((struct rte_ether_hdr*)pStart)->s_addr); /* set source addr */ + ((struct rte_ether_hdr*)pStart)->d_addr = eth_ctx->entities[vf_id][ID_O_RU]; /* set dst addr */ ++#endif + ((struct rte_ether_hdr*)pStart)->ether_type = ETHER_TYPE_ECPRI_BE; /* ethertype */ + + nPktSize = sizeof(struct rte_ether_hdr) diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c index fe22a1f..3fd369b 100644 --- a/fhi_lib/lib/src/xran_up_api.c diff --git a/executables/main_ru.c b/executables/main_ru.c index 86a26f9ac3..3579c26f7a 100644 --- a/executables/main_ru.c +++ b/executables/main_ru.c @@ -97,11 +97,19 @@ void exit_function(const char *file, const char *function, const int line, const oai_exit = 1; if (ru_m.rfdevice.trx_end_func) { + if (ru_m.rfdevice.trx_get_stats_func) { + ru_m.rfdevice.trx_get_stats_func(&ru_m.rfdevice); + ru_m.rfdevice.trx_get_stats_func = NULL; + } ru_m.rfdevice.trx_end_func(&ru_m.rfdevice); ru_m.rfdevice.trx_end_func = NULL; } if (ru_m.ifdevice.trx_end_func) { + if (ru_m.ifdevice.trx_get_stats_func) { + ru_m.ifdevice.trx_get_stats_func(&ru_m.ifdevice); + ru_m.ifdevice.trx_get_stats_func = NULL; + } ru_m.ifdevice.trx_end_func(&ru_m.ifdevice); ru_m.ifdevice.trx_end_func = NULL; } @@ -363,11 +371,19 @@ int main ( int argc, char **argv ) end_configmodule(uniqCfg); if (ru->rfdevice.trx_end_func) { + if (ru->rfdevice.trx_get_stats_func) { + ru->rfdevice.trx_get_stats_func(&ru->rfdevice); + ru->rfdevice.trx_get_stats_func = NULL; + } ru->rfdevice.trx_end_func(&ru->rfdevice); ru->rfdevice.trx_end_func = NULL; } if (ru->ifdevice.trx_end_func) { + if (ru->ifdevice.trx_get_stats_func) { + ru->ifdevice.trx_get_stats_func(&ru->ifdevice); + ru->ifdevice.trx_get_stats_func = NULL; + } ru->ifdevice.trx_end_func(&ru->ifdevice); ru->ifdevice.trx_end_func = NULL; } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 21fff0cd5a..66a983e380 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1341,6 +1341,9 @@ int start_rf(RU_t *ru) { } int stop_rf(RU_t *ru) { + if (ru->rfdevice.trx_get_stats_func) { + ru->rfdevice.trx_get_stats_func(&ru->rfdevice); + } ru->rfdevice.trx_end_func(&ru->rfdevice); return 0; } diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 332e06e7af..602606039a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -207,11 +207,19 @@ void exit_function(const char *file, const char *function, const int line, const for (ru_id=0; ru_idrfdevice.trx_end_func) { + if (RC.ru[ru_id]->rfdevice.trx_get_stats_func) { + RC.ru[ru_id]->rfdevice.trx_get_stats_func(&RC.ru[ru_id]->rfdevice); + RC.ru[ru_id]->rfdevice.trx_get_stats_func = NULL; + } RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); RC.ru[ru_id]->rfdevice.trx_end_func = NULL; } if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { + if (RC.ru[ru_id]->ifdevice.trx_get_stats_func) { + RC.ru[ru_id]->ifdevice.trx_get_stats_func(&RC.ru[ru_id]->ifdevice); + RC.ru[ru_id]->ifdevice.trx_get_stats_func = NULL; + } RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); RC.ru[ru_id]->ifdevice.trx_end_func = NULL; } @@ -423,11 +431,17 @@ int stop_L1(module_id_t gnb_id) 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); + } if (ru->rfdevice.trx_stop_func) { ru->rfdevice.trx_stop_func(&ru->rfdevice); LOG_I(GNB_APP, "turned off RU rfdevice\n"); } + if (ru->ifdevice.trx_get_stats_func) { + ru->ifdevice.trx_get_stats_func(&ru->rfdevice); + } if (ru->ifdevice.trx_stop_func) { ru->ifdevice.trx_stop_func(&ru->ifdevice); LOG_I(GNB_APP, "turned off RU ifdevice\n"); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index f1e94e9e55..fad251b060 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -170,8 +170,12 @@ void exit_function(const char *file, const char *function, const int line, const if (PHY_vars_UE_g && PHY_vars_UE_g[0]) { for(CC_id=0; CC_idrfdevice.trx_end_func) + if (PHY_vars_UE_g[0][CC_id] && PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) { + if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_get_stats_func) { + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_get_stats_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } } } @@ -591,6 +595,8 @@ int main(int argc, char **argv) ret = pthread_join(phy_vars->stat_thread, NULL); AssertFatal(ret == 0, "pthread_join error %d, errno %d (%s)\n", ret, errno, strerror(errno)); } + if (phy_vars->rfdevice.trx_get_stats_func) + phy_vars->rfdevice.trx_get_stats_func(&phy_vars->rfdevice); if (phy_vars->rfdevice.trx_end_func) phy_vars->rfdevice.trx_end_func(&phy_vars->rfdevice); } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 84284f0c48..3770d2c6ec 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -35,6 +35,7 @@ #include "NR_CellGroupConfig.h" #include "NR_UE-NR-Capability.h" #include "nr_mac.h" +#include "nr_prach_config.h" #include "common/utils/nr/nr_common.h" #define NB_SRS_PERIOD (18) @@ -52,20 +53,6 @@ typedef enum { pusch_len2 = 2 } pusch_maxLength_t; -typedef struct { - uint32_t format; - uint32_t start_symbol; - uint32_t N_t_slot; - uint32_t N_dur; - uint32_t N_RA_slot; - uint32_t N_RA_sfn; - uint32_t max_association_period; - int x; - int y; - int y2; - uint64_t s_map; -} nr_prach_info_t; - typedef struct { uint16_t bwpStart; uint16_t bwpSize; @@ -161,8 +148,6 @@ void find_aggregation_candidates(uint8_t *aggregation_level, const NR_SearchSpace_t *ss, int maxL); -uint16_t get_nr_prach_format_from_index(uint8_t index, uint32_t pointa, uint8_t unpaired); - bool get_nr_prach_sched_from_info(nr_prach_info_t info, int config_index, int frame, @@ -172,8 +157,6 @@ bool get_nr_prach_sched_from_info(nr_prach_info_t info, uint16_t *RA_sfn_index, uint8_t unpaired); -nr_prach_info_t get_nr_prach_occasion_info_from_index(uint8_t index, frequency_range_t freq_range, uint8_t unpaired); - uint8_t get_pusch_mcs_table(long *mcs_Table, int is_tp, int dci_format, @@ -190,8 +173,6 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec uint8_t get_pdsch_mcs_table(long *mcs_Table, int dci_format, int rnti_type, int ss_type); -int get_format0(uint8_t index, uint8_t unpaired, frequency_range_t frequency_range); - uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); int compute_pucch_crc_size(int O_uci); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h b/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h new file mode 100644 index 0000000000..1b6aa0bfb7 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h @@ -0,0 +1,75 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h +* \brief Tools to query the PRACH configuration tables +* \author Romain beurdouche +* \date Jul. 2025 +* \version 0.1 +* \company Eurecom +* \email romain.beurdouche@eurecom.fr +* \note The PRACH configuration tables are used in the MAC layer for scheduling and beyond. +* For example the PRACH duration is requested in the O-RAN 7.2 FrontHaul Interface +*/ + +/** + * @brief Fetch PRACH format (format only) from PRACH configuration tables + * + * @param index PRACH configuration index + * @param unpaired Duplex mode TDD or FDD + * @param freq_range Frequency range FR1 or FR2 + * @return PRACH format (format only) + */ +int get_format0(uint8_t index, uint8_t unpaired, frequency_range_t frequency_range); + +typedef struct { + uint32_t format; + uint32_t start_symbol; + uint32_t N_t_slot; + uint32_t N_dur; + uint32_t N_RA_slot; + uint32_t N_RA_sfn; + uint32_t max_association_period; + int x; + int y; + int y2; + uint64_t s_map; +} nr_prach_info_t; + +/** + * @brief Fetch PRACH occasion info from PRACH configuration tables + * + * @param index PRACH configuration index + * @param freq_range Frequency range FR1 or FR2 + * @param unpaired Duplex mode TDD or FDD + * @return PRACH occasion information + */ +nr_prach_info_t get_nr_prach_occasion_info_from_index(uint8_t index, frequency_range_t freq_range, uint8_t unpaired); + +/** + * @brief Fetch PRACH format (format concatenated with format2) from PRACH configuration tables + * + * @param index PRACH configuration index + * @param pointa Point A ARFCN to determine the Frequency range FR1 or FR2 + * @param unpaired Duplex mode TDD or FDD + * @return PRACH format (format concatenated with format2) + */ +uint16_t get_nr_prach_format_from_index(uint8_t index, uint32_t pointa, uint8_t unpaired); diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index a874d4cc01..3b0f16d2a4 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -16,8 +16,8 @@ add_library(oran_fhlib_5g MODULE oran-init.c ) -set(E_VERSION 5.1.5) -set(F_VERSION 6.1.3) +set(E_VERSION 5.1.6) +set(F_VERSION 6.1.4) find_package(xran REQUIRED) if(xran_VERSION VERSION_EQUAL E_VERSION) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 7ac4998e40..fc9f58a492 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -35,7 +35,6 @@ #include "xran_sync_api.h" #include "oran_isolate.h" #include "oran-init.h" -#include "xran_common.h" #include "oaioran.h" #include @@ -43,6 +42,8 @@ #include "common/utils/threadPool/notified_fifo.h" +#define N_SC_PER_PRB 12 + #if OAI_FHI72_USE_POLLING #define USE_POLLING #endif @@ -67,49 +68,37 @@ volatile oran_sync_info_t oran_sync_info = {0}; void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) { struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag; - uint64_t second; - uint32_t tti; - uint32_t frame; - uint32_t subframe; - uint32_t slot, slot2; - uint32_t rx_sym; static int32_t last_slot = -1; static int32_t last_frame = -1; - /* xran context contains the same xran_fh_init struct info, - but xran_fh_config struct info is RU specific only */ - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; + const struct xran_fh_init *fh_init = get_xran_fh_init(); int num_ports = fh_init->xran_ports; /* assuming all RUs have the same numerology */ - const int slots_per_subframe = 1 << xran_ctx->fh_cfg.frame_conf.nNumerology; + const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + const int slots_in_sf = 1 << fh_cfg->frame_conf.nNumerology; + const int sf_in_frame = 10; static int rx_RU[XRAN_PORTS_NUM][160] = {0}; - uint32_t rx_tti = callback_tag->slotiId; + 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); - tti = xran_get_slot_idx_from_tti(rx_tti, &frame, &subframe, &slot, &second); - - rx_sym = callback_tag->symbol & 0xFF; + uint32_t rx_sym = callback_tag->symbol & 0xFF; uint32_t ru_id = callback_tag->oXuId; - LOG_D(HW, - "rx_callback frame %d, subframe %d, slot %d, second %lld, rx_sym %d ru_id %d\n", - frame, - subframe, - slot, - (unsigned long long)second, - rx_sym, - ru_id); + 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)) #ifdef F_RELEASE for (int ru_idx = 0; ru_idx < num_ports; ru_idx++) { - struct xran_device_ctx *xran_ctx_per_ru = xran_dev_get_ctx_by_id(ru_idx); - struct xran_fh_config *fh_config = &xran_ctx_per_ru->fh_cfg; + struct xran_fh_config *fh_config = get_xran_fh_config(ru_idx); + oran_buf_list_t *bufs = get_xran_buffers(ru_idx); 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 *)xran_ctx_per_ru->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers->pData; + 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); for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { @@ -127,7 +116,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) // would see periodic output with only "0" in stats counters if (!first_call_set) return; - slot2 = slot + (subframe * slots_per_subframe); + 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)))) @@ -181,29 +170,27 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) /* calculate tti and subframe_id from frame, slot num */ int sym_idx = 0; - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - struct xran_prach_cp_config *pPrachCPConfig = &(xran_ctx->PrachCPConfig); - struct xran_ru_config *ru_conf = &(xran_ctx->fh_cfg.ru_conf); - int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology; - int slots_per_subframe = 1 << xran_ctx->fh_cfg.frame_conf.nNumerology; + struct xran_fh_init *fh_init = get_xran_fh_init(); + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int prach_sym = get_prach_conf_duration(0); + struct xran_ru_config *ru_conf = &fh_cfg->ru_conf; + int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; + int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology; int tti = slots_per_frame * (frame) + (slot); uint32_t subframe = slot / slots_per_subframe; uint32_t is_prach_slot = xran_is_prach_slot(0, subframe, (slot % slots_per_subframe)); - int nb_rx_per_ru = ru->nb_rx / xran_ctx->fh_init.xran_ports; + 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) { - for (sym_idx = 0; sym_idx < pPrachCPConfig->numSymbol; sym_idx++) { + for (sym_idx = 0; sym_idx < prach_sym; sym_idx++) { for (int aa = 0; aa < ru->nb_rx; aa++) { int16_t *dst, *src; int idx = 0; - xran_ctx = xran_dev_get_ctx_by_id(aa / nb_rx_per_ru); + oran_buf_list_t *bufs = get_xran_buffers(aa / nb_rx_per_ru); dst = ru->prach_buf[aa]; // + (sym_idx*576)); - src = (int16_t *)((uint8_t *)xran_ctx->sFHPrachRxBbuIoBufCtrlDecomp[tti % XRAN_N_FE_BUF_LEN][0][aa % nb_rx_per_ru] - .sBufferList.pBuffers[sym_idx] - .pData); - + src = (int16_t *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx].pData; /* convert Network order to host order */ if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) { if (sym_idx == 0) { @@ -328,16 +315,16 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) #endif // return(0); - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology; + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; int tti = slots_per_frame * (*frame) + (*slot); read_prach_data(ru, *frame, *slot); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; - int nPRBs = xran_ctx->fh_cfg.nULRBs; - int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize; + const struct xran_fh_init *fh_init = get_xran_fh_init(); + int nPRBs = fh_cfg->nULRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; int slot_offset_rxdata = 3 & (*slot); uint32_t slot_size = 4 * 14 * fftsize; @@ -348,8 +335,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) { rx_data = (uint8_t *)ru->rxdataF[ant_id]; start_ptr = rx_data + (slot_size * slot_offset_rxdata); - xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_rx_per_ru); - const struct xran_frame_config *frame_conf = &xran_ctx->fh_cfg.frame_conf; + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; // skip processing this slot is TX (no RX in this slot) if (is_tdd_dl_guard_slot(frame_conf, *slot)) continue; @@ -361,8 +347,8 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) continue; uint8_t *pData; - uint8_t *pPrbMapData = xran_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_rx_per_ru] - .sBufferList.pBuffers->pData; + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru); + uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0]; @@ -374,8 +360,8 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) uint32_t one_rb_size = (((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1)); if (fh_init->mtu < pRbElm->nRBSize * one_rb_size) - pData = xran_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_rx_per_ru] - .sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT] + 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_sec_desc->pData; @@ -493,22 +479,20 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) int32_t *pos = NULL; int idx = 0; - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; - int nPRBs = xran_ctx->fh_cfg.nDLRBs; - int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize; + const struct xran_fh_init *fh_init = get_xran_fh_init(); + const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int nPRBs = fh_cfg->nDLRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. for (uint8_t ant_id = 0; ant_id < ru->nb_tx; ant_id++) { - xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_tx_per_ru); + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_tx_per_ru); // 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++) { - uint8_t *pData = xran_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_tx_per_ru] - .sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT] - .pData; - uint8_t *pPrbMapData = xran_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_tx_per_ru] - .sBufferList.pBuffers->pData; + uint8_t *pData = + bufs->src[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData; + uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; ptr = pData; pos = &ru->txdataF_BF[ant_id][sym_idx * fftsize]; diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 891634dbfc..ed8f37f857 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -461,6 +461,11 @@ static uint64_t get_u64_mask(const paramdef_t *pd) return mask; } +#ifdef F_RELEASE +char bbdev_dev[32] = ""; +char bbdev_vfio_vf_token[64] = ""; +#endif + static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, int nump, const int num_rus) { DevAssert(fhip != NULL); @@ -474,8 +479,44 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in for (int i = 0; i < num_dev; ++i) { io_cfg->dpdk_dev[i] = strdup(gpd(fhip, nump, ORAN_CONFIG_DPDK_DEVICES)->strlistptr[i]); // VFs devices } +#ifdef F_RELEASE + io_cfg->bbdev_dev[0] = NULL; // BBDev dev name; max devices = 1 + io_cfg->bbdev_vfio_vf_token[0] = NULL; // BBDev dev token; max devices = 1 + char *shlibversion = NULL; // version of the LDPC coding library + paramdef_t LoaderParams_shlibversion[] = {{"shlibversion", NULL, 0, .strptr = &shlibversion, .defstrval = NULL, TYPE_STRING, 0, NULL}}; + config_get(config_get_if(), LoaderParams_shlibversion, sizeofArray(LoaderParams_shlibversion), "loader.ldpc"); + if (shlibversion != NULL && strncmp(shlibversion, "_t2", 3) == 0) { + uint32_t eal_init_bbdev = 0; // If not 0 then include the BBDEV device in the EAL init for FHI + char *dpdk_dev = NULL; // PCI address of the card + char *vfio_vf_token = NULL; // vfio token for the bbdev card + paramdef_t LoaderParams[] = { + {"eal_init_bbdev", NULL, 0, .uptr = &eal_init_bbdev, .defuintval = 0, TYPE_UINT, 0, NULL}, + {"dpdk_dev", NULL, 0, .strptr = &dpdk_dev, .defstrval = NULL, TYPE_STRING, 0, NULL}, + {"vfio_vf_token", NULL, 0, .strptr = &vfio_vf_token, .defstrval = NULL, TYPE_STRING, 0, NULL} + }; + config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_t2"); + + if (eal_init_bbdev != 0) { + AssertFatal(dpdk_dev!=NULL, "nrLDPC_coding_t2.dpdk_dev was not provided"); + snprintf(&bbdev_dev[0], sizeof(bbdev_dev), "%s", dpdk_dev); + io_cfg->bbdev_dev[0] = &bbdev_dev[0]; // BBDev dev name; max devices = 1 + if(vfio_vf_token != NULL) { + snprintf(&bbdev_vfio_vf_token[0], sizeof(bbdev_vfio_vf_token), "%s", vfio_vf_token); + io_cfg->bbdev_vfio_vf_token[0] = &bbdev_vfio_vf_token[0]; // BBDev dev token; max devices = 1 + } else { + io_cfg->bbdev_vfio_vf_token[0] = NULL; // BBDev dev token; max devices = 1 + } + io_cfg->bbdev_mode = XRAN_BBDEV_MODE_HW_ON; // DPDK for BBDev + } else { + io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev + } + } else { + io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev + } +#elif defined(E_RELEASE) io_cfg->bbdev_dev[0] = NULL; // BBDev dev name; max devices = 1 io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev +#endif int dpdk_iova_mode_idx = config_paramidx_fromname((paramdef_t *)fhip, nump, ORAN_CONFIG_DPDK_IOVA_MODE); AssertFatal(dpdk_iova_mode_idx >= 0,"Index for dpdk_iova_mode config option not found!"); io_cfg->dpdkIoVaMode = config_get_processedint(config_get_if(), (paramdef_t *)&fhip[dpdk_iova_mode_idx]); // IOVA mode diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 38e766805a..07517dcf18 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -30,7 +30,9 @@ #include "common/utils/assertions.h" #include "common/utils/LOG/log.h" +#include "common/utils/nr/nr_common.h" #include "common_lib.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h" /* PRACH data samples are 32 bits wide (16bits for I/Q). Each packet contains * 840 samples for long sequence or 144 for short sequence. The payload length @@ -46,6 +48,10 @@ static oran_port_instance_t gPortInst[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; void *gxran_handle; +static struct xran_fh_init g_fh_init = {0}; +static struct xran_fh_config g_fh_config[XRAN_PORTS_NUM] = {0}; +static uint32_t g_prach_conf_duration[XRAN_PORTS_NUM] = {0}; + static uint32_t get_nSW_ToFpga_FTH_TxBufferLen(int mu, int sections) { uint32_t xran_max_sections_per_slot = RTE_MAX(sections, XRAN_MIN_SECTIONS_PER_SLOT); @@ -460,7 +466,47 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi printf("xran_reg_physide_cb failed %d\n", xret); exit(-1); } + + // retrieve and store prach duration + uint8_t idx = xran_fh_config[o_xu_id].prach_conf.nPrachConfIdx; + const struct xran_frame_config *fc = &xran_fh_config[o_xu_id].frame_conf; + g_prach_conf_duration[o_xu_id] = + get_nr_prach_occasion_info_from_index(idx, + fc->nNumerology > 2 ? FR2 : FR1, + fc->nFrameDuplexType == XRAN_FDD ? duplex_mode_FDD : duplex_mode_TDD) + .N_dur; } + // store config after xran initialization -- xran makes modifications to + // these structs during initialization + memcpy(&g_fh_init, xran_fh_init, sizeof(*xran_fh_init)); + memcpy(&g_fh_config, xran_fh_config, sizeof(*xran_fh_config) * xran_fh_init->xran_ports); + return (void *)gxran_handle; } + +oran_buf_list_t *get_xran_buffers(uint32_t port_id) +{ + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); + return gPortInst[port_id][0].buf_list; +} + +struct xran_fh_init *get_xran_fh_init(void) +{ + return &g_fh_init; +} + +struct xran_fh_config *get_xran_fh_config(uint32_t port_id) +{ + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); + return &g_fh_config[port_id]; +} + +uint32_t get_prach_conf_duration(uint32_t port_id) +{ + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); + return g_prach_conf_duration[port_id]; +} diff --git a/radio/fhi_72/oran-init.h b/radio/fhi_72/oran-init.h index b9f31d9889..e56b683a9f 100644 --- a/radio/fhi_72/oran-init.h +++ b/radio/fhi_72/oran-init.h @@ -59,4 +59,9 @@ extern void *gxran_handle; int *oai_oran_initialize(struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); +oran_buf_list_t *get_xran_buffers(uint32_t port_id); +struct xran_fh_init *get_xran_fh_init(void); +struct xran_fh_config *get_xran_fh_config(uint32_t port_id); +uint32_t get_prach_conf_duration(uint32_t port_id); + #endif /* ORAN_INIT_H */ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 7ceec513c6..4a141275d7 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -103,6 +103,11 @@ int trx_oran_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) int trx_oran_get_stats(openair0_device *device) { + uint64_t total_time, used_time; + uint32_t num_core_used, core_used[64]; + uint32_t ret = xran_get_time_stats(&total_time, &used_time, &num_core_used, &core_used[0], 0); + if (ret == 0) + LOG_I(HW, "xran_get_time_stats(): total thread time %ld, total time essential tasks %ld, num cores used %d\n", total_time, used_time, num_core_used); printf("ORAN: %s\n", __FUNCTION__); return (0); }