#*
#*******************************************************************************/
-PHONY: all
-all:
- cd lls-cu && make #DEBUG=1
- cd ru && make #DEBUG=1
+MYCUSTOMTAB=' '
+MYCUSTOMSPACE='============================================================================================'
+MYCUSTOMSPACE1='------------------------------------------------------------'
-clean:
- cd lls-cu && make clean #DEBUG=1
- cd ru && make clean #DEBUG=1
+##############################################################
+# Tools configuration
+##############################################################
+CC := icc
+CPP := icpc
+AS := as
+AR := ar
+LD := icc
+OBJDUMP := objdump
+ifeq ($(SHELL),cmd.exe)
+MD := mkdir.exe -p
+CP := cp.exe -f
+RM := rm.exe -rf
+else
+MD := mkdir -p
+CP := cp -f
+RM := rm -rf
+endif
+
+PROJECT_NAME := sample-app
+PROJECT_TYPE := elf
+PROJECT_DIR := $(XRAN_DIR)/app
+BUILDDIR := ./build
+PROJECT_BINARY := $(BUILDDIR)/$(PROJECT_NAME)
+
+ifeq ($(RTE_SDK),)
+ $(error "Please define RTE_SDK environment variable")
+endif
+
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
+
+API_DIR := $(XRAN_DIR)/lib/api
+SRC_DIR := $(PROJECT_DIR)/src
+
+ifeq ($(MLOG),1)
+ifeq ($(MLOG_DIR),)
+ MLOG_DIR=$(XRAN_DIR)/../mlog
+endif
+endif
+
+CC_SRC = $(SRC_DIR)/common.c \
+ $(SRC_DIR)/sample-app.c \
+ $(SRC_DIR)/config.c
+
+CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
+ -fdata-sections \
+ -ffunction-sections \
+ -g \
+ -Wall \
+ -Wimplicit-function-declaration \
+ -g -O3
+
+CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+ -no-prec-div -fp-model fast=2\
+ -no-prec-sqrt -falign-functions=16 -fast-transcendentals \
+ -Werror -Wno-unused-variable -std=c++11 -mcmodel=large
+
+INC := -I$(API_DIR) -I$(RTE_INC)
+DEF :=
+
+ifeq ($(MLOG),1)
+ INC += -I$(MLOG_DIR)/source
+ DEF += -DMLOG_ENABLED
+else
+ DEF += -UMLOG_ENABLED
+endif
+
+XRAN_LIB_DIR=$(XRAN_DIR)/lib/build
+LD_FLAGS += -L$(XRAN_LIB_DIR) -lxran
+
+RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
+LD_FLAGS += $(RTE_LIBS)
+
+ifeq ($(MLOG),1)
+ LD_FLAGS += -L$(MLOG_DIR)/bin -lmlog
+endif
+
+AS_FLAGS :=
+AR_FLAGS := rc
+
+PROJECT_OBJ_DIR := build/obj
+
+CC_OBJS := $(patsubst %.c,%.o,$(CC_SRC))
+CPP_OBJS := $(patsubst %.cpp,%.o,$(CPP_SRC))
+AS_OBJS := $(patsubst %.s,%.o,$(AS_SRC))
+OBJS := $(CC_OBJS) $(CPP_OBJS) $(AS_OBJS) $(LIBS)
+DIRLIST := $(addprefix $(PROJECT_OBJ_DIR)/,$(sort $(dir $(OBJS))))
+
+CC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CC_OBJS))
+CPP_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS))
+
+AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
+
+CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF)
+CPP_FLAGS_FULL := $(CPP_FLAGS) $(INC) $(DEF)
+
+AS_FLAGS := $(AS_FLAGS) $(INC)
+
+PROJECT_DEP_FILE := $(PROJECT_OBJ_DIR)/$(PROJECT_NAME).dep
+
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+GENERATE_DEPS :=
+else
+
+CC_DEPS := $(addprefix __dep__,$(subst ../,__up__,$(CC_SRC)))
+CPP_DEPS := $(addprefix __dep__,$(subst ../,__up__,$(CPP_SRC)))
+GENERATE_DEPS := generate_deps
+endif
+
+all : welcome_line $(PROJECT_BINARY)
+ @echo $(PROJECT_BINARY)
+
+.PHONY : clear_dep
+clear_dep:
+ @$(RM) $(PROJECT_DEP_FILE)
+ @echo [DEP] $(subst $(PROJECT_OBJ_DIR)/,,$(PROJECT_DEP_FILE))
+
+$(CC_DEPS) :
+ @$(CC) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.c,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CC_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+$(CPP_DEPS) :
+ @$(CPP) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.cpp,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CPP_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+.PHONY : generate_deps
+generate_deps : clear_dep $(CC_DEPS) $(CPP_DEPS)
+
+
+.PHONY : echo_start_build
+echo_start_build :
+ @echo [BUILD] $(PROJECT_TYPE) : $(PROJECT_NAME)
+
+$(DIRLIST) :
+ -@$(MD) $@
+
+$(CC_OBJTARGETS) :
+ @echo [CC] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(CC) -c $(CC_FLAGS_FULL) -o"$@" $(patsubst %.o,%.c,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(CPP_OBJTARGETS) :
+ @echo [CPP] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(CPP) -c $(CPP_FLAGS_FULL) -o"$@" $(patsubst %.o,%.cpp,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(AS_OBJTARGETS) :
+ @echo [AS] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(AS) $(AS_FLAGS) -o"$@" $(patsubst %.o,%.s,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+
+include $(PROJECT_DEP_FILE)
+
+endif
+
+.PHONY: clean xclean
+clean:
+ @echo [CLEAN] : $(PROJECT_NAME)
+ @$(RM) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+
+xclean: clean
+ifneq ($(wildcard $(PROJECT_DIR)/$(PROJECT_MAKE)),)
+ @echo [XCLEAN] : $(PROJECT_NAME)
+ @$(RM) $(PROJECT_BINARY) $(PROJECT_BINARY_LIB) $(PROJECT_DEP_FILE)
+endif
+
+.PHONY : welcome_line
+welcome_line :
+ @echo $(MYCUSTOMSPACE)
+ @echo Building $(PROJECT_BINARY)
+ @echo $(MYCUSTOMTAB)RTE_TARGET = $(RTE_TARGET)
+ @echo $(MYCUSTOMSPACE)
+
+
+.PHONY : debug release
+
+debug : all
+release : all
+
+$(PROJECT_BINARY): $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+ @echo "[LD] $@ "
+ @$(LD) -o $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS) $(LD_FLAGS) -Wl,-L $(BUILDDIR) -lrt -lpthread
+
+#@echo [APP] $@
+#@$(OBJDUMP) -d $(PROJECT_BINARY) > $(PROJECT_BINARY).asm
+++ /dev/null
-/******************************************************************************
-*
-* Copyright (c) 2019 Intel.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-*******************************************************************************/
-
-#ifndef _XRAN_APP_COMMON_
-#define _XRAN_APP_COMMON_
-
-#include <assert.h>
-#include <err.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "../common/common.h"
-#include "xran_pkt.h"
-#include "xran_pkt_up.h"
-#include "xran_cp_api.h"
-#include "xran_up_api.h"
-#include "../src/xran_printf.h"
-
-
-#define MBUFS_CNT 256
-
-extern enum app_state state;
-
-uint8_t numCCPorts = 1;
-/* Number of antennas supported by front-end */
-
-uint8_t num_eAxc = 4;
-/* Number of CPRI ports supported by front-end */
-
-int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_prach_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t prach_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-int32_t prach_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_tx_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t tx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-
-int16_t *p_rx_buffer[MAX_ANT_CARRIER_SUPPORTED];
-int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
-
-void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
- if (size)
- {
- if (filename && bufname)
- {
- FILE *file;
- printf("Storing %s to file %s: ", bufname, filename);
- file = fopen(filename, "wb");
- if (file == NULL)
- {
- print_err("can't open file %s!!!", filename);
- }
- else
- {
- uint32_t num;
- num = fwrite(pBuffer, buffers_num, size, file);
- fflush(file);
- fclose(file);
- printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
- }
- printf(" \n");
- }
- else
- {
- print_err(" the file name, buffer name are not set!!!");
- }
- }
- else
- {
- print_err(" the %s is free: size = %d bytes!!!", bufname, size);
- }
-}
-
-int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
- unsigned int file_size = 0;
- int num= 0;
-
- if (size)
- {
- if (filename && bufname)
- {
- FILE *file;
- printf("Loading file %s to %s: ", filename, bufname);
- file = fopen(filename, "rb");
-
-
- if (file == NULL)
- {
- print_err("can't open file %s!!!", filename);
- exit(-1);
- }
- else
- {
- fseek(file, 0, SEEK_END);
- file_size = ftell(file);
- fseek(file, 0, SEEK_SET);
-
- if ((file_size > size) || (file_size == 0))
- file_size = size;
-
- printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
-
- num = fread(pBuffer, buffers_num, size, file);
- fflush(file);
- fclose(file);
- printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
- }
- printf(" \n");
-
- }
- else
- {
- print_err(" the file name, buffer name are not set!!!");
- }
- }
- else
- {
- print_err(" the %s is free: size = %d bytes!!!", bufname, size);
- }
- return num;
-}
-
-
-void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
-{
- unsigned int i;
- int ret = 0;
- if (pBuffer == NULL)
- return;
-
- if (size)
- {
- if (filename && bufname)
- {
- FILE *file;
- printf("Storing %s to file %s: ", bufname, filename);
- file = fopen(filename, "w");
- if (file == NULL)
- {
- print_err("can't open file %s!!!", filename);
- exit(-1);
- }
- else
- {
- uint32_t num = 0;
-
- signed short *ptr = (signed short*)pBuffer;
- for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
- {
- ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
- if (ret < 0)
- {
- printf("fprintf %d\n", ret);
- fclose(file);
- break;
- }
- num++;
- }
- fflush(file);
- fclose(file);
- printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
- }
- printf(" \n");
- }
- else
- {
- print_err(" the file name, buffer name are not set!!!");
- }
- }
- else
- {
- print_err(" the %s is free: size = %d bytes!!!", bufname, size);
- }
-}
-
-
-#endif /* _XRAN_APP_COMMON_ */
+++ /dev/null
-#######################################################################
-#
-# <COPYRIGHT_TAG>
-#
-#######################################################################
-
-# This is simple configuration file. Use '#' sign for comments
-appMode=0 # lls-CU(0) | RU(1)
-xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
-ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
-##Numerology
-mu=3 #mmWave 120Khz Sub Carrier Spacing
-antNum=4 # Number of Antennas per CC (default: 4)
-ttiPeriod=125 # in us TTI period (mmWave default 125us)
-llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
-ruMac=00:11:22:33:44:55 #RU VF for RU app
-#ruMac=3c:fd:fe:b1:d8:98 #RU PF for tcpdump
-#56:1e:4b:0c:f5:9b # RU MAC
-antC0=./ant_0.bin #CC0
-antC1=./ant_1.bin #CC0
-antC2=./ant_2.bin #CC0
-antC3=./ant_3.bin #CC0
-antC4=./ant_4.bin #CC1
-antC5=./ant_5.bin #CC1
-antC6=./ant_6.bin #CC1
-antC7=./ant_7.bin #CC1
-antC8=./ant_8.bin #CC2
-antC9=./ant_9.bin #CC2
-antC10=./ant_10.bin #CC2
-antC11=./ant_11.bin #CC2
-antC12=./ant_12.bin #CC3
-antC13=./ant_13.bin #CC3
-antC14=./ant_14.bin #CC3
-antC15=./ant_15.bin #CC3
-
-## RACH TODO: update for PRACH
-#rachEanble=1 # Enable (1)| disable (0) PRACH configuration
-#rachOffset=43 # RB offset for prach detection (see RIU spec)
-#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
-
-## control of IQ byte order
-iqswap=0 #do swap of IQ before send buffer to eth
-nebyteorderswap=0 #do swap of byte order for each I and Q from CPU byte order to network byte order
-
-##Debug
-debugStop=0 #stop app on 1pps boundary (gps_second % 30)
-
-CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
-c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
-u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
-
-##RU Settings
-Tadv_cp_dl=25 #in us TODO: update per RU implementation
- #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
-
-#Reception Window C-plane DL
-T2a_min_cp_dl=50 #in us TODO: update per RU implementation
-T2a_max_cp_dl=140 #in us TODO: update per RU implementation
-
-#Reception Window C-plane UL
-T2a_min_cp_ul=50 #in us TODO: update per RU implementation
-T2a_max_cp_ul=140 #in us TODO: update per RU implementation
-
-#Reception Window U-plane
-T2a_min_up=25 #in us
-T2a_max_up=140 #in us
-
-#Transmission Window
-Ta3_min=20 #in us
-Ta3_max=32 #in us
-
-###########################################################
-##lls-CU Settings
-#C-plane
-#Transmission Window Fast C-plane DL
-T1a_min_cp_dl=70
-T1a_max_cp_dl=100
-
-##Transmission Window Fast C-plane UL
-T1a_min_cp_ul=70
-T1a_max_cp_ul=80
-
-#U-plane
-##Transmission Window
-T1a_min_up=35
-T1a_max_up=50
-
-#Reception Window
-Ta4_min=0
-Ta4_max=45
-###########################################################
-
+++ /dev/null
-#######################################################################
-#
-# <COPYRIGHT_TAG>
-#
-#######################################################################
-
-# This is simple configuration file. Use '#' sign for comments
-appMode=1 # lls-CU(0) | RU(1)
-xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
-ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
-##Numerology
-mu=3 #mmWave 120Khz Sub Carrier Spacing
-antNum=4 # Number of Antennas per CC (default: 4)
-ttiPeriod=125 # in us TTI period (mmWave default 125us)
-llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
-#llsCUMac=3c:fd:fe:9e:93:68 # PF for tcpdump
-ruMac=00:11:22:33:44:55
-#56:1e:4b:0c:f5:9b # RU MAC
-antC0=./ant_0.bin #CC0
-antC1=./ant_1.bin #CC0
-antC2=./ant_2.bin #CC0
-antC3=./ant_3.bin #CC0
-antC4=./ant_4.bin #CC1
-antC5=./ant_5.bin #CC1
-antC6=./ant_6.bin #CC1
-antC7=./ant_7.bin #CC1
-antC8=./ant_8.bin #CC2
-antC9=./ant_9.bin #CC2
-antC10=./ant_10.bin #CC2
-antC11=./ant_11.bin #CC2
-antC12=./ant_12.bin #CC3
-antC13=./ant_13.bin #CC3
-antC14=./ant_14.bin #CC3
-antC15=./ant_15.bin #CC3
-
-## RACH TODO: update for PRACH
-#rachEanble=1 # Enable (1)| disable (0) PRACH configuration
-#rachOffset=43 # RB offset for prach detection (see RIU spec)
-#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
-
-## control of IQ byte order
-iqswap=0 #do swap of IQ before send buffer to eth
-nebyteorderswap=0 #do swap of byte order for each I and Q from CPU byte order to network byte order
-
-##Debug
-debugStop=0 #stop app on 1pps boundary (gps_second % 30)
-
-CPenable=0 #(1) C-Plane is enabled| 0 C-Plane is disabled
-c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
-u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
-
-##RU Settings
-Tadv_cp_dl=25 #in us TODO: update per RU implementation
- #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
-
-#Reception Window C-plane DL
-T2a_min_cp_dl=50 #in us TODO: update per RU implementation
-T2a_max_cp_dl=140 #in us TODO: update per RU implementation
-
-#Reception Window C-plane UL
-T2a_min_cp_ul=50 #in us TODO: update per RU implementation
-T2a_max_cp_ul=140 #in us TODO: update per RU implementation
-
-#Reception Window U-plane
-T2a_min_up=25 #in us
-T2a_max_up=140 #in us
-
-#Transmission Window
-Ta3_min=20 #in us
-Ta3_max=32 #in us
-
-###########################################################
-##lls-CU Settings
-#C-plane
-#Transmission Window Fast C-plane DL
-T1a_min_cp_dl=70
-T1a_max_cp_dl=100
-
-##Transmission Window Fast C-plane UL
-T1a_min_cp_ul=70
-T1a_max_cp_ul=80
-
-#U-plane
-##Transmission Window
-T1a_min_up=35
-T1a_max_up=50
-
-#Reception Window
-Ta4_min=10
-Ta4_max=100
-###########################################################
-
#*
#*******************************************************************************/
+
export RTE_SDK=/home/turner/dpdk
export RTE_TARGET=x86_64-native-linuxapp-icc
fi
}
+#
+# Unloads VFIO modules.
+#
+remove_vfio_module()
+{
+ echo "Unloading any existing VFIO module"
+ /sbin/lsmod | grep -s vfio > /dev/null
+ if [ $? -eq 0 ] ; then
+ sudo /sbin/rmmod vfio-pci
+ sudo /sbin/rmmod vfio_iommu_type1
+ sudo /sbin/rmmod vfio
+ fi
+}
+
+#
+# Loads new vfio-pci (and vfio module if needed).
+#
+load_vfio_module()
+{
+ remove_vfio_module
+
+ VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
+
+ echo "Loading VFIO module"
+ /sbin/lsmod | grep -s vfio_pci > /dev/null
+ if [ $? -ne 0 ] ; then
+ if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
+ sudo /sbin/modprobe vfio-pci
+ fi
+ fi
+
+ # make sure regular users can read /dev/vfio
+ echo "chmod /dev/vfio"
+ sudo chmod a+x /dev/vfio
+ if [ $? -ne 0 ] ; then
+ echo "FAIL"
+ quit
+ fi
+ echo "OK"
+
+ # check if /dev/vfio/vfio exists - that way we
+ # know we either loaded the module, or it was
+ # compiled into the kernel
+ if [ ! -e /dev/vfio/vfio ] ; then
+ echo "## ERROR: VFIO not found!"
+ fi
+}
+
+
load_igb_uio_module
+load_vfio_module
CPU_FEATURES_DETECT=`cat /proc/cpuinfo |grep hypervisor | wc -l`
$RTE_SDK/usertools/dpdk-devbind.py --status
if [ ${VM_DETECT} == 'HOST' ]; then
#HOST
- $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:d8:02.0
- $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:d8:02.1
- $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:07:02.0
- $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:07:02.1
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:86:02.0
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:86:02.1
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:d8:02.0
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:d8:02.1
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.0
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.1
+
else
#VM
$RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:00:04.0
%*
%*******************************************************************************/
-%Matlab: read bin
-%fileID_c = fopen('ant_7.bin','r');
-%ant7_c= fread(fileID_c, [2, 792*14*80], 'integer*2');
-%ant7_c;
-%ant7_c=ant7_c.';
-
close all;
clear all;
-ifft_in = load('ifft_in.txt')
+%select mu and bw to generate test files
+sub6=false; %false
+mu=3; % 0,1, or 3
+bw=100; %5,10,20,100 MHz
+
+nSlots=160; % any 40 and 160
+
+ % 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+nNumRbsPerSymF1 = ...
+[
+ % 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+ [25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0] % Numerology 0 (15KHz)
+ [11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273] % Numerology 1 (30KHz)
+ [0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135] % Numerology 2 (60KHz)
+];
+
+nNumRbsPerSymF2 = ...
+[
+ % 50Mhz 100MHz 200MHz 400MHz
+ [66, 132, 264, 0] % Numerology 2 (60KHz)
+ [32, 66, 132, 264] % Numerology 3 (120KHz)
+];
+
+if sub6
+ disp('Sub6')
+ if mu < 3
+ nNumerology = mu+1;
+ switch (bw)
+ case {5}
+ numRBs = nNumRbsPerSymF1(nNumerology,0+1);
+ case {10}
+ numRBs = nNumRbsPerSymF1(nNumerology,1+1);
+ case {15}
+ numRBs = nNumRbsPerSymF1(nNumerology,2+1);
+ case {20}
+ numRBs = nNumRbsPerSymF1(nNumerology,3+1);
+ case {25}
+ numRBs = nNumRbsPerSymF1(nNumerology,4+1);
+ case {30}
+ numRBs = nNumRbsPerSymF1(nNumerology,5+1);
+ case {40}
+ numRBs = nNumRbsPerSymF1(nNumerology,6+1);
+ case {50}
+ numRBs = nNumRbsPerSymF1(nNumerology,7+1);
+ case {60}
+ numRBs = nNumRbsPerSymF1(nNumerology,8+1);
+ case {70}
+ numRBs = nNumRbsPerSymF1(nNumerology,9+1);
+ case {80}
+ numRBs = nNumRbsPerSymF1(nNumerology,10+1);
+ case {90}
+ numRBs = nNumRbsPerSymF1(nNumerology,11+1);
+ case {100}
+ numRBs = nNumRbsPerSymF1(nNumerology,12+1);
+ otherwise
+ disp('Unknown BW && mu')
+ end
+ end
+else
+ disp('mmWave')
+ if (mu >=2) && (mu <= 3)
+ nNumerology = mu;
+ switch (bw)
+ case {50}
+ numRBs = nNumRbsPerSymF2(nNumerology-1,0+1);
+ case {100}
+ numRBs = nNumRbsPerSymF2(nNumerology-1,1+1);
+ case {200}
+ numRBs = nNumRbsPerSymF2(nNumerology-1,2+1);
+ case {400}
+ numRBs = nNumRbsPerSymF2(nNumerology-1,3+1);
+ otherwise
+ disp('Unknown BW && mu')
+ end
+ end
+end
+
+if numRBs ==0
+ disp('Incorrect Numerology and BW combination.')
+ return
+end
+
+bw
+numRBs
+nSlots
+
+%use file as input
+%ifft_in = load('ifft_in.txt')
+
+%gen IQs
+ifft_in = [[1:1:(numRBs*12)]', [1:1:(numRBs*12)]'];
+
ant_c = ifft_in;
-for (i=1:1:80*14-1)
- ant_c = [ant_c; ifft_in];
+for (i=1:1:nSlots*14-1)
+ ifft_in_1 = ifft_in + i;
+ ant_c = [ant_c; ifft_in_1];
end
ant0=ant_c;
--- /dev/null
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,-1
+19,0
+19,-1
+19,-1
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+19,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,0
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,1
+20,2
+20,1
+20,1
+20,1
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+20,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,2
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,3
+21,4
+21,4
+22,4
+21,3
+21,3
+21,4
+21,4
+21,4
+21,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,4
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+22,5
+23,5
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,6
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+23,7
+24,7
+24,7
+24,7
+24,7
+24,7
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,8
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+24,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,9
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,10
+25,11
+25,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,11
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+26,12
+27,12
+27,12
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,13
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+27,14
+28,14
+28,14
+28,14
+28,14
+28,14
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,15
+28,16
+28,16
+28,16
+28,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,16
+29,17
+29,17
+28,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,17
+29,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,18
+30,19
+30,18
+30,19
+30,19
+30,19
+30,19
+30,19
+31,19
+31,19
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,20
+31,21
+31,21
+31,21
+31,21
+32,21
+31,21
+32,21
+32,21
+32,21
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,22
+32,23
+32,23
+32,23
+33,23
+33,23
+33,23
+33,23
+33,23
+33,24
+34,24
+33,24
+33,24
+33,24
+33,24
+33,24
+33,24
+34,25
+34,25
+34,25
+34,25
+34,25
+34,25
+34,25
+34,26
+34,26
+34,26
+34,26
+34,26
+35,26
+35,26
+35,26
+35,27
+35,27
+35,27
+35,27
+35,27
+35,28
+35,28
+35,28
+36,28
+36,28
+36,28
+36,29
+36,29
+36,29
+36,29
+36,29
+36,29
+36,30
+36,30
+37,30
+37,30
+37,30
+37,30
+37,31
+37,31
+37,31
+37,31
+37,31
+38,32
+38,32
+38,32
+38,32
+38,32
+38,33
+38,33
+38,33
+38,33
+39,33
+39,34
+39,34
+39,34
+39,34
+39,34
+39,35
+39,35
+40,35
+40,35
+40,35
+40,36
+40,36
+40,36
+40,36
+41,37
+41,37
+41,37
+41,37
+41,38
+41,38
+41,38
+41,38
+42,39
+42,39
+42,39
+42,40
+42,39
+42,40
+43,40
+43,40
+43,41
+43,41
+43,41
+43,42
+44,42
+44,42
+44,42
+44,43
+44,43
+44,43
+45,44
+45,44
+45,44
+45,45
+45,45
+45,45
+46,46
+46,46
+46,46
+46,47
+46,47
+47,47
+47,48
+47,48
+47,48
+47,49
+48,49
+48,49
+48,50
+48,50
+49,51
+49,51
+49,51
+49,52
+49,52
+50,53
+50,53
+50,53
+50,54
+51,54
+51,55
+51,55
+51,56
+52,56
+52,57
+52,57
+53,57
+53,58
+53,58
+53,59
+54,59
+54,60
+54,61
+55,61
+55,62
+56,63
+56,63
+56,64
+57,64
+57,65
+57,66
+58,66
+58,67
+58,67
+59,68
+59,69
+59,69
+60,70
+60,71
+61,71
+61,72
+61,73
+62,74
+62,74
+63,75
+63,76
+64,77
+64,77
+64,78
+65,79
+65,80
+66,81
+66,82
+67,82
+67,83
+68,84
+69,85
+69,86
+70,87
+70,88
+71,89
+71,90
+72,91
+73,92
+73,93
+74,95
+75,96
+75,97
+76,98
+77,99
+77,101
+78,102
+79,103
+80,105
+80,106
+81,107
+82,109
+83,110
+84,112
+85,113
+86,115
+87,117
+88,118
+89,120
+90,122
+91,124
+92,126
+93,128
+94,130
+95,132
+97,134
+98,136
+99,138
+100,140
+102,143
+103,145
+105,148
+106,151
+108,153
+110,156
+111,159
+113,162
+115,165
+117,169
+119,172
+121,176
+123,179
+125,183
+127,187
+130,191
+132,195
+135,200
+138,205
+140,210
+143,215
+146,220
+150,226
+153,232
+157,238
+161,245
+165,252
+169,259
+173,267
+178,275
+183,284
+189,293
+194,303
+201,314
+207,325
+214,337
+222,351
+230,365
+239,380
+248,397
+259,415
+271,435
+283,457
+297,481
+312,507
+330,537
+349,571
+371,608
+395,651
+424,701
+457,758
+496,826
+543,907
+600,1005
+670,1127
+759,1281
+877,1485
+1038,1765
+1275,2175
+1653,2829
+2355,4046
+4111,7086
+16399,28370
+-8177,-14197
+-3262,-5684
+-2033,-3556
+-1475,-2588
+-1156,-2035
+-949,-1678
+-805,-1427
+-698,-1242
+-616,-1100
+-550,-987
+-497,-895
+-454,-819
+-417,-755
+-385,-700
+-358,-653
+-334,-612
+-313,-576
+-295,-544
+-278,-515
+-263,-489
+-250,-466
+-238,-444
+-226,-425
+-216,-408
+-207,-392
+-198,-377
+-190,-363
+-183,-350
+-176,-338
+-169,-327
+-163,-317
+-158,-307
+-153,-298
+-148,-289
+-143,-281
+-138,-273
+-134,-266
+-130,-259
+-127,-253
+-123,-247
+-120,-241
+-116,-235
+-113,-230
+-110,-225
+-108,-220
+-105,-215
+-102,-211
+-100,-206
+-98,-202
+-95,-198
+-93,-195
+-91,-191
+-89,-188
+-87,-184
+-85,-181
+-83,-178
+-82,-175
+-80,-172
+-78,-169
\ No newline at end of file
+++ /dev/null
-#/******************************************************************************
-#*
-#* Copyright (c) 2019 Intel.
-#*
-#* Licensed under the Apache License, Version 2.0 (the "License");
-#* you may not use this file except in compliance with the License.
-#* You may obtain a copy of the License at
-#*
-#* http://www.apache.org/licenses/LICENSE-2.0
-#*
-#* Unless required by applicable law or agreed to in writing, software
-#* distributed under the License is distributed on an "AS IS" BASIS,
-#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#* See the License for the specific language governing permissions and
-#* limitations under the License.
-#*
-#*******************************************************************************/
-CC := icc
-
-ifeq ($(RTE_SDK),)
- $(error "Please define RTE_SDK environment variable")
-endif
-
-RTE_TARGET := x86_64-native-linuxapp-icc
-RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-
-ifeq ($(XRAN_DIR),)
- XRAN_DIR=$(PWD)/../..
-endif
-
-COMMON_SRC=$(XRAN_DIR)/app/common
-SRC_SRC=$(XRAN_DIR)/app/src
-
-ifeq ($(MLOG_DIR),)
- MLOG_DIR=$(XRAN_DIR)/../mlog
-endif
-
-APP = sample-lls-cu
-SRC = $(COMMON_SRC)/common.c \
- ./sample-lls-cu.c \
- $(SRC_SRC)/config.c
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wextra -Werror -I$(XRAN_DIR)/lib/api -I$(COMMON_SRC) -I$(SRC_SRC) -I$(MLOG_DIR)/source -I$(RTE_INC)
-ifeq ($(ME),1)
- CFLAGS += -DMLOG_ENABLED
-endif
-ifeq ($(NB),1)
- CFLAGS += -DNightly_build
-endif
-
-ifeq ($(DEBUG),1)
- CFLAGS += -DDEBUG -O0 -g
-else
- CFLAGS += -O3
-endif
-
-ifeq ($(MULTI_SECTION),1)
- CFLAGS += -DMULTI_SECTION
-endif
-
-LDFLAGS += -pthread -lrt
-
-RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
-
-XRAN_LIB_DIR=$(XRAN_DIR)/lib/bin
-LDFLAGS += -L$(XRAN_LIB_DIR) -Wl, -lxran -Wl, -L$(MLOG_DIR)/bin -Wl, $(RTE_LIBS)
-ifeq ($(ME),1)
- LDFLAGS += -Wl,-lmlog
-endif
-
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
-
-
-all: $(APP) install
-
-$(OBJ): %.o: %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-$(APP): $(OBJ)
- $(CC) -o $(APP) $(CFLAGS) $(OBJ) $(LDFLAGS)
-
-install: $(APP)
- @mkdir -p bin
- @cp $(APP) ./bin
-
-clean:
- @rm -rf $(APP) $(OBJ) ./bin/$(APP)
-
-#include $(RTE_SDK)/mk/rte.extapp.mk
+++ /dev/null
-#/******************************************************************************
-#*
-#* Copyright (c) 2019 Intel.
-#*
-#* Licensed under the Apache License, Version 2.0 (the "License");
-#* you may not use this file except in compliance with the License.
-#* You may obtain a copy of the License at
-#*
-#* http://www.apache.org/licenses/LICENSE-2.0
-#*
-#* Unless required by applicable law or agreed to in writing, software
-#* distributed under the License is distributed on an "AS IS" BASIS,
-#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#* See the License for the specific language governing permissions and
-#* limitations under the License.
-#*
-#*******************************************************************************/
-CC := icc
-
-ifeq ($(RTE_SDK),)
- $(error "Please define RTE_SDK environment variable")
-endif
-
-RTE_TARGET := x86_64-native-linuxapp-icc
-RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-
-ifeq ($(XRAN_DIR),)
- XRAN_DIR=$(PWD)/../..
-endif
-
-COMMON_SRC=$(XRAN_DIR)/app/common
-SRC_SRC=$(XRAN_DIR)/app/src
-
-ifeq ($(MLOG_DIR),)
- MLOG_DIR=$(XRAN_DIR)/../mlog
-endif
-APP = sample-ru
-SRC = $(COMMON_SRC)/common.c \
- ../lls-cu/sample-lls-cu.c \
- $(SRC_SRC)/config.c
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wextra -Werror -I$(XRAN_DIR)/lib/api -I$(COMMON_SRC) -I$(SRC_SRC) -I$(MLOG_DIR)/source -I$(RTE_INC)
-ifeq ($(ME),1)
- CFLAGS += -DMLOG_ENABLED
-endif
-
-ifeq ($(DEBUG),1)
- CFLAGS += -DDEBUG -O0 -g
-else
- CFLAGS += -O3
-endif
-
-ifeq ($(MULTI_SECTION),1)
- CFLAGS += -DMULTI_SECTION
-endif
-
-LDFLAGS += -pthread -lrt
-
-RTE_LIBS = -L$(RTE_SDK)/$(RTE_TARGET)/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_octeontx -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_qat -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,
-
-XRAN_LIB_DIR=$(XRAN_DIR)/lib/bin
-LDFLAGS += -L$(XRAN_LIB_DIR) -Wl, -lxran -Wl, -L$(MLOG_DIR)/bin -Wl, $(RTE_LIBS)
-ifeq ($(ME),1)
- LDFLAGS += -Wl,-lmlog
-endif
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
-
-
-all: $(APP) install
-
-$(OBJ): %.o: %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-$(APP): $(OBJ)
- $(CC) -o $(APP) $(CFLAGS) $(OBJ) $(LDFLAGS)
-
-install: $(APP)
- @mkdir -p bin
- @cp $(APP) ./bin
-
-clean:
- @rm -rf $(APP) $(OBJ) ./bin/$(APP)
-
-#include $(RTE_SDK)/mk/rte.extapp.mk
#*
#*******************************************************************************/
-
ulimit -c unlimited
echo 1 > /proc/sys/kernel/core_uses_pid
mount none $huge_folder -t hugetlbfs -o rw,mode=0777
fi
-./lls-cu/bin/sample-lls-cu config_file_lls_cu.dat 0000:18:02.0 0000:18:02.1
+#40G
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat 0000:d8:02.0 0000:d8:02.1
+
+#25G
+#./build/sample-app ./usecase/mu0_10mhz/12/config_file_o_du.dat 0000:af:02.0 0000:af:02.1
umount $huge_folder
rmdir $huge_folder
mount none $huge_folder -t hugetlbfs -o rw,mode=0777
fi
-./ru/bin/sample-ru config_file_ru.dat 0000:18:02.0 0000:18:02.1
+#40G
+./build/sample-app ./usecase/mu1_100mhz/config_file_o_ru.dat 0000:d8:02.0 0000:d8:02.1
umount $huge_folder
rmdir $huge_folder
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+#include <assert.h>
+#include <err.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "common.h"
+#include "xran_fh_o_du.h"
+#include "xran_pkt.h"
+#include "xran_pkt_up.h"
+#include "xran_cp_api.h"
+#include "xran_up_api.h"
+
+#include "xran_mlog_lnx.h"
+
+extern enum app_state state;
+
+int iq_playback_buffer_size_dl = IQ_PLAYBACK_BUFFER_BYTES;
+int iq_playback_buffer_size_ul = IQ_PLAYBACK_BUFFER_BYTES;
+
+uint8_t numCCPorts = 1;
+/* Number of antennas supported by front-end */
+
+uint8_t num_eAxc = 4;
+/* Number of CPRI ports supported by front-end */
+
+int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_tx_prach_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_prach_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_prach_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_prach_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t prach_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+int32_t prach_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_tx_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t tx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+
+int16_t *p_rx_buffer[MAX_ANT_CARRIER_SUPPORTED];
+int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+
+
+// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+uint16_t nNumRbsPerSymF1[3][13] =
+{
+ // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+ {25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0}, // Numerology 0 (15KHz)
+ {11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273}, // Numerology 1 (30KHz)
+ {0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135} // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+uint16_t nNumRbsPerSymF2[2][4] =
+{
+ // 50Mhz 100MHz 200MHz 400MHz
+ {66, 132, 264, 0}, // Numerology 2 (60KHz)
+ {32, 66, 132, 264} // Numerology 3 (120KHz)
+};
+
+// 38.211 - Table 4.2.1
+uint16_t nSubCarrierSpacing[5] =
+{
+ 15, // mu = 0
+ 30, // mu = 1
+ 60, // mu = 2
+ 120, // mu = 3
+ 240 // mu = 4
+};
+
+// TTI interval in us (slot duration)
+uint16_t nTtiInterval[4] =
+{
+ 1000, // mu = 0
+ 500, // mu = 1
+ 250, // mu = 2
+ 125, // mu = 3
+};
+
+
+// F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
+uint16_t nCpSizeF1[3][13][2] =
+{
+ // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+ {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, // Numerology 0 (15KHz)
+ {{22, 18}, {44, 36}, {66, 54}, {88, 72}, {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}}, // Numerology 1 (30KHz)
+ { {0, 0}, {26, 18}, {39, 27}, {52, 36}, {52, 36}, {78, 54}, {104, 72}, {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}}, // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
+int16_t nCpSizeF2[2][4][2] =
+{
+ // 50Mhz 100MHz 200MHz 400MHz
+ { {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
+ {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
+};
+
+uint32_t gMaxSlotNum;
+uint32_t gNumDLCtx;
+uint32_t gNumULCtx;
+uint32_t gDLResetAdvance;
+uint32_t gDLProcAdvance;
+uint32_t gULProcAdvance;
+
+static uint16_t g_NumSlotTDDLoop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
+static uint16_t g_NumDLSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint16_t g_NumULSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint8_t g_SlotType[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
+float g_UlRate[XRAN_MAX_SECTOR_NR] = {0.0};
+float g_DlRate[XRAN_MAX_SECTOR_NR] = {0.0};
+
+uint32_t app_xran_get_tti_interval(uint8_t nMu)
+{
+ if (nMu < 4)
+ {
+ return nTtiInterval[nMu];
+ }
+ else
+ {
+ printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+ }
+
+ return 0;
+}
+
+uint32_t app_xran_get_scs(uint8_t nMu)
+{
+ if (nMu <= 3)
+ {
+ return nSubCarrierSpacing[nMu];
+ }
+ else
+ {
+ printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+ }
+
+ return 0;
+}
+
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ * @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
+ * @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ * @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ * @return Number of RBs in cell
+ *
+ * @description
+ * Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t app_xran_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
+{
+ uint32_t error = 1;
+ uint16_t numRBs = 0;
+
+ if (nAbsFrePointA <= 6000000)
+ {
+ // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+ if (nNumerology < 3)
+ {
+ switch(nBandwidth)
+ {
+ case PHY_BW_5_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][0];
+ error = 0;
+ break;
+ case PHY_BW_10_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][1];
+ error = 0;
+ break;
+ case PHY_BW_15_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][2];
+ error = 0;
+ break;
+ case PHY_BW_20_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][3];
+ error = 0;
+ break;
+ case PHY_BW_25_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][4];
+ error = 0;
+ break;
+ case PHY_BW_30_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][5];
+ error = 0;
+ break;
+ case PHY_BW_40_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][6];
+ error = 0;
+ break;
+ case PHY_BW_50_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][7];
+ error = 0;
+ break;
+ case PHY_BW_60_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][8];
+ error = 0;
+ break;
+ case PHY_BW_70_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][9];
+ error = 0;
+ break;
+ case PHY_BW_80_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][10];
+ error = 0;
+ break;
+ case PHY_BW_90_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][11];
+ error = 0;
+ break;
+ case PHY_BW_100_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][12];
+ error = 0;
+ break;
+ default:
+ error = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if ((nNumerology >= 2) && (nNumerology <= 3))
+ {
+ // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+ switch(nBandwidth)
+ {
+ case PHY_BW_50_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][0];
+ error = 0;
+ break;
+ case PHY_BW_100_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][1];
+ error = 0;
+ break;
+ case PHY_BW_200_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][2];
+ error = 0;
+ break;
+ case PHY_BW_400_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][3];
+ error = 0;
+ break;
+ default:
+ error = 1;
+ break;
+ }
+ }
+ }
+
+
+ if (error)
+ {
+ printf("ERROR: %s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA);
+ }
+ else
+ {
+ printf("%s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA, numRBs);
+ }
+
+ return numRBs;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ * @param[in] center frequency
+ *
+ * @return NR-ARFCN
+ *
+ * @description
+ * This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq)
+{
+ uint32_t nDeltaFglobal,nFoffs,nNoffs;
+ uint32_t nNRARFCN = 0;
+
+ if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
+ {
+ nDeltaFglobal = 5;
+ nFoffs = 0;
+ nNoffs = 0;
+ }
+ else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
+ {
+ nDeltaFglobal = 15;
+ nFoffs = 3000*1000;
+ nNoffs = 600000;
+ }
+ else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
+ {
+ nDeltaFglobal = 60;
+ nFoffs = 24250080;
+ nNoffs = 2016667;
+ }
+ else
+ {
+ printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
+ return (0);
+ }
+
+ nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
+
+ printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
+ return (nNRARFCN);
+}
+
+int32_t app_xran_slot_limit(int32_t nSfIdx)
+{
+ while (nSfIdx < 0) {
+ nSfIdx += gMaxSlotNum;
+ }
+
+ while (nSfIdx >= gMaxSlotNum) {
+ nSfIdx -= gMaxSlotNum;
+ }
+
+ return nSfIdx;
+}
+
+void app_xran_clear_slot_type(uint32_t nPhyInstanceId)
+{
+ g_UlRate[nPhyInstanceId] = 0.0;
+ g_DlRate[nPhyInstanceId] = 0.0;
+ g_NumSlotTDDLoop[nPhyInstanceId] = 1;
+}
+
+int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig)
+{
+ uint32_t nSlotNum, nSymNum, nVal, i;
+ uint32_t numDlSym, numUlSym, numGuardSym;
+ uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
+ char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
+
+ // nPhyInstanceId Carrier ID
+ // nFrameDuplexType 0 = FDD 1 = TDD
+ // nTddPeriod Tdd Periodicity
+ // psSlotConfig[80] Slot Config Structure for nTddPeriod Slots
+
+ g_UlRate[nPhyInstanceId] = 0.0;
+ g_DlRate[nPhyInstanceId] = 0.0;
+ g_NumSlotTDDLoop[nPhyInstanceId] = nTddPeriod;
+
+ for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+ {
+ g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
+ g_NumDLSymSp[nPhyInstanceId][i] = 0;
+ g_NumULSymSp[nPhyInstanceId][i] = 0;
+ }
+
+ if (nFrameDuplexType == XRAN_FDD)
+ {
+ for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+ {
+ g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
+ }
+ g_NumSlotTDDLoop[nPhyInstanceId] = 1;
+ g_DlRate[nPhyInstanceId] = 1.0;
+ g_UlRate[nPhyInstanceId] = 1.0;
+ }
+ else
+ {
+ for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
+ {
+ numDlSym = 0;
+ numUlSym = 0;
+ numGuardSym = 0;
+ for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
+ {
+ switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
+ {
+ case XRAN_SYMBOL_TYPE_DL:
+ numDlSym++;
+ break;
+ case XRAN_SYMBOL_TYPE_GUARD:
+ numGuardSym++;
+ break;
+ default:
+ numUlSym++;
+ break;
+ }
+ }
+
+ // printf("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d]\n", nSlotNum, numDlSym, numGuardSym, numUlSym);
+
+ if ((numUlSym == 0) && (numGuardSym == 0))
+ {
+ g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
+ numDlSlots++;
+ }
+ else if ((numDlSym == 0) && (numGuardSym == 0))
+ {
+ g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
+ numUlSlots++;
+ }
+ else
+ {
+ g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
+ numSpSlots++;
+
+ if (numDlSym)
+ {
+ numSpDlSlots++;
+ g_NumDLSymSp[nPhyInstanceId][nSlotNum] = numDlSym;
+ }
+ if (numUlSym)
+ {
+ numSpUlSlots++;
+ g_NumULSymSp[nPhyInstanceId][nSlotNum] = numUlSym;
+ }
+ }
+
+ // printf(" numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
+ }
+
+ g_DlRate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
+ g_UlRate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
+ }
+
+ printf("set_slot_type: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
+ nPhyInstanceId, nFrameDuplexType, nTddPeriod);
+
+ printf("DLRate[%f] ULRate[%f]\n", g_DlRate[nPhyInstanceId], g_UlRate[nPhyInstanceId]);
+
+ nVal = (g_NumSlotTDDLoop[nPhyInstanceId] < 10) ? g_NumSlotTDDLoop[nPhyInstanceId] : 10;
+
+ printf("SlotPattern:\n");
+ printf("Slot: ");
+ for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
+ {
+ printf("%d ", nSlotNum);
+ }
+ printf("\n");
+
+ printf(" %3d ", 0);
+ for (nSlotNum = 0, i = 0; nSlotNum < g_NumSlotTDDLoop[nPhyInstanceId]; nSlotNum++)
+ {
+ printf("%s ", sSlotPattern[g_SlotType[nPhyInstanceId][nSlotNum]]);
+ i++;
+ if ((i == 10) && ((nSlotNum+1) < g_NumSlotTDDLoop[nPhyInstanceId]))
+ {
+ printf("\n");
+ printf(" %3d ", nSlotNum);
+ i = 0;
+ }
+ }
+ printf("\n\n");
+
+ return 0;
+}
+
+int32_t app_xran_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
+{
+ int32_t nSfIdxMod, nSfType, ret = 0;
+
+ nSfIdxMod = app_xran_slot_limit(nSlotdx) % ((g_NumSlotTDDLoop[nCellIdx] > 0) ? g_NumSlotTDDLoop[nCellIdx]: 1);
+ nSfType = g_SlotType[nCellIdx][nSfIdxMod];
+
+ if (nSfType == nType)
+ {
+ ret = 1;
+ }
+ else if (nSfType == XRAN_SLOT_TYPE_SP)
+ {
+ if ((nType == XRAN_SLOT_TYPE_DL) && g_NumDLSymSp[nCellIdx][nSfIdxMod])
+ {
+ ret = 1;
+ }
+
+ if ((nType == XRAN_SLOT_TYPE_UL) && g_NumULSymSp[nCellIdx][nSfIdxMod])
+ {
+ ret = 1;
+ }
+ }
+ else if (nSfType == XRAN_SLOT_TYPE_FDD)
+ {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+
+
+void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+ if (size)
+ {
+ if (filename && bufname)
+ {
+ FILE *file;
+ printf("Storing %s to file %s: ", bufname, filename);
+ file = fopen(filename, "wb");
+ if (file == NULL)
+ {
+ printf("can't open file %s!!!", filename);
+ }
+ else
+ {
+ uint32_t num;
+ num = fwrite(pBuffer, buffers_num, size, file);
+ fflush(file);
+ fclose(file);
+ printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
+ }
+ printf(" \n");
+ }
+ else
+ {
+ printf(" the file name, buffer name are not set!!!");
+ }
+ }
+ else
+ {
+ printf(" the %s is free: size = %d bytes!!!", bufname, size);
+ }
+}
+
+int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+ unsigned int file_size = 0;
+ int num= 0;
+
+ if (size)
+ {
+ if (filename && bufname)
+ {
+ FILE *file;
+ printf("Loading file %s to %s: ", filename, bufname);
+ file = fopen(filename, "rb");
+
+
+ if (file == NULL)
+ {
+ printf("can't open file %s!!!", filename);
+ exit(-1);
+ }
+ else
+ {
+ fseek(file, 0, SEEK_END);
+ file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ if ((file_size > size) || (file_size == 0))
+ file_size = size;
+
+ printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
+
+ num = fread(pBuffer, buffers_num, size, file);
+ fflush(file);
+ fclose(file);
+ printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
+ }
+ printf(" \n");
+
+ }
+ else
+ {
+ printf(" the file name, buffer name are not set!!!");
+ }
+ }
+ else
+ {
+ printf(" the %s is free: size = %d bytes!!!", bufname, size);
+ }
+ return num;
+}
+
+
+void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
+{
+ unsigned int i;
+ int ret = 0;
+ if (pBuffer == NULL)
+ return;
+
+ if (size)
+ {
+ if (filename && bufname)
+ {
+ FILE *file;
+ printf("Storing %s to file %s: ", bufname, filename);
+ file = fopen(filename, "w");
+ if (file == NULL)
+ {
+ printf("can't open file %s!!!", filename);
+ exit(-1);
+ }
+ else
+ {
+ uint32_t num = 0;
+
+ signed short *ptr = (signed short*)pBuffer;
+ for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
+ {
+#ifndef CSCOPE_DEBUG
+ ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
+#else
+ ret = fprintf(file,"%d %d ", ptr[i], ptr[i + 1]);
+ /* I data => Ramp data, from 1 to 792.
+ Q data => Contains time information of the current symbol:
+ Bits [15:14] = Antenna-ID
+ Bits [13:12] = \9300\94
+ Bits [11:8] = Subframe-ID
+ Bits [7:4] = Slot-ID
+ Bits [3:0] = Symbol-ID */
+ fprintf(file, "0x%04x: ant %d Subframe-ID %d Slot-ID %d Symbol-ID %d\n",
+ ptr[i + 1], (ptr[i + 1]>>14) & 0x3, (ptr[i + 1]>>8) & 0xF, (ptr[i + 1]>>4) & 0xF, (ptr[i + 1]>>0) & 0xF);
+#endif
+ if (ret < 0)
+ {
+ printf("fprintf %d\n", ret);
+ fclose(file);
+ break;
+ }
+ num++;
+ }
+ fflush(file);
+ fclose(file);
+ printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
+ }
+ printf(" \n");
+ }
+ else
+ {
+ printf(" the file name, buffer name are not set!!!");
+ }
+ }
+ else
+ {
+ printf(" the %s is free: size = %d bytes!!!", bufname, size);
+ }
+}
+
*
*******************************************************************************/
+
+#ifndef _XRAN_APP_COMMON_H_
+#define _XRAN_APP_COMMON_H_
+
#include <stdio.h>
#include <unistd.h>
+#include "xran_fh_o_du.h"
#include "xran_pkt_up.h"
#include <rte_common.h>
#include <rte_mbuf.h>
-#define APP_LLS_CU 0
-#define APP_RU 1
+#define VERSIONX "#DIRTY#"
+
+#define APP_O_DU 0
+#define APP_O_RU 1
enum app_state
{
APP_STOPPED
};
-#define NUM_OF_PRB_IN_FULL_BAND (66)
+enum nRChBwOptions
+{
+ PHY_BW_5_0_MHZ = 5, PHY_BW_10_0_MHZ = 10, PHY_BW_15_0_MHZ = 15, PHY_BW_20_0_MHZ = 20, PHY_BW_25_0_MHZ = 25,
+ PHY_BW_30_0_MHZ = 30, PHY_BW_40_0_MHZ = 40, PHY_BW_50_0_MHZ = 50, PHY_BW_60_0_MHZ = 60, PHY_BW_70_0_MHZ = 70,
+ PHY_BW_80_0_MHZ = 80, PHY_BW_90_0_MHZ = 90, PHY_BW_100_0_MHZ = 100, PHY_BW_200_0_MHZ = 200, PHY_BW_400_0_MHZ = 400
+};
+
#define N_SC_PER_PRB 12
#define N_SYM_PER_SLOT 14
-#define N_FULLBAND_SC (NUM_OF_PRB_IN_FULL_BAND*N_SC_PER_PRB)
-#define MAX_ANT_CARRIER_SUPPORTED 16
-// 0.125, just for testing
-#define SLOTNUM_PER_SUBFRAME 8
+#define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR)
+
+#define SUBFRAME_DURATION_US 1000
+//#define SLOTNUM_PER_SUBFRAME 8
+
#define SUBFRAMES_PER_SYSTEMFRAME 10
-#define PDSCH_PAYLOAD_SIZE (N_FULLBAND_SC*4)
-#define NUM_OF_SLOT_IN_TDD_LOOP (80)
-#define IQ_PLAYBACK_BUFFER_BYTES (NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*N_FULLBAND_SC*4L)
-/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples. The payload length is 3356 octets.*/
-#define PRACH_PLAYBACK_BUFFER_BYTES (10*839*4L)
+#define IQ_PLAYBACK_BUFFER_BYTES (XRAN_NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*66*N_SC_PER_PRB*4L)
+/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples for long sequence or 144*14 (max) for short sequence. The payload length is 3356 octets.*/
+#define PRACH_PLAYBACK_BUFFER_BYTES (144*14*4L)
#ifdef _DEBUG
#define iAssert(p) if(!(p)){fprintf(stderr,\
#define iAssert(p)
#endif /* _DEBUG */
-struct send_symbol_cb_args
-{
- struct rb_map *samp_buf;
- uint8_t *symb_id;
-};
-
-struct pkt_dump
-{
- int num_samp;
- int num_bytes;
- uint8_t symb;
- struct ecpri_seq_id seq;
-} __rte_packed;
+extern int iq_playback_buffer_size_dl;
+extern int iq_playback_buffer_size_ul;
extern uint8_t numCCPorts;
/* Number of antennas supported by front-end */
extern int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
extern int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+extern int16_t *p_tx_prach_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
+extern int32_t tx_prach_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
+extern int32_t tx_prach_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
+
/* Number of antennas supported by front-end */
extern int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
extern int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
+uint32_t app_xran_get_scs(uint8_t nMu);
+uint16_t app_xran_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
+uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq);
+int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType,
+ uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig);
+uint32_t app_xran_get_tti_interval(uint8_t nMu);
+
+
+#endif /*_XRAN_APP_COMMON_H_*/
#include "rte_common.h"
#include "config.h"
+#include "common.h"
+#include "debug.h"
#include <rte_ethdev.h>
#define MAX_LINE_SIZE 512
/* Configuration file maximum supported line length */
-
#define KEY_APP_MODE "appMode"
#define KEY_XRAN_MODE "xranMode"
#define KEY_MU_NUMBER "mu"
+#define KEY_NDLABSFREPOINTA "nDLAbsFrePointA"
+#define KEY_NULABSFREPOINTA "nULAbsFrePointA"
+#define KEY_NDLBANDWIDTH "nDLBandwidth"
+#define KEY_NULBANDWIDTH "nULBandwidth"
+#define KEY_NDLFFTSIZE "nDLFftSize"
+#define KEY_NULFFTSIZE "nULFftSize"
+
+#define KEY_NFRAMEDUPLEXTYPE "nFrameDuplexType"
+#define KEY_NTDDPERIOD "nTddPeriod"
+
+#define KEY_SSLOTCONFIG "sSlotConfig"
+
#define KEY_CC_PER_PORT_NUM "ccNum"
#define KEY_ANT_NUM "antNum"
#define KEY_TTI_PERIOD "ttiPeriod"
+
+#define KEY_MTU_SIZE "MTUSize"
#define KEY_LLS_CU_MAC "llsCUMac"
#define KEY_RU_MAC "ruMac"
-#define KEY_FILE_AxC0 "antC0"
-#define KEY_FILE_AxC1 "antC1"
-#define KEY_FILE_AxC2 "antC2"
-#define KEY_FILE_AxC3 "antC3"
-#define KEY_FILE_AxC4 "antC4"
-#define KEY_FILE_AxC5 "antC5"
-#define KEY_FILE_AxC6 "antC6"
-#define KEY_FILE_AxC7 "antC7"
-#define KEY_FILE_AxC8 "antC8"
-#define KEY_FILE_AxC9 "antC9"
-#define KEY_FILE_AxC10 "antC10"
-#define KEY_FILE_AxC11 "antC11"
-#define KEY_FILE_AxC12 "antC12"
-#define KEY_FILE_AxC13 "antC13"
-#define KEY_FILE_AxC14 "antC14"
-#define KEY_FILE_AxC15 "antC15"
+#define KEY_FILE_NUMSLOTS "numSlots"
+#define KEY_FILE_AxC "antC"
+#define KEY_FILE_PRACH_AxC "antPrachC"
+
#define KEY_PRACH_ENABLE "rachEanble"
-#define KEY_PRACH_OFFSET "rachOffset"
-#define KEY_PRACH_CFG_IDX "rachCfgIdx"
+#define KEY_PRACH_CFGIDX "prachConfigIndex"
#define KEY_IQ_SWAP "iqswap"
#define KEY_HTONS_SWAP "nebyteorderswap"
#define KEY_CP_VTAG "c_plane_vlan_tag"
#define KEY_UP_VTAG "u_plane_vlan_tag"
#define KEY_DEBUG_STOP "debugStop"
+#define KEY_DEBUG_STOP_CNT "debugStopCount"
+#define KEY_BBDEV_MODE "bbdevMode"
+#define KEY_DYNA_SEC_ENA "DynamicSectionEna"
/**
config->numCC= atoi(value);
} else if (strcmp(key, KEY_MU_NUMBER) == 0) {
config->mu_number= atoi(value);
+ printf("mu_number: %d\n",config->mu_number);
+ } else if (strcmp(key, KEY_NDLABSFREPOINTA) == 0) {
+ config->nDLAbsFrePointA = atoi(value);
+ printf("nDLAbsFrePointA: %d\n",config->nDLAbsFrePointA);
+ } else if (strcmp(key, KEY_NULABSFREPOINTA) == 0) {
+ config->nULAbsFrePointA = atoi(value);
+ printf("nULAbsFrePointA: %d\n",config->nULAbsFrePointA);
+ } else if (strcmp(key, KEY_NDLBANDWIDTH) == 0) {
+ config->nDLBandwidth = atoi(value);
+ printf("nDLBandwidth: %d\n",config->nDLBandwidth);
+ } else if (strcmp(key, KEY_NULBANDWIDTH) == 0) {
+ config->nULBandwidth = atoi(value);
+ printf("nULBandwidth: %d\n",config->nULBandwidth);
+ } else if (strcmp(key, KEY_NDLFFTSIZE) == 0) {
+ config->nDLFftSize = atoi(value);
+ printf("nULFftSize: %d\n",config->nDLFftSize);
+ } else if (strcmp(key, KEY_NULFFTSIZE) == 0) {
+ config->nULFftSize = atoi(value);
+ printf("nULFftSize: %d\n",config->nULFftSize);
+ } else if (strcmp(key, KEY_NFRAMEDUPLEXTYPE) == 0) {
+ config->nFrameDuplexType = atoi(value);
+ printf("nFrameDuplexType: %d\n",config->nFrameDuplexType);
+ } else if (strcmp(key, KEY_NTDDPERIOD) == 0) {
+ config->nTddPeriod = atoi(value);
+ printf("nTddPeriod: %d\n",config->nTddPeriod);
+ if (config->nTddPeriod > XRAN_MAX_TDD_PERIODICITY)
+ {
+ printf("nTddPeriod is larger than max allowed, invalid!\n");
+ config->nTddPeriod = XRAN_MAX_TDD_PERIODICITY;
+ }
+ } else if (strncmp(key, KEY_SSLOTCONFIG, strlen(KEY_SSLOTCONFIG)) == 0) {
+ unsigned int slot_num = 0;
+ int i = 0;
+ sscanf(key,"sSlotConfig%u",&slot_num);
+ if (slot_num >= config->nTddPeriod){
+ printf("slot_num %d exceeds TddPeriod\n",slot_num);
+ }
+ else{
+ sscanf(value, "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[0],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[1],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[2],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[3],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[4],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[5],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[6],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[7],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[8],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[9],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[10],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[11],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[12],
+ (uint32_t*)&config->sSlotConfig[slot_num].nSymbolType[13]);
+ printf("sSlotConfig%d: ",slot_num);
+ for (i = 0; i< 14; i++){
+ printf("%d ",config->sSlotConfig[slot_num].nSymbolType[i]);
+ }
+ printf("\n");
+ }
} else if (strcmp(key, KEY_ANT_NUM) == 0) {
config->numAxc = atoi(value);
} else if (strcmp(key, KEY_TTI_PERIOD) == 0) {
config->iqswap = atoi(value);
} else if (strcmp(key, KEY_HTONS_SWAP) == 0) {
config->nebyteorderswap = atoi(value);
+ } else if (strcmp(key, KEY_MTU_SIZE) == 0) {
+ config->mtu = atoi(value);
+ printf("mtu %d\n", config->mtu);
} else if (strcmp(key, KEY_LLS_CU_MAC) == 0) {
- sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->lls_cu_addr.addr_bytes[0],
- (uint32_t*)&config->lls_cu_addr.addr_bytes[1],
- (uint32_t*)&config->lls_cu_addr.addr_bytes[2],
- (uint32_t*)&config->lls_cu_addr.addr_bytes[3],
- (uint32_t*)&config->lls_cu_addr.addr_bytes[4],
- (uint32_t*)&config->lls_cu_addr.addr_bytes[5]);
+ sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->o_du_addr.addr_bytes[0],
+ (uint32_t*)&config->o_du_addr.addr_bytes[1],
+ (uint32_t*)&config->o_du_addr.addr_bytes[2],
+ (uint32_t*)&config->o_du_addr.addr_bytes[3],
+ (uint32_t*)&config->o_du_addr.addr_bytes[4],
+ (uint32_t*)&config->o_du_addr.addr_bytes[5]);
printf("lls-CU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
- config->lls_cu_addr.addr_bytes[0],
- config->lls_cu_addr.addr_bytes[1],
- config->lls_cu_addr.addr_bytes[2],
- config->lls_cu_addr.addr_bytes[3],
- config->lls_cu_addr.addr_bytes[4],
- config->lls_cu_addr.addr_bytes[5]);
+ config->o_du_addr.addr_bytes[0],
+ config->o_du_addr.addr_bytes[1],
+ config->o_du_addr.addr_bytes[2],
+ config->o_du_addr.addr_bytes[3],
+ config->o_du_addr.addr_bytes[4],
+ config->o_du_addr.addr_bytes[5]);
} else if (strcmp(key, KEY_RU_MAC) == 0) {
- sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->ru_addr.addr_bytes[0],
- (uint32_t*)&config->ru_addr.addr_bytes[1],
- (uint32_t*)&config->ru_addr.addr_bytes[2],
- (uint32_t*)&config->ru_addr.addr_bytes[3],
- (uint32_t*)&config->ru_addr.addr_bytes[4],
- (uint32_t*)&config->ru_addr.addr_bytes[5]);
+ sscanf(value, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t*)&config->o_ru_addr.addr_bytes[0],
+ (uint32_t*)&config->o_ru_addr.addr_bytes[1],
+ (uint32_t*)&config->o_ru_addr.addr_bytes[2],
+ (uint32_t*)&config->o_ru_addr.addr_bytes[3],
+ (uint32_t*)&config->o_ru_addr.addr_bytes[4],
+ (uint32_t*)&config->o_ru_addr.addr_bytes[5]);
printf("RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
- config->ru_addr.addr_bytes[0],
- config->ru_addr.addr_bytes[1],
- config->ru_addr.addr_bytes[2],
- config->ru_addr.addr_bytes[3],
- config->ru_addr.addr_bytes[4],
- config->ru_addr.addr_bytes[5]);
- } else if (strcmp(key, KEY_FILE_AxC0) == 0) {
- strncpy(&config->ant_file[0][0], value, strlen(value));
- printf("ant0: %s\n",config->ant_file[0]);
- } else if (strcmp(key, KEY_FILE_AxC1) == 0) {
- strncpy(&config->ant_file[1][0], value, strlen(value));
- printf("ant1: %s\n",config->ant_file[1]);
- } else if (strcmp(key, KEY_FILE_AxC2) == 0) {
- strncpy(&config->ant_file[2][0], value, strlen(value));
- printf("ant2: %s\n",config->ant_file[2]);
- } else if (strcmp(key, KEY_FILE_AxC3) == 0) {
- strncpy(&config->ant_file[3][0], value, strlen(value));
- printf("ant3: %s\n",config->ant_file[3]);
- } else if (strcmp(key, KEY_FILE_AxC4) == 0) {
- strncpy(&config->ant_file[4][0], value, strlen(value));
- printf("ant4: %s\n",config->ant_file[4]);
- } else if (strcmp(key, KEY_FILE_AxC5) == 0) {
- strncpy(&config->ant_file[5][0], value, strlen(value));
- printf("ant5: %s\n",config->ant_file[5]);
- } else if (strcmp(key, KEY_FILE_AxC6) == 0) {
- strncpy(&config->ant_file[6][0], value, strlen(value));
- printf("ant6: %s\n",config->ant_file[6]);
- } else if (strcmp(key, KEY_FILE_AxC7) == 0) {
- strncpy(&config->ant_file[7][0], value, strlen(value));
- printf("ant7: %s\n",config->ant_file[7]);
- } else if (strcmp(key, KEY_FILE_AxC8) == 0) {
- strncpy(&config->ant_file[8][0], value, strlen(value));
- printf("ant8: %s\n",config->ant_file[8]);
- } else if (strcmp(key, KEY_FILE_AxC9) == 0) {
- strncpy(&config->ant_file[9][0], value, strlen(value));
- printf("ant9: %s\n",config->ant_file[9]);
- } else if (strcmp(key, KEY_FILE_AxC10) == 0) {
- strncpy(&config->ant_file[10][0], value, strlen(value));
- printf("ant10: %s\n",config->ant_file[10]);
- } else if (strcmp(key, KEY_FILE_AxC11) == 0) {
- strncpy(&config->ant_file[11][0], value, strlen(value));
- printf("ant11: %s\n",config->ant_file[11]);
- } else if (strcmp(key, KEY_FILE_AxC12) == 0) {
- strncpy(&config->ant_file[12][0], value, strlen(value));
- printf("ant12: %s\n",config->ant_file[12]);
- } else if (strcmp(key, KEY_FILE_AxC13) == 0) {
- strncpy(&config->ant_file[13][0], value, strlen(value));
- printf("ant13: %s\n",config->ant_file[13]);
- } else if (strcmp(key, KEY_FILE_AxC14) == 0) {
- strncpy(&config->ant_file[14][0], value, strlen(value));
- printf("ant14: %s\n",config->ant_file[14]);
- } else if (strcmp(key, KEY_FILE_AxC15) == 0) {
- strncpy(&config->ant_file[15][0], value, strlen(value));
- printf("ant15: %s\n",config->ant_file[15]);
+ config->o_ru_addr.addr_bytes[0],
+ config->o_ru_addr.addr_bytes[1],
+ config->o_ru_addr.addr_bytes[2],
+ config->o_ru_addr.addr_bytes[3],
+ config->o_ru_addr.addr_bytes[4],
+ config->o_ru_addr.addr_bytes[5]);
+ } else if (strcmp(key, KEY_FILE_NUMSLOTS) == 0) {
+ config->numSlots = atoi(value);
+ printf("numSlots: %d\n",config->numSlots);
+ }else if (strncmp(key, KEY_FILE_AxC, strlen(KEY_FILE_AxC)) == 0) {
+ unsigned int ant_num = 0;
+ sscanf(key,"antC%02u",&ant_num);
+ if (ant_num >= MAX_ANT_CARRIER_SUPPORTED)
+ {
+ printf("antC%d exceeds max antenna supported\n",ant_num);
+ }
+ else{
+ strncpy(&config->ant_file[ant_num][0], value, strlen(value));
+ printf("antC%d: %s\n",ant_num, config->ant_file[ant_num]);
+ }
} else if (strcmp(key, KEY_PRACH_ENABLE) == 0) {
config->enablePrach = atoi(value);
printf("Prach enable: %d\n",config->enablePrach);
- } else if (strcmp(key, KEY_PRACH_OFFSET ) == 0) {
- config->prachOffset = atoi(value);
- printf("Prach Offset: %d\n",config->prachOffset);
- } else if (strcmp(key, KEY_PRACH_CFG_IDX ) == 0) {
+ } else if (strcmp(key, KEY_PRACH_CFGIDX) == 0) {
config->prachConfigIndex = atoi(value);
- printf("Prach Conf Index: %d\n",config->prachConfigIndex);
-
+ printf("Prach config index: %d\n",config->prachConfigIndex);
+ } else if (strncmp(key, KEY_FILE_PRACH_AxC, strlen(KEY_FILE_PRACH_AxC)) == 0) {
+ unsigned int ant_num = 0;
+ sscanf(key,"antPrachC%02u",&ant_num);
+ if (ant_num >= MAX_ANT_CARRIER_SUPPORTED)
+ {
+ printf("antC%d exceeds max antenna supported\n",ant_num);
+ }
+ else{
+ strncpy(&config->prach_file[ant_num][0], value, strlen(value));
+ printf("antPrachC%d: %s\n",ant_num, config->prach_file[ant_num]);
+ }
/* timing */
} else if (strcmp(key, KEY_TADV_CP_DL ) == 0) {
config->Tadv_cp_dl = atoi(value);
} else if (strcmp(key, KEY_DEBUG_STOP ) == 0) {
config->debugStop = atoi(value);
printf("debugStop: %d\n",config->debugStop);
+ } else if (strcmp(key, KEY_DEBUG_STOP_CNT) == 0) {
+ config->debugStopCount = atoi(value);
+ printf("debugStopCount: %d\n",config->debugStopCount);
+ } else if (strcmp(key, KEY_BBDEV_MODE) == 0) {
+ config->bbdevMode = atoi(value);
+ printf("bbdevMode: %d\n",config->debugStopCount);
+ } else if (strcmp(key, KEY_DYNA_SEC_ENA) == 0) {
+ config->DynamicSectionEna = atoi(value);
+ printf("DynamicSectionEna: %d\n",config->DynamicSectionEna);
} else if (strcmp(key, KEY_CP_VTAG ) == 0) {
config->cp_vlan_tag = atoi(value);
printf("cp_vlan_tag: %d\n",config->cp_vlan_tag);
FILE *file = fopen(filename, "r");
if (NULL == file) {
- //log_err("Error while opening config file from: %s", filename);
+ log_err("Error while opening config file from: %s", filename);
return -1;
}
- init_config(config);
+// init_config(config);
for (;;) {
if (fgets(inputLine, MAX_LINE_SIZE, file) == NULL) {
key[i] = '\0';
trim(key);
if ((i + 1 > inputLen - 1) || (i - 2 > inputLen)) {
- //log_err("Parsing config file error at line %d", lineNum);
+ log_err("Parsing config file error at line %d", lineNum);
fclose(file);
return -1;
}
#include <stdint.h>
#include <rte_ether.h>
+#include "xran_fh_o_du.h"
/** Run time configuration of application */
typedef struct _RuntimeConfig
uint8_t appMode; /**< Application mode: lls-CU or RU */
uint8_t xranMode; /**< xran mode: Categoty A | Category B */
uint8_t numCC; /**< Number of CC per ports supported by RU */
- uint8_t mu_number; /**< Mu numner as per 3GPP */
uint8_t numAxc; /**< Number of Antenna Carriers per CC */
uint32_t ttiPeriod; /**< TTI period */
uint32_t testVect; /**< Test Signal to send */
- struct ether_addr lls_cu_addr; /**< lls-CU Ethernet Mac Address */
- struct ether_addr ru_addr; /**< RU Ethernet Mac Address */
- char ant_file[16][512] /**< file to use for test vector */ ;
+ struct ether_addr o_du_addr; /**< lls-CU Ethernet Mac Address */
+ struct ether_addr o_ru_addr; /**< RU Ethernet Mac Address */
+ struct ether_addr tmp_addr; /**< Temp Ethernet Mac Address */
+
+ uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
+ int numSlots; /**< number of slots in IQ vector */
+ char ant_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512] /**< file to use for test vector */ ;
+ char prach_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512] /**< file to use for test vector */ ;
/* prach config */
uint8_t enablePrach; /**< enable PRACH */
uint8_t up_vlan_tag; /**< U-plane vlan tag */
int32_t debugStop;
+ int32_t debugStopCount;
+ int32_t bbdevMode;
+ int32_t DynamicSectionEna;
+
+ uint8_t mu_number; /**< Mu numner as per 3GPP */
+ uint32_t nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+ uint32_t nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+ uint32_t nDLBandwidth; /**< Carrier bandwidth for in MHz. Value: 5->400 */
+ uint32_t nULBandwidth; /**< Carrier bandwidth for in MHz. Value: 5->400 */
+ uint32_t nDLFftSize; /**< DL FFT size */
+ uint32_t nULFftSize; /**< UL FFT size */
+ uint8_t nFrameDuplexType;
+ uint8_t nTddPeriod;
+ struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
} RuntimeConfig;
/**
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+/**
+ * @brief
+ * @file
+ * @ingroup
+ * @author Intel Corporation
+ **/
+
+#ifndef _SAMPLEAPP__DEBUG_H_
+#define _SAMPLEAPP__DEBUG_H_
+
+#include <stdio.h>
+
+#include "config.h"
+
+#define MAX_FILE_NAME_LEN (512)
+#define MAX_PATH_NAME_LEN (1024)
+
+#ifdef _DEBUG
+ #define log_dbg(fmt, ...) \
+ fprintf(stderr, \
+ "DEBUG: %s(%d): " fmt "\n", \
+ __FILE__, \
+ __LINE__, ##__VA_ARGS__)
+#else
+ #define log_dbg(fmt, ...)
+#endif
+
+#if defined(_DEBUG) || defined(_VERBOSE)
+ #define log_wrn(fmt, ...) \
+ fprintf( \
+ stderr, \
+ "WARNING: %s(%d): " fmt "\n", \
+ __FILE__, \
+ __LINE__, ##__VA_ARGS__)
+#else
+ #define log_dbg(fmt, ...)
+ #define log_wrn(fmt, ...)
+#endif
+
+
+#define log_err(fmt, ...) \
+ fprintf(stderr, \
+ "ERROR: %s(%d): " fmt "\n", \
+ __FILE__, \
+ __LINE__, ##__VA_ARGS__)
+
+
+inline void ShowData(void* ptr, unsigned int size)
+{
+ uint8_t *d = (uint8_t *)ptr;
+ unsigned int i;
+
+ for(i = 0; i < size; i++)
+ {
+ if ( !(i & 0xf) )
+ printf("\n");
+ printf("%02x ", d[i]);
+ }
+ printf("\n");
+}
+
+
+#endif /* _SAMPLEAPP__DEBUG_H_ */
*
*******************************************************************************/
+
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
+#include <fcntl.h>
#include <pthread.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
#include "common.h"
#include "config.h"
+#include "xran_mlog_lnx.h"
-#ifndef MLOG_ENABLED
-#include "../../lib/src/mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
-
-
-#include "xran_fh_lls_cu.h"
-//#include "xran_pkt.h"
-//#include "xran_up_api.h"
+#include "xran_fh_o_du.h"
#include "xran_cp_api.h"
#include "xran_sync_api.h"
#include "xran_mlog_task_id.h"
+#define MAX_BBU_POOL_CORE_MASK (4)
+
+
#define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024
#define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024
#define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024
RuntimeConfig startupConfiguration = {0};
-//FH FPGA buffer
+/* buffers size */
uint32_t nFpgaToSW_FTH_RxBufferLen;
uint32_t nFpgaToSW_PRACH_RxBufferLen;
uint32_t nSW_ToFpga_FTH_TxBufferLen;
-static XRANFHINIT xranInit;
+static struct xran_fh_init xranInit;
void * xranHandle = NULL;
-XRANFHCONFIG xranConf;
-PXRANFHCONFIG pXranConf = NULL;
+struct xran_fh_config xranConf;
+struct xran_fh_config *pXranConf = NULL;
typedef struct
{
}XranLibConfigStruct;
typedef enum {
XRANFTHTX_OUT = 0,
+ XRANFTHTX_PRB_MAP_OUT,
XRANFTHRX_IN,
+ XRANFTHRX_PRB_MAP_IN,
XRANFTHRACH_IN,
MAX_SW_XRAN_INTERFACE_NUM
}SWXRANInterfaceTypeEnum;
// -1 means that DL packet to be transmitted is not ready in BS
int32_t nSegTransferred; // number of data segments has been transmitted or received
struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
- XRANBufferListStruct sBufferList;
+ struct xran_buffer_list sBufferList;
} BbuIoBufCtrlStruct;
typedef struct {
/* io struct */
BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
/* buffers lists */
- XRANFlatBufferStruct sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
- XRANFlatBufferStruct sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
- XRANFlatBufferStruct sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
void* nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool
uint16_t nInstanceNum;
- /*subframe type for this TTI:
- 0: DL control + DL data
- 1: DL control + DL data + UL control
- 2: DL control + UL data
- 3: DL control + UL data + UL control
- */
- uint8_t nSubframeType;
-
uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
} BbuXranIoIfStruct;
static BbuXranIoIfStruct gsXranIoIf;
static XranLibConfigStruct *gpXranLibConfig = NULL;
+extern long rx_counter;
+extern long tx_counter;
+
#define CPU_HZ tick_per_usec //us
/* Application User space functions */
puts("+---------------------------------------+");
}
-void xran_fh_rx_callback(void *pCallbackTag, XranStatusInt32 status)
+static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
+{
+ int32_t nSfIdx = -1;
+ uint32_t nFrameIdx;
+ uint32_t nSubframeIdx;
+ uint32_t nSlotIdx;
+ uint64_t nSecond;
+
+ uint32_t nXranTime = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
+ nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
+ + nSubframeIdx*nNrOfSlotInSf
+ + nSlotIdx;
+#if 0
+ printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
+ nXranTime,
+ nSfIdx,
+ nFrameIdx,
+ nSubframeIdx,
+ nSlotIdx,
+ __rdtsc()/CPU_HZ);
+#endif
+
+ return nSfIdx;
+}
+
+void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
{
uint64_t t1 = MLogTick();
uint32_t mlogVar[10];
uint32_t mlogVarCnt = 0;
+ uint8_t Numerlogy = xranConf.frame_conf.nNumerology;
+ uint8_t nNrOfSlotInSf = 1<<Numerlogy;
+ int32_t sfIdx = get_xran_sfidx(nNrOfSlotInSf);
mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
mlogVar[mlogVarCnt++] = status >> 16; /* tti */
mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
+ mlogVar[mlogVarCnt++] = (uint32_t)sfIdx;
MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
rte_pause();
return;
}
-void xran_fh_rx_prach_callback(void *pCallbackTag, XranStatusInt32 status)
+void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
{
uint64_t t1 = MLogTick();
+ uint32_t mlogVar[10];
+ uint32_t mlogVarCnt = 0;
+
+ mlogVar[mlogVarCnt++] = 0xDDDDDDDD;
+ mlogVar[mlogVarCnt++] = status >> 16; /* tti */
+ mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
+ MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
rte_pause();
+
MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
}
int32_t init_xran(void)
{
BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
- XranStatusInt32 status;
+ xran_status_t status;
int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
int32_t nSectorNum;
int32_t i, j, k, z;
void *ptr;
+ void *mb;
uint32_t *u32dptr;
uint16_t *u16dptr;
uint8_t *u8dptr;
XranLibConfigStruct *ptrLibConfig;
- XRANBufferListStruct *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
- XRANBufferListStruct *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
- XRANBufferListStruct *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
-
- FPGAPhaseCompCfg *pPhaseCompDl = NULL;
- FPGAPhaseCompCfg *pPhaseCompUl = NULL;
- uint32_t nPhaseCompDl,nPhaseCompUl;
+ struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+ struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+ struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+ struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
+ struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
-
-#if 0
- printf("init_xran: nFpgaProbe[%d] nSecNum[%d] nUENum[%d] nTimeAdvance[%d] nEthPorts[%d] nPhaseCompFlag[%d]\n",
- psFPGAInitPara->nFpgaProbe, psFPGAInitPara->nSecNum, psFPGAInitPara->nUENum, psFPGAInitPara->nTimeAdvance, psFPGAInitPara->nEthPorts, psFPGAInitPara->nPhaseCompFlag);
- for (i = 0; i < nSectorNum; i ++)
- {
- printf(" [%d]: nDlArfcn[%d] nUlArfcn[%d]\n", i, psFPGAInitPara->nDlArfcn[i], psFPGAInitPara->nUlArfcn[i]);
- }
-#endif
for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
{
nSectorIndex[nSectorNum] = nSectorNum;
psBbuIo->nInstanceNum = numCCPorts;
for (k = 0; k < XRAN_PORTS_NUM; k++) {
- status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,psBbuIo->nInstanceHandle[k]);
+ status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]);
if (status != XRAN_STATUS_SUCCESS)
{
printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
exit(-1);
}
+ for (i = 0; i < psBbuIo->nInstanceNum; i++){
+ printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]);
+ }
}
printf("Sucess xran_mm_init \n");
ptrLibConfig = gpXranLibConfig;
if (ptrLibConfig)
{
- #if 0
+ #if 0
ptrLibConfig->nDriverCoreId = psBbuIo->nDriverCoreId;
ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
{
ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
}
- #endif
+ #endif
}
else
{
for(i = 0; i<nSectorNum; i++)
{
eInterfaceType = XRANFTHTX_OUT;
- status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+ printf("nSectorIndex[%d] = %d\n",i, nSectorIndex[i]);
+ status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
if(XRAN_STATUS_SUCCESS != status)
{
psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
- status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
if(XRAN_STATUS_SUCCESS != status)
{
printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
iAssert(status == XRAN_STATUS_SUCCESS);
}
psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+ psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if(ptr){
u32dptr = (uint32_t*)(ptr);
}
}
}
+
+ /* C-plane DL */
+ eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
+ printf("nSectorIndex[%d] = %d\n",i, nSectorIndex[i]);
+ status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+ XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
+ if(XRAN_STATUS_SUCCESS != status)
+ {
+ printf("Failed at xran_bm_init , status %d\n", status);
+ iAssert(status == XRAN_STATUS_SUCCESS);
+ }
+ for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
+ {
+ for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z];
+
+ {
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
+ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
+ if(XRAN_STATUS_SUCCESS != status)
+ {
+ printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
+ iAssert(status == XRAN_STATUS_SUCCESS);
+ }
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
+ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
+
+ if(ptr){
+ u32dptr = (uint32_t*)(ptr);
+ uint8_t *ptr_temp = (uint8_t *)ptr;
+ memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
+ ptr_temp[0] = j; // TTI
+ ptr_temp[1] = i; // Sec
+ ptr_temp[2] = z; // Ant
+ ptr_temp[3] = k; // sym
+ }
+ }
+ }
+ }
}
for(i = 0; i<nSectorNum; i++)
{
eInterfaceType = XRANFTHRX_IN;
- status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
+ status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
if(XRAN_STATUS_SUCCESS != status)
{
printf("Failed at xran_bm_init, status %d\n", status);
psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
- status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
if(XRAN_STATUS_SUCCESS != status)
{
- printf("Failed at cpa_bb_bm_allocate_buffer , status %d\n",status);
+ printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
iAssert(status == XRAN_STATUS_SUCCESS);
}
psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+ psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
if(ptr){
u32dptr = (uint32_t*)(ptr);
uint8_t *ptr_temp = (uint8_t *)ptr;
}
}
}
+
+ /* C-plane */
+ eInterfaceType = XRANFTHRX_PRB_MAP_IN;
+ status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
+ XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
+ if(XRAN_STATUS_SUCCESS != status)
+ {
+ printf("Failed at xran_bm_init, status %d\n", status);
+ iAssert(status == XRAN_STATUS_SUCCESS);
+ }
+
+ for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
+ {
+ for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z];
+ {
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
+ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
+ if(XRAN_STATUS_SUCCESS != status)
+ {
+ printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
+ iAssert(status == XRAN_STATUS_SUCCESS);
+ }
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
+ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
+ if(ptr){
+ u32dptr = (uint32_t*)(ptr);
+ uint8_t *ptr_temp = (uint8_t *)ptr;
+ memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
+ ptr_temp[0] = j; // TTI
+ ptr_temp[1] = i; // Sec
+ ptr_temp[2] = z; // Ant
+ ptr_temp[3] = k; // sym
+ }
+ }
+ }
+ }
}
// add prach rx buffer
for(i = 0; i<nSectorNum; i++)
{
eInterfaceType = XRANFTHRACH_IN;
- status =xran_bm_init(xranHandle,&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
+ status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
if(XRAN_STATUS_SUCCESS != status)
{
printf("Failed at xran_bm_init, status %d\n", status);
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
- //for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
- k = 0; // one PRACH buffer per antenna per slot
+ for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
{
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
- status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
+ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
if(XRAN_STATUS_SUCCESS != status)
{
printf("Failed at xran_bm_allocate_buffer, status %d\n",status);
iAssert(status == XRAN_STATUS_SUCCESS);
}
psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
+ psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if(ptr){
u32dptr = (uint32_t*)(ptr);
memset(u32dptr, 0xCC, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
{
for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
pFthTxBuffer[i][z][j] = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
+ pFthTxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
+ pFthRxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
}
}
{
xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
pFthTxBuffer[i],
+ pFthTxPrbMapBuffer[i],
pFthRxBuffer[i],
+ pFthRxPrbMapBuffer[i],
xran_fh_rx_callback, &pFthRxBuffer[i][0]);
}
ptrLibConfig->nFhBufIntFlag = 1;
}
- /*config phase compensation*/
- /* TODO: add phase compensation handling */
- for(i=0; i<nSectorNum; i++)
- {
- pPhaseCompDl = (FPGAPhaseCompCfg *)(&nPhaseCompDl);
- pPhaseCompDl->NRARFCN = 0;//psFPGAInitPara->nDlArfcn[i];
- pPhaseCompDl->phaseFlag = 0;//psFPGAInitPara->nPhaseCompFlag;
- pPhaseCompDl->SULFlag = 0;
- pPhaseCompDl->SULFreShift = 0;
- pPhaseCompDl->rsv = 0;
-
- pPhaseCompUl = (FPGAPhaseCompCfg *)(&nPhaseCompUl);
- pPhaseCompUl->NRARFCN = 0;//psFPGAInitPara->nUlArfcn[i];
- pPhaseCompUl->phaseFlag = 0;// psFPGAInitPara->nPhaseCompFlag;
- pPhaseCompUl->SULFlag = 0;
- pPhaseCompUl->SULFreShift = 0;
- pPhaseCompUl->rsv = 0;
-
- xran_5g_pre_compenstor_cfg(psBbuIo->nInstanceHandle[0][i],nPhaseCompDl,nPhaseCompUl,i);
-
- printf("@@@ NB cell %d DL NR-ARFCN %d,DL phase comp flag %d UL NR-ARFCN %d,UL phase comp flag %d \n",
- i,pPhaseCompDl->NRARFCN,pPhaseCompDl->phaseFlag,
- pPhaseCompUl->NRARFCN,pPhaseCompUl->phaseFlag);
- }
return status;
}
int init_xran_iq_content(void)
{
BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
- XranStatusInt32 status;
+ xran_status_t status;
int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
int32_t nSectorNum;
int32_t cc_id, ant_id, sym_id, tti;
uint8_t *u8dptr;
char *pos = NULL;
+ struct xran_prb_map *pRbMap = NULL;
for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
{
for(tti = 0; tti < XRAN_N_FE_BUF_LEN; tti ++) {
for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
- flowId = nSectorNum * ant_id + cc_id;
+
+ flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
if(p_tx_play_buffer[flowId]){
- /* (0-79 slots) 10ms of IQs */
pos = ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
-
ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
- if(ptr){
+ if(ptr && pos){
u32dptr = (uint32_t*)(ptr);
- rte_memcpy(u32dptr, pos, PDSCH_PAYLOAD_SIZE);
+ rte_memcpy(u32dptr, pos, pXranConf->nDLRBs*N_SC_PER_PRB*4);
#ifdef DEBUG_XRAN_BUFFERS
uint8_t *ptr_temp = (uint8_t *)ptr;
ptr_temp[0] = tti; // TTI
ptr_temp[2] = ant_id; // Ant
ptr_temp[3] = sym_id; // sym
#endif
- }else
+ } else {
+ exit(-1);
printf("ptr ==NULL\n");
-
- tx_play_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
+ }
+
+ /* c-plane DL */
+ pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
+ if(pRbMap){
+ pRbMap->dir = XRAN_DIR_DL;
+ pRbMap->xran_port = 0;
+ pRbMap->band_id = 0;
+ pRbMap->cc_id = cc_id;
+ pRbMap->ru_port_id = ant_id;
+ pRbMap->tti_id = tti;
+ pRbMap->start_sym_id = 0;
+ pRbMap->nPrbElm = 1;
+ pRbMap->prbMap[0].nRBStart = 0;
+ pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
+ pRbMap->prbMap[0].nBeamIndex = 0;
+ pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
+ }else{
+ printf("DL pRbMap ==NULL\n");
+ exit(-1);
+ }
+
+ /* c-plane UL */
+ pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
+ if(pRbMap){
+ pRbMap->dir = XRAN_DIR_UL;
+ pRbMap->xran_port = 0;
+ pRbMap->band_id = 0;
+ pRbMap->cc_id = cc_id;
+ pRbMap->ru_port_id = ant_id;
+ pRbMap->tti_id = tti;
+ pRbMap->start_sym_id = 0;
+ pRbMap->nPrbElm = 1;
+ pRbMap->prbMap[0].nRBStart = 0;
+ pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
+ pRbMap->prbMap[0].nBeamIndex = 0;
+ pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
+ }else {
+ printf("UL: pRbMap ==NULL\n");
+ exit(-1);
+ }
+
+ tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4;
if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
tx_play_buffer_position[flowId] = 0;
}
}
}
- }
+ /* prach TX for RU only */
+ if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+ for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
+ for(sym_id = 0; sym_id < 1; sym_id++) {
+ flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
+
+ if(p_tx_prach_play_buffer[flowId]){
+ /* (0-79 slots) 10ms of IQs */
+ pos = ((char*)p_tx_prach_play_buffer[flowId]);
+
+ ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+
+ if(ptr && pos){
+ u32dptr = (uint32_t*)(ptr);
+ rte_memcpy(u32dptr, pos, PRACH_PLAYBACK_BUFFER_BYTES);
+#ifdef DEBUG_XRAN_BUFFERS
+ uint8_t *ptr_temp = (uint8_t *)ptr;
+ ptr_temp[0] = tti; // TTI
+ ptr_temp[1] = cc_id; // Sec
+ ptr_temp[2] = ant_id; // Ant
+ ptr_temp[3] = sym_id; // sym
+#endif
+ } else {
+ exit(-1);
+ printf("ptr ==NULL\n");
+ }
+ } else {
+ //printf("flowId %d\n", flowId);
+ }
+ }
+ }
+ }
+ }
}
return 0;
void stop_xran(void)
{
- XranStatusInt32 status = 0;
+ xran_status_t status = 0;
SWXRANInterfaceTypeEnum eInterfaceType;
free(gpXranLibConfig);
}
}
-int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
-{
- int32_t nSfIdx = -1;
- uint32_t nFrameIdx;
- uint32_t nSubframeIdx;
- uint32_t nSlotIdx;
- uint64_t nSecond;
-
- uint32_t nXranTime = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
- nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
- + nSubframeIdx*nNrOfSlotInSf
- + nSlotIdx;
-#if 0
- printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
- nXranTime,
- nSfIdx,
- nFrameIdx,
- nSubframeIdx,
- nSlotIdx,
- __rdtsc()/CPU_HZ);
-#endif
-
- return nSfIdx;
-}
-
int get_xran_iq_content(void)
{
BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
- XranStatusInt32 status;
+ xran_status_t status;
int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
int32_t nSectorNum;
int32_t cc_id, ant_id, sym_id, tti;
for(tti = 0; tti < XRAN_N_FE_BUF_LEN; tti++) {
for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
- flowId = nSectorNum * ant_id + cc_id;
+ flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
if(p_rx_log_buffer[flowId]){
/* (0-79 slots) 10ms of IQs */
pos = ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
if(ptr){
u32dptr = (uint32_t*)(ptr);
- rte_memcpy(pos, u32dptr, PDSCH_PAYLOAD_SIZE);
+ rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4);
#ifdef DEBUG_XRAN_BUFFERS
if (pos[0] != tti||
pos[1] != cc_id ||
}else
printf("ptr ==NULL\n");
- rx_log_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
+ rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;
if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
rx_log_buffer_position[flowId] = 0;
//printf("flowId %d\n", flowId);
}
}
+
+ /* prach RX for O-DU only */
+ if(startupConfiguration.appMode == APP_O_DU){
+ flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
+ sym_id = 0;
+
+ if(p_prach_log_buffer[flowId]){
+ /* (0-79 slots) 10ms of IQs */
+ pos = ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId];
+ ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+ if(ptr){
+ u32dptr = (uint32_t*)(ptr);
+ rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES);
+#ifdef DEBUG_XRAN_BUFFERS
+ if (pos[0] != tti||
+ pos[1] != cc_id ||
+ pos[2] != ant_id ||
+ pos[3] != sym_id){
+ printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
+ }
+#endif
+ }else
+ printf("ptr ==NULL\n");
+
+ prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES;
+
+ if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId])
+ prach_log_buffer_position[flowId] = 0;
+ } else {
+ //printf("flowId %d\n", flowId);
+ }
+ }
+
}
}
}
return 0;
}
+void version_print(void)
+{
+ char sysversion[100];
+ char *compilation_date = __DATE__;
+ char *compilation_time = __TIME__;
+
+ uint32_t nLen;
+ uint32_t i;
+
+ snprintf(sysversion, 99, "Version: %s", VERSIONX);
+ nLen = strlen(sysversion);
+
+ printf("\n\n");
+ printf("===========================================================================================================\n");
+ printf("SAMPLE-APP VERSION\n");
+ printf("===========================================================================================================\n");
+
+ printf("%s\n", sysversion);
+ printf("build-date: %s\n", compilation_date);
+ printf("build-time: %s\n", compilation_time);
+}
+
int main(int argc, char *argv[])
{
int i;
- int j;
+ int j, len;
int lcore_id = 0;
char filename[64];
+ uint32_t nCenterFreq;
+ int32_t xret = 0;
+ struct stat st = {0};
+ uint32_t filenameLength = strlen(argv[1]);
+ char *pCheckName1 = NULL, *pCheckName2 = NULL;
+ enum xran_if_state xran_curr_if_state = XRAN_INIT;
if (argc == 3)
errx(2, "Need two argument - the PCI address of the network port");
+ if (filenameLength >= 64)
+ {
+ printf("Config file name input is too long, exiting!\n");
+ exit(-1);
+ }
+
+ version_print();
+
+ //add for Klocworks
+ len = strlen(argv[1]) + 1;
+ if (len > (sizeof(filename) - 10))
+ len = (sizeof(filename) - 10);
+ strncpy(filename, argv[1], (sizeof(filename) - 10));
+ filename[len] = '\0';
+
+ pCheckName1 = strstr(filename, "config_file_o_du.dat");
+ pCheckName2 = strstr(filename, "config_file_o_ru.dat");
+ if ((pCheckName1 == NULL) && (pCheckName2 == NULL))
+ {
+ printf("config file name %s is not valid!\n", filename);
+ exit(-1);
+ }
if (xran_is_synchronized() != 0)
printf("Machine is not synchronized using PTP!\n");
memset(&startupConfiguration, 0, sizeof(RuntimeConfig));
- if (parseConfigFile(argv[1], &startupConfiguration) != 0) {
+ if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) {
printf("Configuration file error.\n");
return 0;
}
printf("it looks like test vector for antennas were not provided\n");
exit(-1);
}
+ if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR)
+ {
+ printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR);
+ startupConfiguration.numCC = XRAN_MAX_SECTOR_NR;
+ }
numCCPorts = startupConfiguration.numCC;
num_eAxc = startupConfiguration.numAxc;
printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);
- /* Numerology 3 */
- nFpgaToSW_FTH_RxBufferLen = 3328; //3200 * 14;
- nFpgaToSW_PRACH_RxBufferLen = 8192;
- nSW_ToFpga_FTH_TxBufferLen = 3328; //3200; * 14;
+ if (startupConfiguration.mu_number <= 1){
+ nFpgaToSW_FTH_RxBufferLen = 13168; /* 273*12*4 + 64*/
+ nFpgaToSW_PRACH_RxBufferLen = 8192;
+ nSW_ToFpga_FTH_TxBufferLen = 13168; /* 273*12*4 + 64*/
+ } else if (startupConfiguration.mu_number == 3){
+ nFpgaToSW_FTH_RxBufferLen = 3328;
+ nFpgaToSW_PRACH_RxBufferLen = 8192;
+ nSW_ToFpga_FTH_TxBufferLen = 3328;
+ } else {
+ printf("given numerology is not supported %d\n", startupConfiguration.mu_number);
+ exit(-1);
+ }
- memset(&xranInit, 0, sizeof(XRANFHINIT));
+ memset(&xranInit, 0, sizeof(struct xran_fh_init));
- if(startupConfiguration.appMode == APP_LLS_CU) {
- printf("set lls-CU\n");
+ if(startupConfiguration.appMode == APP_O_DU) {
+ printf("set O-DU\n");
xranInit.io_cfg.id = 0;//ID_LLS_CU;
xranInit.io_cfg.core = 4+1;
xranInit.io_cfg.system_core = 0;
xranInit.io_cfg.pkt_aux_core = 0; /* do not start*/
xranInit.io_cfg.timing_core = 4+3;
} else {
- printf("set RU\n");
+ printf("set O-DU\n");
xranInit.io_cfg.id = 1; /* ID_LLS_CU;*/
xranInit.io_cfg.core = 1;
xranInit.io_cfg.system_core = 0;
xranInit.io_cfg.timing_core = 3;
}
- xranInit.llscuId = 0; // for ecpriRtcid/ecpriPcid
- xranInit.nSec = 1; // shall be one
+ xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
xranInit.eAxCId_conf.mask_cuPortId = 0xf000;
xranInit.eAxCId_conf.mask_bandSectorId = 0x0f00;
xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] = argv[2];
xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] = argv[3];
- xranInit.p_lls_cu_addr = (int8_t*)&startupConfiguration.lls_cu_addr;
- xranInit.p_ru_addr = (int8_t*)&startupConfiguration.ru_addr;
- xranInit.ttiPeriod = startupConfiguration.ttiPeriod;
+ xranInit.mtu = startupConfiguration.mtu;
+
+ xranInit.p_o_du_addr = (int8_t*)&startupConfiguration.o_du_addr;
+ xranInit.p_o_ru_addr = (int8_t*)&startupConfiguration.o_ru_addr;
+ xranInit.filePrefix = "wls";
+ xranInit.xranCat = XRAN_CATRGORY_A;
xranInit.Tadv_cp_dl = startupConfiguration.Tadv_cp_dl;
xranInit.T2a_min_cp_dl = startupConfiguration.T2a_min_cp_dl;
xranInit.Ta4_min = startupConfiguration.Ta4_min;
xranInit.Ta4_max = startupConfiguration.Ta4_max;
- xranInit.enableCP = startupConfiguration.enableCP;
- xranInit.debugStop = startupConfiguration.debugStop;
+ xranInit.enableCP = startupConfiguration.enableCP;
+ xranInit.prachEnable = startupConfiguration.enablePrach;
+ xranInit.debugStop = startupConfiguration.debugStop;
+ xranInit.debugStopCount = startupConfiguration.debugStopCount;
+ xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna;
+ xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; //startupConfiguration.bbdevMode;
+
+ xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag;
+ xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag;
- xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag;
- xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag;
+ printf("IQ files size is %d slots\n", startupConfiguration.numSlots);
+ iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
+ app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
+ *4L);
+
+ iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
+ app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
+ *4L);
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- p_tx_play_buffer[i] = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
- tx_play_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
+ p_tx_play_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_dl);
+ tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;
if (p_tx_play_buffer[i] == NULL)
exit(-1);
tx_play_buffer_position[i] = 0;
}
+ if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+ p_tx_prach_play_buffer[i] = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
+ tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
+
+ if (p_tx_prach_play_buffer[i] == NULL)
+ exit(-1);
+
+ tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i],
+ "PRACH IQ Samples in binary format",
+ (uint8_t*) p_tx_prach_play_buffer[i],
+ tx_prach_play_buffer_size[i],
+ 1);
+ tx_prach_play_buffer_position[i] = 0;
+ }
+ }
/* log of ul */
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- p_rx_log_buffer[i] = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
- rx_log_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
+ p_rx_log_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_ul);
+ rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul;
if (p_rx_log_buffer[i] == NULL)
exit(-1);
/* log of Prach */
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- p_prach_log_buffer[i] = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
- prach_log_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
+ p_prach_log_buffer[i] = (int16_t*)malloc(startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES);
+ prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES;
if (p_prach_log_buffer[i] == NULL)
exit(-1);
prach_log_buffer_position[i] = 0;
}
+ if (stat("./logs", &st) == -1) {
+ mkdir("./logs", 0777);
+ }
+
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "%s-play_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+ sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
sys_save_buf_to_file_txt(filename,
"DL IFFT IN IQ Samples in human readable format",
(uint8_t*) p_tx_play_buffer[i],
tx_play_buffer_size[i],
1);
- sprintf(filename, "%s-play_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+ sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
sys_save_buf_to_file(filename,
"DL IFFT IN IQ Samples in binary format",
(uint8_t*) p_tx_play_buffer[i],
tx_play_buffer_size[i]/sizeof(short),
sizeof(short));
+
+ if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
+ sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+ sys_save_buf_to_file_txt(filename,
+ "DL IFFT IN IQ Samples in human readable format",
+ (uint8_t*) p_tx_prach_play_buffer[i],
+ tx_prach_play_buffer_size[i],
+ 1);
+
+ sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+ sys_save_buf_to_file(filename,
+ "DL IFFT IN IQ Samples in binary format",
+ (uint8_t*) p_tx_prach_play_buffer[i],
+ tx_prach_play_buffer_size[i]/sizeof(short),
+ sizeof(short));
+ }
}
if (startupConfiguration.iqswap == 1){
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
}
}
}
+ if (startupConfiguration.appMode == APP_O_RU){
+ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+ printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
+ {
+ /* swap I and Q */
+ int32_t j;
+ signed short *ptr = (signed short *) p_tx_prach_play_buffer[i];
+ signed short temp;
+
+ for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
+ temp = ptr[j];
+ ptr[j] = ptr[j + 1];
+ ptr[j + 1] = temp;
+ }
+ }
+ }
+ }
+
}
#if 0
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "swap_IQ_play_ant%d.txt", i);
+ sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
sys_save_buf_to_file_txt(filename,
"DL IFFT IN IQ Samples in human readable format",
(uint8_t*) p_tx_play_buffer[i],
p_tx_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
}
}
+
+ if (startupConfiguration.appMode == APP_O_RU){
+ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+ printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
+ for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){
+ p_tx_prach_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]);
+ }
+ }
+ }
}
#if 0
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "swap_be_play_ant%d.txt", i);
+ sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
sys_save_buf_to_file_txt(filename,
"DL IFFT IN IQ Samples in human readable format",
(uint8_t*) p_tx_play_buffer[i],
}
#endif
+
timer_set_tsc_freq_from_clock();
- xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
+ xret = xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
+ if(xret != XRAN_STATUS_SUCCESS){
+ printf("xran_init failed %d\n", xret);
+ exit(-1);
+ }
+
if(xranHandle == NULL)
exit(1);
- memset(&xranConf, 0, sizeof(XRANFHCONFIG));
+ memset(&xranConf, 0, sizeof(struct xran_fh_config));
pXranConf = &xranConf;
- for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- pXranConf->playback_conf.TxPlayBufAddr[i] = (unsigned long)p_tx_play_buffer[i];
- pXranConf->playback_conf.TxPlayBufSize = tx_play_buffer_size[i];
- }
-
pXranConf->sector_id = 0;
pXranConf->nCC = numCCPorts;
pXranConf->neAxc = num_eAxc;
- pXranConf->frame_conf.nFrameDuplexType = 1; // TDD
- pXranConf->frame_conf.nNumerology = startupConfiguration.mu_number; // 120KHz; same as XRAN_SCS_120KHz?
-// pXranConf->frame_conf.nTddPeriod = ;
+ pXranConf->frame_conf.nFrameDuplexType = startupConfiguration.nFrameDuplexType;
+ pXranConf->frame_conf.nNumerology = startupConfiguration.mu_number;
+ pXranConf->frame_conf.nTddPeriod = startupConfiguration.nTddPeriod;
- pXranConf->prach_conf.nPrachSubcSpacing = XRAN_SCS_120KHZ;
+ for (i = 0; i < startupConfiguration.nTddPeriod; i++){
+ pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i];
+ }
+
+ pXranConf->prach_conf.nPrachSubcSpacing = startupConfiguration.mu_number;
pXranConf->prach_conf.nPrachFreqStart = 0;
pXranConf->prach_conf.nPrachFilterIdx = XRAN_FILTERINDEX_PRACH_ABC;
- pXranConf->prach_conf.nPrachConfIdx = 81;
+ pXranConf->prach_conf.nPrachConfIdx = startupConfiguration.prachConfigIndex;
pXranConf->prach_conf.nPrachFreqOffset = -792;
pXranConf->ru_conf.iqWidth = 16;
pXranConf->ru_conf.compMeth = XRAN_COMPMETHOD_NONE;
- pXranConf->ru_conf.fftSize = XRAN_FFTSIZE_2048;
+ pXranConf->ru_conf.fftSize = 0;
+ while (startupConfiguration.nULFftSize >>= 1)
+ ++pXranConf->ru_conf.fftSize;
+
+ pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER ;
+ pXranConf->ru_conf.iqOrder = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;
+
+ printf("FFT Order %d\n", pXranConf->ru_conf.fftSize);
+ pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA);
+ pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA);
+
+ nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
+ pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
+ printf("DL center freq %d DL NR-ARFCN %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN);
+
+ nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
+ pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
+ printf("UL center freq %d UL NR-ARFCN %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN);
+
+ pXranConf->bbdev_dec = NULL;
+ pXranConf->bbdev_enc = NULL;
if(init_xran() != 0)
exit(-1);
init_xran_iq_content();
- xran_open(xranHandle, pXranConf);
+ xret = xran_open(xranHandle, pXranConf);
+
+ if(xret != XRAN_STATUS_SUCCESS){
+ printf("xran_open failed %d\n", xret);
+ exit(-1);
+ }
+
+ sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru");
+
+// MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
- sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "lls-cu" : "ru");
+ MLogOpen(256, 3, 20000, 0xFFFFFFFF, filename);
- MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
puts("----------------------------------------");
printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
puts("----------------------------------------");
+
+ uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
+ nActiveCoreMask[0] = 1 << xranInit.io_cfg.timing_core;
+ uint32_t numCarriers = startupConfiguration.numCC;
+
+ MLogAddTestCase(nActiveCoreMask, numCarriers);
+
+ fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+
state = APP_RUNNING;
- sleep(6);
+ printf("Start XRAN traffic\n");
+ xran_start(xranHandle);
+ sleep(3);
+ print_menu();
for (;;) {
- print_menu();
+ struct xran_common_counters x_counters;
char input[10];
- int sel_opt;
-//#ifdef Nightly_build
-// sel_opt = 3;
-// sleep(10);
-//#else
- if (NULL == fgets(input, 10, stdin)) {
- state = APP_STOPPED;
+ sleep(1);
+ xran_curr_if_state = xran_get_if_state();
+ if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) {
+ printf("rx %ld tx %ld [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld\n", rx_counter, tx_counter,
+ x_counters.Rx_on_time,
+ x_counters.Rx_early,
+ x_counters.Rx_late,
+ x_counters.Rx_corrupt,
+ x_counters.Rx_pkt_dupl,
+ x_counters.Total_msgs_rcvd);
+ } else {
+ printf("error xran_get_common_counters\n");
+ }
+
+ if (xran_curr_if_state == XRAN_STOPPED){
break;
}
- sel_opt = atoi(input);
-//#endif
+ if (NULL == fgets(input, 10, stdin)) {
+ continue;
+ }
+
+ const int sel_opt = atoi(input);
switch (sel_opt) {
case 1:
xran_start(xranHandle);
printf("Stop XRAN traffic\n");
state = APP_STOPPED;
break;
- case 4:
-// send_cpmsg_dlul(XRAN_DIR_DL, flowId,
-// frame_id, subframe_id, slot_id,
-// 0, XRAN_SYMBOLPERSLOT_MAX, NUM_OF_PRB_IN_FULL_BAND,
-// beam_id, cc_id, ant_id,
-// cp_seq_id_num[XRAN_DIR_DL][ant_id]++);
- break;
default:
puts("Wrong option passed!");
break;
}
-
if (APP_STOPPED == state)
break;
}
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+ sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
sys_save_buf_to_file_txt(filename,
"UL FFT OUT IQ Samples in human readable format",
(uint8_t*) p_rx_log_buffer[i],
rx_log_buffer_size[i],
1);
- sprintf(filename, "%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
+ sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
sys_save_buf_to_file(filename,
"UL FFT OUT IQ Samples in binary format",
(uint8_t*) p_rx_log_buffer[i],
sizeof(short));
}
- if (startupConfiguration.iqswap == 1){
- for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
- {
- /* swap I and Q */
- int32_t j;
- signed short *ptr = (signed short *) p_prach_log_buffer[i];
- signed short temp;
-
- for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
- temp = ptr[j];
- ptr[j] = ptr[j + 1];
- ptr[j + 1] = temp;
+ if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enablePrach){
+ if (startupConfiguration.iqswap == 1){
+ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+ printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
+ {
+ /* swap I and Q */
+ int32_t j;
+ signed short *ptr = (signed short *) p_prach_log_buffer[i];
+ signed short temp;
+
+ for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
+ temp = ptr[j];
+ ptr[j] = ptr[j + 1];
+ ptr[j + 1] = temp;
+ }
}
}
}
- }
- if (startupConfiguration.nebyteorderswap == 1){
- for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
- for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
- p_prach_log_buffer[i][j] = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
+
+ if (startupConfiguration.nebyteorderswap == 1){
+ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
+ printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
+ for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
+ p_prach_log_buffer[i][j] = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
+ }
}
}
- }
- for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
- sys_save_buf_to_file_txt(filename,
- "PRACH FFT OUT IQ Samples in human readable format",
- (uint8_t*) p_prach_log_buffer[i],
- prach_log_buffer_size[i],
- 1);
+ for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
- sprintf(filename, "%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
- sys_save_buf_to_file(filename,
- "PRACH FFT OUT IQ Samples in binary format",
- (uint8_t*) p_prach_log_buffer[i],
- prach_log_buffer_size[i]/sizeof(short),
- sizeof(short));
+ sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+ sys_save_buf_to_file_txt(filename,
+ "PRACH FFT OUT IQ Samples in human readable format",
+ (uint8_t*) p_prach_log_buffer[i],
+ prach_log_buffer_size[i],
+ 1);
+
+ sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
+ sys_save_buf_to_file(filename,
+ "PRACH FFT OUT IQ Samples in binary format",
+ (uint8_t*) p_prach_log_buffer[i],
+ prach_log_buffer_size[i]/sizeof(short),
+ sizeof(short));
+ }
}
return 0;
*
*******************************************************************************/
-
/**
* @brief This file has the System Debug Trace Logger (Mlog) Task IDs used by PHY
* @file mlog_task_id.h
#ifndef _XRAN_TASK_ID_H_
#define _XRAN_TASK_ID_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define RESOURCE_CORE_0 0
#define RESOURCE_CORE_1 1
#define RESOURCE_CORE_2 2
// XRAN APP
//--------------------------------------------------------------------
-#define PID_GNB_PROC_TIMING 902
-#define PID_GNB_PROC_TIMING_TIMEOUT 903
-#define PID_GNB_SYM_CB 904
-#define PID_GNB_PRACH_CB 905
+#define PID_GNB_PROC_TIMING 70
+#define PID_GNB_PROC_TIMING_TIMEOUT 71
+#define PID_GNB_SYM_CB 72
+#define PID_GNB_PRACH_CB 73
+#ifdef __cplusplus
+}
+#endif
#endif /* _XRAN_TASK_ID_H_ */
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=12 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/12/ant_0.bin #CC0
+antC1=./usecase/mu0_10mhz/12/ant_1.bin #CC0
+antC2=./usecase/mu0_10mhz/12/ant_2.bin #CC0
+antC3=./usecase/mu0_10mhz/12/ant_3.bin #CC0
+antC4=./usecase/mu0_10mhz/12/ant_4.bin #CC1
+antC5=./usecase/mu0_10mhz/12/ant_5.bin #CC1
+antC6=./usecase/mu0_10mhz/12/ant_6.bin #CC1
+antC7=./usecase/mu0_10mhz/12/ant_7.bin #CC1
+antC8=./usecase/mu0_10mhz/12/ant_8.bin #CC2
+antC9=./usecase/mu0_10mhz/12/ant_9.bin #CC2
+antC10=./usecase/mu0_10mhz/12/ant_10.bin #CC2
+antC11=./usecase/mu0_10mhz/12/ant_11.bin #CC2
+antC12=./usecase/mu0_10mhz/12/ant_12.bin #CC3
+antC13=./usecase/mu0_10mhz/12/ant_13.bin #CC3
+antC14=./usecase/mu0_10mhz/12/ant_14.bin #CC3
+antC15=./usecase/mu0_10mhz/12/ant_15.bin #CC3
+antC16=./usecase/mu0_10mhz/12/ant_0.bin #CC4
+antC17=./usecase/mu0_10mhz/12/ant_1.bin #CC4
+antC18=./usecase/mu0_10mhz/12/ant_2.bin #CC4
+antC19=./usecase/mu0_10mhz/12/ant_3.bin #CC4
+antC20=./usecase/mu0_10mhz/12/ant_4.bin #CC5
+antC21=./usecase/mu0_10mhz/12/ant_5.bin #CC5
+antC22=./usecase/mu0_10mhz/12/ant_6.bin #CC5
+antC23=./usecase/mu0_10mhz/12/ant_7.bin #CC5
+antC24=./usecase/mu0_10mhz/12/ant_8.bin #CC6
+antC25=./usecase/mu0_10mhz/12/ant_9.bin #CC6
+antC26=./usecase/mu0_10mhz/12/ant_10.bin #CC6
+antC27=./usecase/mu0_10mhz/12/ant_11.bin #CC6
+antC28=./usecase/mu0_10mhz/12/ant_12.bin #CC7
+antC29=./usecase/mu0_10mhz/12/ant_13.bin #CC7
+antC30=./usecase/mu0_10mhz/12/ant_14.bin #CC7
+antC31=./usecase/mu0_10mhz/12/ant_15.bin #CC7
+antC32=./usecase/mu0_10mhz/12/ant_0.bin #CC8
+antC33=./usecase/mu0_10mhz/12/ant_1.bin #CC8
+antC34=./usecase/mu0_10mhz/12/ant_2.bin #CC8
+antC35=./usecase/mu0_10mhz/12/ant_3.bin #CC8
+antC36=./usecase/mu0_10mhz/12/ant_4.bin #CC9
+antC37=./usecase/mu0_10mhz/12/ant_5.bin #CC9
+antC38=./usecase/mu0_10mhz/12/ant_6.bin #CC9
+antC39=./usecase/mu0_10mhz/12/ant_7.bin #CC9
+antC40=./usecase/mu0_10mhz/12/ant_8.bin #CC10
+antC41=./usecase/mu0_10mhz/12/ant_9.bin #CC10
+antC42=./usecase/mu0_10mhz/12/ant_10.bin #CC10
+antC43=./usecase/mu0_10mhz/12/ant_11.bin #CC10
+antC44=./usecase/mu0_10mhz/12/ant_12.bin #CC11
+antC45=./usecase/mu0_10mhz/12/ant_13.bin #CC11
+antC46=./usecase/mu0_10mhz/12/ant_14.bin #CC11
+antC47=./usecase/mu0_10mhz/12/ant_15.bin #CC11
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=12 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70 #lls-CU PF for tcpdump
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/12/ant_0.bin #CC0
+antC1=./usecase/mu0_10mhz/12/ant_1.bin #CC0
+antC2=./usecase/mu0_10mhz/12/ant_2.bin #CC0
+antC3=./usecase/mu0_10mhz/12/ant_3.bin #CC0
+antC4=./usecase/mu0_10mhz/12/ant_4.bin #CC1
+antC5=./usecase/mu0_10mhz/12/ant_5.bin #CC1
+antC6=./usecase/mu0_10mhz/12/ant_6.bin #CC1
+antC7=./usecase/mu0_10mhz/12/ant_7.bin #CC1
+antC8=./usecase/mu0_10mhz/12/ant_8.bin #CC2
+antC9=./usecase/mu0_10mhz/12/ant_9.bin #CC2
+antC10=./usecase/mu0_10mhz/12/ant_10.bin #CC2
+antC11=./usecase/mu0_10mhz/12/ant_11.bin #CC2
+antC12=./usecase/mu0_10mhz/12/ant_12.bin #CC3
+antC13=./usecase/mu0_10mhz/12/ant_13.bin #CC3
+antC14=./usecase/mu0_10mhz/12/ant_14.bin #CC3
+antC15=./usecase/mu0_10mhz/12/ant_15.bin #CC3
+antC16=./usecase/mu0_10mhz/12/ant_0.bin #CC4
+antC17=./usecase/mu0_10mhz/12/ant_1.bin #CC4
+antC18=./usecase/mu0_10mhz/12/ant_2.bin #CC4
+antC19=./usecase/mu0_10mhz/12/ant_3.bin #CC4
+antC20=./usecase/mu0_10mhz/12/ant_4.bin #CC5
+antC21=./usecase/mu0_10mhz/12/ant_5.bin #CC5
+antC22=./usecase/mu0_10mhz/12/ant_6.bin #CC5
+antC23=./usecase/mu0_10mhz/12/ant_7.bin #CC5
+antC24=./usecase/mu0_10mhz/12/ant_8.bin #CC6
+antC25=./usecase/mu0_10mhz/12/ant_9.bin #CC6
+antC26=./usecase/mu0_10mhz/12/ant_10.bin #CC6
+antC27=./usecase/mu0_10mhz/12/ant_11.bin #CC6
+antC28=./usecase/mu0_10mhz/12/ant_12.bin #CC7
+antC29=./usecase/mu0_10mhz/12/ant_13.bin #CC7
+antC30=./usecase/mu0_10mhz/12/ant_14.bin #CC7
+antC31=./usecase/mu0_10mhz/12/ant_15.bin #CC7
+antC32=./usecase/mu0_10mhz/12/ant_0.bin #CC8
+antC33=./usecase/mu0_10mhz/12/ant_1.bin #CC8
+antC34=./usecase/mu0_10mhz/12/ant_2.bin #CC8
+antC35=./usecase/mu0_10mhz/12/ant_3.bin #CC8
+antC36=./usecase/mu0_10mhz/12/ant_4.bin #CC9
+antC37=./usecase/mu0_10mhz/12/ant_5.bin #CC9
+antC38=./usecase/mu0_10mhz/12/ant_6.bin #CC9
+antC39=./usecase/mu0_10mhz/12/ant_7.bin #CC9
+antC40=./usecase/mu0_10mhz/12/ant_8.bin #CC10
+antC41=./usecase/mu0_10mhz/12/ant_9.bin #CC10
+antC42=./usecase/mu0_10mhz/12/ant_10.bin #CC10
+antC43=./usecase/mu0_10mhz/12/ant_11.bin #CC10
+antC44=./usecase/mu0_10mhz/12/ant_12.bin #CC11
+antC45=./usecase/mu0_10mhz/12/ant_13.bin #CC11
+antC46=./usecase/mu0_10mhz/12/ant_14.bin #CC11
+antC47=./usecase/mu0_10mhz/12/ant_15.bin #CC11
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC1=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC2=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC3=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC4=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC5=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC6=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC7=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC8=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC9=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC10=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC11=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC12=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC13=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC14=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC15=./usecase/mu0_10mhz/12/ant_15.bin
+antPrachC16=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC17=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC18=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC19=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC20=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC21=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC22=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC23=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC24=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC25=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC26=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC27=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC28=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC29=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC30=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC31=./usecase/mu0_10mhz/12/ant_15.bin
+antPrachC32=./usecase/mu0_10mhz/12/ant_0.bin
+antPrachC33=./usecase/mu0_10mhz/12/ant_1.bin
+antPrachC34=./usecase/mu0_10mhz/12/ant_2.bin
+antPrachC35=./usecase/mu0_10mhz/12/ant_3.bin
+antPrachC36=./usecase/mu0_10mhz/12/ant_4.bin
+antPrachC37=./usecase/mu0_10mhz/12/ant_5.bin
+antPrachC38=./usecase/mu0_10mhz/12/ant_6.bin
+antPrachC39=./usecase/mu0_10mhz/12/ant_7.bin
+antPrachC40=./usecase/mu0_10mhz/12/ant_8.bin
+antPrachC41=./usecase/mu0_10mhz/12/ant_9.bin
+antPrachC42=./usecase/mu0_10mhz/12/ant_10.bin
+antPrachC43=./usecase/mu0_10mhz/12/ant_11.bin
+antPrachC44=./usecase/mu0_10mhz/12/ant_12.bin
+antPrachC45=./usecase/mu0_10mhz/12/ant_13.bin
+antPrachC46=./usecase/mu0_10mhz/12/ant_14.bin
+antPrachC47=./usecase/mu0_10mhz/12/ant_15.bin
+
+
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_10mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_10mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_10mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_10mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_10mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_10mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_10mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_10mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_10mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_10mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_10mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_10mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_10mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_10mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_10mhz/ant_15.bin #CC3
+antC16=./usecase/mu0_10mhz/ant_0.bin #CC4
+antC17=./usecase/mu0_10mhz/ant_1.bin #CC4
+antC18=./usecase/mu0_10mhz/ant_2.bin #CC4
+antC19=./usecase/mu0_10mhz/ant_3.bin #CC4
+antC20=./usecase/mu0_10mhz/ant_4.bin #CC5
+antC21=./usecase/mu0_10mhz/ant_5.bin #CC5
+antC22=./usecase/mu0_10mhz/ant_6.bin #CC5
+antC23=./usecase/mu0_10mhz/ant_7.bin #CC5
+antC24=./usecase/mu0_10mhz/ant_8.bin #CC6
+antC25=./usecase/mu0_10mhz/ant_9.bin #CC6
+antC26=./usecase/mu0_10mhz/ant_10.bin #CC6
+antC27=./usecase/mu0_10mhz/ant_11.bin #CC6
+antC28=./usecase/mu0_10mhz/ant_12.bin #CC7
+antC29=./usecase/mu0_10mhz/ant_13.bin #CC7
+antC30=./usecase/mu0_10mhz/ant_14.bin #CC7
+antC31=./usecase/mu0_10mhz/ant_15.bin #CC7
+antC32=./usecase/mu0_10mhz/ant_0.bin #CC8
+antC33=./usecase/mu0_10mhz/ant_1.bin #CC8
+antC34=./usecase/mu0_10mhz/ant_2.bin #CC8
+antC35=./usecase/mu0_10mhz/ant_3.bin #CC8
+antC36=./usecase/mu0_10mhz/ant_4.bin #CC9
+antC37=./usecase/mu0_10mhz/ant_5.bin #CC9
+antC38=./usecase/mu0_10mhz/ant_6.bin #CC9
+antC39=./usecase/mu0_10mhz/ant_7.bin #CC9
+antC40=./usecase/mu0_10mhz/ant_8.bin #CC10
+antC41=./usecase/mu0_10mhz/ant_9.bin #CC10
+antC42=./usecase/mu0_10mhz/ant_10.bin #CC10
+antC43=./usecase/mu0_10mhz/ant_11.bin #CC10
+antC44=./usecase/mu0_10mhz/ant_12.bin #CC11
+antC45=./usecase/mu0_10mhz/ant_13.bin #CC11
+antC46=./usecase/mu0_10mhz/ant_14.bin #CC11
+antC47=./usecase/mu0_10mhz/ant_15.bin #CC11
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+bbdevMode=-1 #bbdev mode, -1 = not use bbdev, 0: use software mode, 1: use hardware mode
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=10 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+
+antC0=./usecase/mu0_10mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_10mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_10mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_10mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_10mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_10mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_10mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_10mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_10mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_10mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_10mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_10mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_10mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_10mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_10mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_10mhz/ant_15.bin #CC3
+antC16=./usecase/mu0_10mhz/ant_0.bin #CC4
+antC17=./usecase/mu0_10mhz/ant_1.bin #CC4
+antC18=./usecase/mu0_10mhz/ant_2.bin #CC4
+antC19=./usecase/mu0_10mhz/ant_3.bin #CC4
+antC20=./usecase/mu0_10mhz/ant_4.bin #CC5
+antC21=./usecase/mu0_10mhz/ant_5.bin #CC5
+antC22=./usecase/mu0_10mhz/ant_6.bin #CC5
+antC23=./usecase/mu0_10mhz/ant_7.bin #CC5
+antC24=./usecase/mu0_10mhz/ant_8.bin #CC6
+antC25=./usecase/mu0_10mhz/ant_9.bin #CC6
+antC26=./usecase/mu0_10mhz/ant_10.bin #CC6
+antC27=./usecase/mu0_10mhz/ant_11.bin #CC6
+antC28=./usecase/mu0_10mhz/ant_12.bin #CC7
+antC29=./usecase/mu0_10mhz/ant_13.bin #CC7
+antC30=./usecase/mu0_10mhz/ant_14.bin #CC7
+antC31=./usecase/mu0_10mhz/ant_15.bin #CC7
+antC32=./usecase/mu0_10mhz/ant_0.bin #CC8
+antC33=./usecase/mu0_10mhz/ant_1.bin #CC8
+antC34=./usecase/mu0_10mhz/ant_2.bin #CC8
+antC35=./usecase/mu0_10mhz/ant_3.bin #CC8
+antC36=./usecase/mu0_10mhz/ant_4.bin #CC9
+antC37=./usecase/mu0_10mhz/ant_5.bin #CC9
+antC38=./usecase/mu0_10mhz/ant_6.bin #CC9
+antC39=./usecase/mu0_10mhz/ant_7.bin #CC9
+antC40=./usecase/mu0_10mhz/ant_8.bin #CC10
+antC41=./usecase/mu0_10mhz/ant_9.bin #CC10
+antC42=./usecase/mu0_10mhz/ant_10.bin #CC10
+antC43=./usecase/mu0_10mhz/ant_11.bin #CC10
+antC44=./usecase/mu0_10mhz/ant_12.bin #CC11
+antC45=./usecase/mu0_10mhz/ant_13.bin #CC11
+antC46=./usecase/mu0_10mhz/ant_14.bin #CC11
+antC47=./usecase/mu0_10mhz/ant_15.bin #CC11
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_10mhz/ant_0.bin
+antPrachC1=./usecase/mu0_10mhz/ant_1.bin
+antPrachC2=./usecase/mu0_10mhz/ant_2.bin
+antPrachC3=./usecase/mu0_10mhz/ant_3.bin
+
+
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=2048
+nULFftSize=2048
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+antC0=./usecase/mu0_20mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_20mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_20mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_20mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_20mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_20mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_20mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_20mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_20mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_20mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_20mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_20mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_20mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_20mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_20mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_20mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#rachCfgIdx=14 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=20 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=2048
+nULFftSize=2048
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+antC0=./usecase/mu0_20mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_20mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_20mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_20mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_20mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_20mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_20mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_20mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_20mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_20mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_20mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_20mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_20mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_20mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_20mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_20mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+prachConfigIndex=189 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+antPrachC0=./usecase/mu0_20mhz/ant_0.bin
+antPrachC1=./usecase/mu0_20mhz/ant_1.bin
+antPrachC3=./usecase/mu0_20mhz/ant_3.bin
+antPrachC4=./usecase/mu0_20mhz/ant_4.bin
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=0 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=512
+nULFftSize=512
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu0_5mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_5mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_5mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_5mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_5mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_5mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_5mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_5mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_5mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_5mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_5mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_5mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_5mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_5mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_5mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_5mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#prachConfigIndex=1 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=0 #15Khz Sub Carrier Spacing
+ttiPeriod=1000 # in us TTI period (15Khz default 1000us)
+nDLAbsFrePointA=2645460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=2525460 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=5 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=512
+nULFftSize=512
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=0 #TDD priod e.g. DDDS 4
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+antC0=./usecase/mu0_5mhz/ant_0.bin #CC0
+antC1=./usecase/mu0_5mhz/ant_1.bin #CC0
+antC2=./usecase/mu0_5mhz/ant_2.bin #CC0
+antC3=./usecase/mu0_5mhz/ant_3.bin #CC0
+antC4=./usecase/mu0_5mhz/ant_4.bin #CC1
+antC5=./usecase/mu0_5mhz/ant_5.bin #CC1
+antC6=./usecase/mu0_5mhz/ant_6.bin #CC1
+antC7=./usecase/mu0_5mhz/ant_7.bin #CC1
+antC8=./usecase/mu0_5mhz/ant_8.bin #CC2
+antC9=./usecase/mu0_5mhz/ant_9.bin #CC2
+antC10=./usecase/mu0_5mhz/ant_10.bin #CC2
+antC11=./usecase/mu0_5mhz/ant_11.bin #CC2
+antC12=./usecase/mu0_5mhz/ant_12.bin #CC3
+antC13=./usecase/mu0_5mhz/ant_13.bin #CC3
+antC14=./usecase/mu0_5mhz/ant_14.bin #CC3
+antC15=./usecase/mu0_5mhz/ant_15.bin #CC3
+
+## RACH TODO: update for PRACH
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+#rachOffset=43 # RB offset for prach detection (see RIU spec)
+#prachConfigIndex=1 # PRACH config index as per TS36.211 - Table 5.7.1-2 : PRACH Configuration Index
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=400 #in us
+T2a_max_cp_dl=1120 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=400 #in us
+T2a_max_cp_ul=1120 #in us
+
+#Reception Window U-plane
+T2a_min_up=200 # in us
+T2a_max_up=1120 # in us
+
+#Transmission Window
+Ta3_min=160 #in us
+Ta3_max=256 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=560
+T1a_max_cp_dl=800
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=480
+T1a_max_cp_ul=560
+
+#U-plane
+##Transmission Window
+T1a_min_up=280
+T1a_max_up=400
+
+#Reception Window
+Ta4_min=0
+Ta4_max=360
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=1 #30Khz Sub Carrier Spacing
+
+ttiPeriod=500 # in us TTI period (30Khz default 500us)
+
+nDLAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=4096
+nULFftSize=4096
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=10 #[0-9] DDDSUUDDDD, for S it\92s 6:4:4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,0,0,0,0,0,2,2,2,2,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig4=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 # RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu1_100mhz/ant_0.bin #CC0
+antC1=./usecase/mu1_100mhz/ant_1.bin #CC0
+antC2=./usecase/mu1_100mhz/ant_2.bin #CC0
+antC3=./usecase/mu1_100mhz/ant_3.bin #CC0
+antC4=./usecase/mu1_100mhz/ant_4.bin #CC1
+antC5=./usecase/mu1_100mhz/ant_5.bin #CC1
+antC6=./usecase/mu1_100mhz/ant_6.bin #CC1
+antC7=./usecase/mu1_100mhz/ant_7.bin #CC1
+antC8=./usecase/mu1_100mhz/ant_8.bin #CC2
+antC9=./usecase/mu1_100mhz/ant_9.bin #CC2
+antC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+rachEanble=1 # Enable (1)| disable (0) PRACH configuration
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 # in us
+ # C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+#Reception Window C-plane DL
+T2a_min_cp_dl=285 # 285.42us
+T2a_max_cp_dl=429 # 428.12us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=285 # 285.42us
+T2a_max_cp_ul=429 # 428.12us
+
+#Reception Window U-plane
+T2a_min_up=71 # 71.35in us
+T2a_max_up=428 # 428.12us
+
+#Transmission Window
+Ta3_min=20 # in us
+Ta3_max=32 # in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=285
+T1a_max_cp_dl=429
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=285
+T1a_max_cp_ul=300
+
+#U-plane
+##Transmission Window
+T1a_min_up=96 #71 + 25 us
+T1a_max_up=196 #71 + 25 us
+
+#Reception Window
+Ta4_min=0 # in us
+Ta4_max=75 # in us
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 4)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=1 #30Khz Sub Carrier Spacing
+
+ttiPeriod=500 # in us TTI period (30Khz default 500us)
+
+nDLAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=3568160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=4096
+nULFftSize=4096
+
+nFrameDuplexType=0 # 0 - FDD 1 - TDD
+nTddPeriod=10 #[0-9] DDDSUUDDDD, for S it\92s 6:4:4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,0,0,0,0,0,2,2,2,2,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig4=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70
+ruMac=00:11:22:33:44:55 # RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu1_100mhz/ant_0.bin #CC0
+antC1=./usecase/mu1_100mhz/ant_1.bin #CC0
+antC2=./usecase/mu1_100mhz/ant_2.bin #CC0
+antC3=./usecase/mu1_100mhz/ant_3.bin #CC0
+antC4=./usecase/mu1_100mhz/ant_4.bin #CC1
+antC5=./usecase/mu1_100mhz/ant_5.bin #CC1
+antC6=./usecase/mu1_100mhz/ant_6.bin #CC1
+antC7=./usecase/mu1_100mhz/ant_7.bin #CC1
+antC8=./usecase/mu1_100mhz/ant_8.bin #CC2
+antC9=./usecase/mu1_100mhz/ant_9.bin #CC2
+antC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+antPrachC0=./usecase/mu1_100mhz/ant_0.bin #CC0
+antPrachC1=./usecase/mu1_100mhz/ant_1.bin #CC0
+antPrachC2=./usecase/mu1_100mhz/ant_2.bin #CC0
+antPrachC3=./usecase/mu1_100mhz/ant_3.bin #CC0
+antPrachC4=./usecase/mu1_100mhz/ant_4.bin #CC1
+antPrachC5=./usecase/mu1_100mhz/ant_5.bin #CC1
+antPrachC6=./usecase/mu1_100mhz/ant_6.bin #CC1
+antPrachC7=./usecase/mu1_100mhz/ant_7.bin #CC1
+antPrachC8=./usecase/mu1_100mhz/ant_8.bin #CC2
+antPrachC9=./usecase/mu1_100mhz/ant_9.bin #CC2
+antPrachC10=./usecase/mu1_100mhz/ant_10.bin #CC2
+antPrachC11=./usecase/mu1_100mhz/ant_11.bin #CC2
+antPrachC12=./usecase/mu1_100mhz/ant_12.bin #CC3
+antPrachC13=./usecase/mu1_100mhz/ant_13.bin #CC3
+antPrachC14=./usecase/mu1_100mhz/ant_14.bin #CC3
+antPrachC15=./usecase/mu1_100mhz/ant_15.bin #CC3
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=1
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 # in us
+ # C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+#Reception Window C-plane DL
+T2a_min_cp_dl=285 # 285.42us
+T2a_max_cp_dl=429 # 428.12us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=285 # 285.42us
+T2a_max_cp_ul=429 # 428.12us
+
+#Reception Window U-plane
+T2a_min_up=71 # 71.35in us
+T2a_max_up=428 # 428.12us
+
+#Transmission Window
+Ta3_min=20 # in us TODO: update
+Ta3_max=32 # in us TODO: update
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=285
+T1a_max_cp_dl=429
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=285
+T1a_max_cp_ul=300
+
+#U-plane
+##Transmission Window
+T1a_min_up=96 #71 + 25 us
+T1a_max_up=196 #71 + 25 us
+
+#Reception Window
+Ta4_min=0 # in us TODO: update
+Ta4_max=75 # in us TODO: update
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=0 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=3 #mmWave 120Khz Sub Carrier Spacing
+ttiPeriod=125 # in us TTI period (mmWave default 125us)
+nDLAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=4 #[0-5] TDD priod e.g. DDDS 4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+# not used
+#sSlotConfig4=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+#ruMac=3c:fd:fe:9e:93:68 #RU PF for tcpdump
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu3_100mhz/ant_0.bin #CC0
+antC1=./usecase/mu3_100mhz/ant_1.bin #CC0
+antC2=./usecase/mu3_100mhz/ant_2.bin #CC0
+antC3=./usecase/mu3_100mhz/ant_3.bin #CC0
+antC4=./usecase/mu3_100mhz/ant_4.bin #CC1
+antC5=./usecase/mu3_100mhz/ant_5.bin #CC1
+antC6=./usecase/mu3_100mhz/ant_6.bin #CC1
+antC7=./usecase/mu3_100mhz/ant_7.bin #CC1
+antC8=./usecase/mu3_100mhz/ant_8.bin #CC2
+antC9=./usecase/mu3_100mhz/ant_9.bin #CC2
+antC10=./usecase/mu3_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu3_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu3_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu3_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu3_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu3_100mhz/ant_15.bin #CC3
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=81
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=1 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=50 #in us
+T2a_max_cp_dl=140 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=50 #in us
+T2a_max_cp_ul=140 #in us
+
+#Reception Window U-plane
+T2a_min_up=25 #in us
+T2a_max_up=140 #in us
+
+#Transmission Window
+Ta3_min=20 #in us
+Ta3_max=32 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=70
+T1a_max_cp_dl=100
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=60
+T1a_max_cp_ul=70
+
+#U-plane
+##Transmission Window
+T1a_min_up=35
+T1a_max_up=50
+
+#Reception Window
+Ta4_min=0
+Ta4_max=45
+###########################################################
+
--- /dev/null
+#######################################################################
+#
+# <COPYRIGHT_TAG>
+#
+#######################################################################
+
+# This is simple configuration file. Use '#' sign for comments
+appMode=1 # lls-CU(0) | RU(1)
+xranMode=0 # Category A (0) (precoder in lls-CU) | Category B (1) (precoder in RU)
+ccNum=1 # Number of Componnent Carriers (CC) per ETH port with XRAN protocol (default:1 max: 12)
+antNum=4 # Number of Antennas per CC (default: 4)
+
+##Numerology
+mu=3 #mmWave 120Khz Sub Carrier Spacing
+ttiPeriod=125 # in us TTI period (mmWave default 125us)
+nDLAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nULAbsFrePointA=27968160 #nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+nDLBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nULBandwidth=100 #Carrier bandwidth for in MHz. Value: 5->400
+nDLFftSize=1024
+nULFftSize=1024
+
+nFrameDuplexType=1 # 0 - FDD 1 - TDD
+nTddPeriod=4 #[0-5] TDD priod e.g. DDDS 4
+sSlotConfig0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig1=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig2=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+sSlotConfig3=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+ #not used
+#sSlotConfig4=0,2,2,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig5=1,1,1,1,1,1,1,1,1,1,1,1,1,1 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig6=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig7=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig8=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+#sSlotConfig9=0,0,0,0,0,0,0,0,0,0,0,0,0,0 # (0) - DL (1) - UL (2) - GUARD
+
+MTUSize=9600 #maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ #xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame)
+
+llsCUMac=00:11:22:33:44:66 # asigned MAC of lls-CU VF
+#llsCUMac=3c:fd:fe:a8:e0:70 #lls-CU PF for tcpdump
+ruMac=00:11:22:33:44:55 #RU VF for RU app
+
+numSlots=40 #number of slots per IQ files
+antC0=./usecase/mu3_100mhz/ant_0.bin #CC0
+antC1=./usecase/mu3_100mhz/ant_1.bin #CC0
+antC2=./usecase/mu3_100mhz/ant_2.bin #CC0
+antC3=./usecase/mu3_100mhz/ant_3.bin #CC0
+antC4=./usecase/mu3_100mhz/ant_4.bin #CC1
+antC5=./usecase/mu3_100mhz/ant_5.bin #CC1
+antC6=./usecase/mu3_100mhz/ant_6.bin #CC1
+antC7=./usecase/mu3_100mhz/ant_7.bin #CC1
+antC8=./usecase/mu3_100mhz/ant_8.bin #CC2
+antC9=./usecase/mu3_100mhz/ant_9.bin #CC2
+antC10=./usecase/mu3_100mhz/ant_10.bin #CC2
+antC11=./usecase/mu3_100mhz/ant_11.bin #CC2
+antC12=./usecase/mu3_100mhz/ant_12.bin #CC3
+antC13=./usecase/mu3_100mhz/ant_13.bin #CC3
+antC14=./usecase/mu3_100mhz/ant_14.bin #CC3
+antC15=./usecase/mu3_100mhz/ant_15.bin #CC3
+
+antPrachC0=./usecase/mu1_100mhz/ant_0.bin #CC0
+antPrachC1=./usecase/mu1_100mhz/ant_1.bin #CC0
+antPrachC2=./usecase/mu1_100mhz/ant_2.bin #CC0
+antPrachC3=./usecase/mu1_100mhz/ant_3.bin #CC0
+
+rachEanble=0 # Enable (1)| disable (0) PRACH configuration
+prachConfigIndex=81
+
+## control of IQ byte order
+iqswap=0 #do swap of IQ before send buffer to eth
+nebyteorderswap=1 #do swap of byte order for each I and Q from CPU byte order to network byte order
+
+##Debug
+debugStop=1 #stop app on 1pps boundary (gps_second % 30)
+debugStopCount=0 #if this value is >0 then stop app after x transmission packets, otherwise app will stop at 1pps boundary
+
+CPenable=0 #(1) C-Plane is enabled| (0) C-Plane is disabled
+c_plane_vlan_tag=1 #VLAN Tag used for C-Plane
+u_plane_vlan_tag=2 #VLAN Tag used for U-Plane
+
+##RU Settings
+Tadv_cp_dl=25 #in us TODO: update per RU implementation
+ #C-Plane messages must arrive at the RU some amount of time in advance (Tcp_adv_dl) of the corresponding U-Plane messages
+
+#Reception Window C-plane DL
+T2a_min_cp_dl=50 #in us
+T2a_max_cp_dl=140 #in us
+
+#Reception Window C-plane UL
+T2a_min_cp_ul=50 #in us
+T2a_max_cp_ul=140 #in us
+
+#Reception Window U-plane
+T2a_min_up=25 #in us
+T2a_max_up=140 #in us
+
+#Transmission Window
+Ta3_min=20 #in us
+Ta3_max=32 #in us
+
+###########################################################
+##lls-CU Settings
+#C-plane
+#Transmission Window Fast C-plane DL
+T1a_min_cp_dl=70
+T1a_max_cp_dl=100
+
+##Transmission Window Fast C-plane UL
+T1a_min_cp_ul=60
+T1a_max_cp_ul=70
+
+#U-plane
+##Transmission Window
+T1a_min_up=35
+T1a_max_up=50
+
+#Reception Window
+Ta4_min=0
+Ta4_max=45
+###########################################################
+
XRAN_FH_LIB_DIR=$XRAN_DIR/lib
XRAN_FH_APP_DIR=$XRAN_DIR/app
+XRAN_FH_TEST_DIR=$XRAN_DIR/test/test_xran
+LIBXRANSO=0
+MLOG=0
+COMMAND_LINE=
-echo 'Building XRAN Library'
-cd $XRAN_FH_LIB_DIR
-make clean; make #DEBUG=1 VERBOSE=1
+echo Number of commandline arguments: $#
+while [[ $# -ne 0 ]]
+do
+key="$1"
-echo 'Building XRAN Test Application'
-cd $XRAN_FH_APP_DIR
-make clean; make #DEBUG=1 VERBOSE=1
+#echo Parsing: $key
+case $key in
+ LIBXRANSO)
+ LIBXRANSO=1
+ ;;
+ MLOG)
+ MLOG=1
+ ;;
+ xclean)
+ COMMAND_LINE+=$key
+ COMMAND_LINE+=" "
+ ;;
+ *)
+ echo $key is unknown command # unknown option
+ ;;
+esac
+shift # past argument or value
+done
+
+if [ -z "$MLOG_DIR" ]
+then
+ echo 'MLOG folder is not set. Disable MLOG (MLOG_DIR='$MLOG_DIR')'
+ MLOG=0
+else
+ echo 'MLOG folder is set. Enable MLOG (MLOG_DIR='$MLOG_DIR')'
+ MLOG=1
+fi
+
+echo 'Building xRAN Library'
+echo "LIBXRANSO = ${LIBXRANSO}"
+echo "MLOG = ${MLOG}"
+
+cd $XRAN_FH_LIB_DIR
+make $COMMAND_LINE MLOG=${MLOG} LIBXRANSO=${LIBXRANSO} #DEBUG=1 VERBOSE=1
+
+echo 'Building xRAN Test Application'
+cd $XRAN_FH_APP_DIR
+make $COMMAND_LINE MLOG=${MLOG} #DEBUG=1 VERBOSE=1
+
+if [ -z ${GTEST_ROOT+x} ];
+then
+ echo "GTEST_ROOT is not set. Unit tests are not compiled";
+else
+ echo 'Building xRAN Test Application ('$GTEST_ROOT')'
+ cd $XRAN_FH_TEST_DIR
+ make clean;
+ make
+fi
#* limitations under the License.
#*
#*******************************************************************************/
-CC := icc
-AR := xiar
+
+
+MYCUSTOMTAB=' '
+MYCUSTOMSPACE='============================================================================================'
+MYCUSTOMSPACE1='------------------------------------------------------------'
+
+##############################################################
+# Tools configuration
+##############################################################
+CC := icc
+CPP := icpc
+AS := as
+AR := ar
+LD := icc
+OBJDUMP := objdump
+
+ifeq ($(SHELL),cmd.exe)
+MD := mkdir.exe -p
+CP := cp.exe -f
+RM := rm.exe -rf
+else
+MD := mkdir -p
+CP := cp -f
+RM := rm -rf
+endif
+
+PROJECT_NAME := libxran
+PROJECT_TYPE := lib
+PROJECT_DIR := $(XRAN_DIR)/lib
+BUILDDIR := ./build
+PROJECT_BINARY := $(BUILDDIR)/$(PROJECT_NAME).a
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
-RTE_TARGET := x86_64-native-linuxapp-icc
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
RTE_INC := $(RTE_SDK)/$(RTE_TARGET)/include
-#include $(RTE_SDK)/mk/rte.vars.mk
-API_DIR := $(PWD)/api
-SRC_DIR := $(PWD)/src
-ETH_DIR := $(PWD)/ethernet
+API_DIR := $(PROJECT_DIR)/api
+SRC_DIR := $(PROJECT_DIR)/src
+ETH_DIR := $(PROJECT_DIR)/ethernet
+ifeq ($(MLOG),1)
ifeq ($(MLOG_DIR),)
MLOG_DIR=$(XRAN_DIR)/../mlog
endif
-
-CFLAGS += -std=gnu11 -Wall -wd9 -Wno-deprecated-declarations -Wextra -Werror -qopt-report-phase:all -qopt-zmm-usage=high \
- -fdata-sections \
- -ffunction-sections \
- -restrict \
- -g \
- -Wall \
- -Wimplicit-function-declaration \
- -Werror \
- -Wextra \
- -no-inline-max-total-size \
- -no-inline-max-size \
- -I$(API_DIR) -I$(ETH_DIR) -I$(MLOG_DIR)/source -I$(RTE_INC) -g -O3
-
-ifeq ($(ME),1)
- CFLAGS += -DMLOG_ENABLED
endif
-SRC = $(ETH_DIR)/ethdi.c \
+
+CC_SRC = $(ETH_DIR)/ethdi.c \
$(ETH_DIR)/ethernet.c \
$(SRC_DIR)/xran_up_api.c \
$(SRC_DIR)/xran_sync_api.c \
$(SRC_DIR)/xran_timer.c \
$(SRC_DIR)/xran_cp_api.c \
- $(SRC_DIR)/xran_transport.c \
+ $(SRC_DIR)/xran_transport.c \
$(SRC_DIR)/xran_common.c \
$(SRC_DIR)/xran_ul_tables.c \
- $(SRC_DIR)/xran_main.c
+ $(SRC_DIR)/xran_frame_struct.c \
+ $(SRC_DIR)/xran_app_frag.c \
+ $(SRC_DIR)/xran_main.c
+
+CPP_SRC = $(SRC_DIR)/xran_compression.cpp
+
+CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
+ -fdata-sections \
+ -ffunction-sections \
+ -g \
+ -Wall \
+ -Wimplicit-function-declaration \
+ -g -O3
+
+CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+ -no-prec-div -fp-model fast=2\
+ -no-prec-sqrt -falign-functions=16 -fast-transcendentals \
+ -Werror -Wno-unused-variable -std=c++11 -mcmodel=large
+
+INC := -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) -I$(RTE_INC)
+DEF :=
+ifeq ($(MLOG),1)
+ INC += -I$(MLOG_DIR)/source
+ DEF += -DMLOG_ENABLED
+else
+ DEF += -UMLOG_ENABLED
+endif
+
+AS_FLAGS :=
+AR_FLAGS := rc
+
+PROJECT_OBJ_DIR := build/obj
-FLEX_C_CRAN_LIB = libxran.a
+CC_OBJS := $(patsubst %.c,%.o,$(CC_SRC))
+CPP_OBJS := $(patsubst %.cpp,%.o,$(CPP_SRC))
+AS_OBJS := $(patsubst %.s,%.o,$(AS_SRC))
+OBJS := $(CC_OBJS) $(CPP_OBJS) $(AS_OBJS) $(LIBS)
+DIRLIST := $(addprefix $(PROJECT_OBJ_DIR)/,$(sort $(dir $(OBJS))))
-OBJ = $(foreach file,$(SRC),$(file:.c=.o))
+CC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CC_OBJS))
+CPP_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS))
+AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
-all: flex_lib install
+CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF)
+CPP_FLAGS_FULL := $(CPP_FLAGS) $(INC) $(DEF)
-$(OBJ): %.o: %.c
- $(CC) $(CFLAGS) -I$(API_DIR) -c $< -o $@
+AS_FLAGS := $(AS_FLAGS) $(INC)
+PROJECT_DEP_FILE := $(PROJECT_OBJ_DIR)/$(PROJECT_NAME).dep
-flex_lib:$(FLEX_C_CRAN_LIB)
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+GENERATE_DEPS :=
+else
-$(FLEX_C_CRAN_LIB): $(OBJ)
- $(AR) rsu $@ $^
+CC_DEPS := $(addprefix __dep__,$(subst ../,__up__,$(CC_SRC)))
+CPP_DEPS := $(addprefix __dep__,$(subst ../,__up__,$(CPP_SRC)))
+GENERATE_DEPS := generate_deps
+endif
+
+all : welcome_line $(PROJECT_BINARY)
+ @echo $(PROJECT_BINARY)
+
+.PHONY : clear_dep
+clear_dep:
+ @$(RM) $(PROJECT_DEP_FILE)
+ @echo [DEP] $(subst $(PROJECT_OBJ_DIR)/,,$(PROJECT_DEP_FILE))
+
+$(CC_DEPS) :
+ @$(CC) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.c,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CC_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+$(CPP_DEPS) :
+ @$(CPP) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.cpp,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CPP_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
+
+.PHONY : generate_deps
+generate_deps : clear_dep $(CC_DEPS) $(CPP_DEPS)
+
+
+.PHONY : echo_start_build
+echo_start_build :
+ @echo [BUILD] $(PROJECT_TYPE) : $(PROJECT_NAME)
+
+$(DIRLIST) :
+ -@$(MD) $@
+
+$(CC_OBJTARGETS) :
+ @echo [CC] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(CC) -c $(CC_FLAGS_FULL) -o"$@" $(patsubst %.o,%.c,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+
+$(CPP_OBJTARGETS) :
+ @echo [CPP] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(CPP) -c $(CPP_FLAGS_FULL) -o"$@" $(patsubst %.o,%.cpp,$(subst $(PROJECT_OBJ_DIR)/,,$@))
-install: $(FLEX_C_CRAN_LIB)
- mkdir -p bin
- @mv $(FLEX_C_CRAN_LIB) ./bin
+$(AS_OBJTARGETS) :
+ @echo [AS] $(subst $(PROJECT_OBJ_DIR)/,,$@)
+ @$(AS) $(AS_FLAGS) -o"$@" $(patsubst %.o,%.s,$(subst $(PROJECT_OBJ_DIR)/,,$@))
+ifeq ($(wildcard $(PROJECT_DEP_FILE)),$(PROJECT_DEP_FILE))
+
+include $(PROJECT_DEP_FILE)
+
+endif
+
+.PHONY: clean xclean
clean:
- @rm -rf $(FLEX_C_CRAN_LIB) $(OBJ) ./bin/$(FLEX_C_CRAN_LIB)
+ @echo [CLEAN] : $(PROJECT_NAME)
+ @$(RM) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+
+xclean: clean
+ifneq ($(wildcard $(PROJECT_DIR)/$(PROJECT_MAKE)),)
+ @echo [XCLEAN] : $(PROJECT_NAME)
+ @$(RM) $(PROJECT_BINARY) $(PROJECT_BINARY_LIB) $(PROJECT_DEP_FILE)
+endif
+
+.PHONY : welcome_line
+welcome_line :
+ @echo $(MYCUSTOMSPACE)
+ @echo Building $(PROJECT_BINARY)
+ @echo $(MYCUSTOMTAB)RTE_TARGET = $(RTE_TARGET)
+ @echo $(MYCUSTOMSPACE)
+
+
+.PHONY : debug release
+
+debug : all
+release : all
-#include $(RTE_SDK)/mk/rte.extlib.mk
+$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+ @echo [AR] $(subst $(BUILDDIR)/,,$@)
+ @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+#pragma once
+#include <stdint.h>
+
+// This configuration file sets global constants and macros which are
+// of general use throughout the project.
+
+// All current IA processors of interest align their cache lines on
+// this boundary. If the cache alignment for future processors changes
+// then the most restrictive alignment should be set.
+constexpr unsigned k_cacheByteAlignment = 64;
+
+// Force the data to which this macro is applied to be aligned on a cache line.
+// For example:
+//
+// CACHE_ALIGNED float data[64];
+#define CACHE_ALIGNED alignas(k_cacheByteAlignment)
+
+// Hint to the compiler that the data to which this macro is applied
+// can be assumed to be aligned to a cache line. This allows the
+// compiler to generate improved code by using aligned reads and
+// writes.
+#define ASSUME_CACHE_ALIGNED(data) __assume_aligned(data, k_cacheByteAlignment);
+
+/// Intel compiler frequently complains about templates not being declared in an external
+/// header. Templates are used throughout this project's source files to define local type-specific
+/// versions of functions. Defining every one of these in a header is unnecessary, so the warnings
+/// about this are turned off globally.
+#pragma warning(disable:1418)
+#pragma warning(disable:1419)
+
+
+namespace BlockFloatCompander
+{
+ /// Compute 32 RB at a time
+ static constexpr int k_numBitsIQ = 16;
+ static constexpr int k_numRB = 16;
+ static constexpr int k_numRE = 12;
+ static constexpr int k_numREReal = k_numRE * 2;
+ static constexpr int k_numSampsExpanded = k_numRB * k_numREReal;
+ static constexpr int k_numSampsCompressed = k_numSampsExpanded + k_numRB;
+ static constexpr int k_iqWidth = 8;
+
+
+ struct CompressedData
+ {
+ /// Compressed data
+ CACHE_ALIGNED int8_t dataCompressed[k_numSampsCompressed];
+ };
+
+ struct ExpandedData
+ {
+ /// Expanded data or input data to compressor
+ CACHE_ALIGNED int16_t dataExpanded[k_numSampsExpanded];
+ };
+
+ void BlockFloatCompress_AVX512(const ExpandedData& dataIn, CompressedData* dataOut);
+
+ void BlockFloatExpand_AVX512(const CompressedData& dataIn, ExpandedData* dataOut);
+
+ void BlockFloatCompress_Basic(const ExpandedData& dataIn, CompressedData* dataOut);
+
+ void BlockFloatExpand_Basic(const CompressedData& dataIn, ExpandedData* dataOut);
+
+}
*
*******************************************************************************/
-
/**
* @brief This file provides the definitions for Control Plane Messages APIs.
*
#ifndef _XRAN_CP_API_H_
#define _XRAN_CP_API_H_
-#include "xran_fh_lls_cu.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "xran_fh_o_du.h"
#include "xran_pkt_cp.h"
+#include "xran_transport.h"
+
+#define XRAN_MAX_SECTIONDB_CTX 2
+
+#define XRAN_MAX_NUM_EXTENSIONS 4 /* Maximum number of extensions in a section */
+#define XRAN_MAX_NUM_UE 16 /* Maximum number of UE */
+#define XRAN_MAX_NUM_ANT_BF 64 /* Maximum number of beamforming antenna,
+ * could be defined as XRAN_MAX_ANTENNA_NR */
+/* Maximum total number of beamforming weights (5.4.7.1.2) */
+#define XRAN_MAX_BFW_N (XRAN_MAX_NUM_ANT_BF*XRAN_MAX_NUM_UE)
+#define XRAN_MAX_MODCOMP_ADDPARMS 2
+
+#define XRAN_SECTIONEXT_ALIGN 4 /* alignment size in byte for section extension */
-/* Error Codes
- * For errors and exceptions, all values will be negative */
-enum xran_errcodes {
- XRAN_ERRCODE_OK = 0,
- XRAN_ERRCODE_INVALIDPARAM,
- XRAN_ERRCODE_OUTOFMEMORY,
- XRAN_ERRCODE_FAILTOSEND,
- XRAN_ERRCODE_INVALIDPACKET,
- XRAN_ERRCODE_MAX
- };
/** Control Plane section types, defined in 5.4 Table 5.1 */
enum xran_cp_sectiontype {
XRAN_SYMBOLNUMBER_INC_MAX
};
+/** Macro to convert the number of PRBs as defined in 5.4.5.6 */
+#define XRAN_CONVERT_NUMPRBC(x) ((x) > 255 ? 0 : (x))
+
+#define XRAN_CONVERT_IQWIDTH(x) ((x) > 15 ? 0 : (x))
+
/** Minimum number of symbols, defined in 5.4.5.7 */
#define XRAN_SYMBOLNUMBER_MIN 1
/** Maximum number of symbols, defined in 5.4.5.7 */
#define XRAN_LBTMODE_PARTIAL34 2
#define XRAN_LBTMODE_FULLSTOP 3
+
+/** Control Plane section extension commands, defined in 5.4.6 Table 5.13 */
+enum xran_cp_sectionextcmd {
+ XRAN_CP_SECTIONEXTCMD_0 = 0, /**< Reserved, for future use */
+ XRAN_CP_SECTIONEXTCMD_1 = 1, /**< Beamforming weights */
+ XRAN_CP_SECTIONEXTCMD_2 = 2, /**< Beamforming attributes */
+ XRAN_CP_SECTIONEXTCMD_3 = 3, /**< DL Precoding configuration parameters and indications, not supported */
+ XRAN_CP_SECTIONEXTCMD_4 = 4, /**< Modulation compression parameter */
+ XRAN_CP_SECTIONEXTCMD_5 = 5, /**< Modulation compression additional scaling parameters */
+ XRAN_CP_SECTIONEXTCMD_MAX /* 6~127 reserved for future use */
+ };
+
+/** Macro to convert bfwIqWidth defined in 5.4.7.1.1, Table 5-15 */
+#define XRAN_CONVERT_BFWIQWIDTH(x) ((x) > 15 ? 0 : (x))
+
+/** Beamforming Weights Compression Method 5.4.7.1.1, Table 5-16 */
+enum xran_cp_bfw_compression_method {
+ XRAN_BFWCOMPMETHOD_NONE = 0, /**< Uncopressed I/Q value */
+ XRAN_BFWCOMPMETHOD_BLKFLOAT = 1, /**< I/Q mantissa value */
+ XRAN_BFWCOMPMETHOD_BLKSCALE = 2, /**< I/Q scaled value */
+ XRAN_BFWCOMPMETHOD_ULAW = 3, /**< compressed I/Q value */
+ XRAN_BFWCOMPMETHOD_BEAMSPACE = 4, /**< beamspace I/Q coefficient */
+ XRAN_BFWCOMPMETHOD_MAX /* reserved for future methods */
+ };
+
+/** Beamforming Attributes Bitwidth 5.4.7.2.1 */
+enum xran_cp_bfa_bitwidth {
+ XRAN_BFABITWIDTH_NO = 0, /**< the filed is no applicable or the default value shall be used */
+ XRAN_BFABITWIDTH_2BIT = 1, /**< the filed is 2-bit bitwidth */
+ XRAN_BFABITWIDTH_3BIT = 2, /**< the filed is 3-bit bitwidth */
+ XRAN_BFABITWIDTH_4BIT = 3, /**< the filed is 4-bit bitwidth */
+ XRAN_BFABITWIDTH_5BIT = 4, /**< the filed is 5-bit bitwidth */
+ XRAN_BFABITWIDTH_6BIT = 5, /**< the filed is 6-bit bitwidth */
+ XRAN_BFABITWIDTH_7BIT = 6, /**< the filed is 7-bit bitwidth */
+ XRAN_BFABITWIDTH_8BIT = 7, /**< the filed is 8-bit bitwidth */
+ };
+
/**
* This structure contains the information to generate the section body of C-Plane message */
struct xran_section_info {
+ uint8_t type; /* type of this section */
/* section type bit- */
/* 0 1 3 5 6 7 length */
- uint16_t id; /* X X X X X 12bits */
- uint8_t rb; /* X X X X X 1bit */
- uint8_t symInc; /* X X X X X 1bit */
- uint16_t startPrbc; /* X X X X X 10bits */
- uint8_t numPrbc; /* X X X X X 8bits */
+ uint8_t startSymId; /* X X X X X X 4bits */
uint8_t numSymbol; /* X X X X 4bits */
+ uint8_t symInc; /* X X X X X 1bit */
+ uint16_t id; /* X X X X X 12bits */
uint16_t reMask; /* X X X X 12bits */
+ uint16_t startPrbc; /* X X X X X 10bits */
+ uint16_t numPrbc; /* X X X X X 8bits */ /* will be converted to zero if >255 */
+ uint8_t rb; /* X X X X X 1bit */
+ uint8_t iqWidth; /* X X X 4bits */
+ uint8_t compMeth; /* X X X 4bits */
+ uint8_t ef; /* X X X X 1bit */
+ int32_t freqOffset; /* X 24bits */
uint16_t beamId; /* X X 15bits */
uint16_t ueId; /* X X 15bits */
uint16_t regFactor; /* X 16bits */
- int32_t freqOffset; /* X 24bits */
- uint8_t ef; /* X X X X 1bit */
-
- uint8_t type; /* type of this section */
uint16_t pad0;
};
+
+struct xran_sectionext1_info {
+ uint16_t bfwNumber; /* number of bf weights in this section */
+ uint8_t bfwiqWidth;
+ uint8_t bfwCompMeth;
+ uint16_t bfwIQ[XRAN_MAX_BFW_N*2]; /* I/Q pair, max 4KB with 16bits, 16UE and 64ANT */
+ union {
+ uint8_t exponent;
+ uint8_t blockScaler;
+ uint8_t compBitWidthShift;
+ uint8_t activeBeamspaceCoeffMask[XRAN_MAX_BFW_N]; /* ceil(N/8)*8, should be multiple of 8 */
+ } bfwCompParam;
+ };
+
+struct xran_sectionext2_info {
+ uint8_t bfAzPtWidth; /* beamforming zenith beamwidth parameter */
+ uint8_t bfAzPt;
+ uint8_t bfZePtWidth; /* beamforming azimuth beamwidth parameter */
+ uint8_t bfZePt;
+ uint8_t bfAz3ddWidth; /* beamforming zenith pointing parameter */
+ uint8_t bfAz3dd;
+ uint8_t bfZe3ddWidth; /* beamforming azimuth pointing parameter */
+ uint8_t bfZe3dd;
+
+ uint8_t bfAzSI;
+ uint8_t bfZeSI;
+ };
+
+struct xran_sectionext3_info { /* NOT SUPPORTED */
+ uint8_t codebookIdx;
+ uint8_t layerId;
+ uint8_t numLayers;
+ uint8_t txScheme;
+ uint16_t crsReMask;
+ uint8_t crsShift;
+ uint8_t crsSymNum;
+ uint16_t beamIdAP1;
+ uint16_t beamIdAP2;
+ uint16_t beamIdAP3;
+ };
+
+struct xran_sectionext4_info {
+ uint8_t csf;
+ uint8_t pad0;
+ uint16_t modCompScaler;
+ };
+
+struct xran_sectionext5_info {
+ uint8_t num_sets;
+ struct {
+ uint16_t csf;
+// uint16_t pad0;
+ uint16_t mcScaleReMask;
+ uint16_t mcScaleOffset;
+ } mc[XRAN_MAX_MODCOMP_ADDPARMS];
+ };
+
+struct xran_sectionext_info {
+ uint16_t type;
+ uint16_t len;
+ void *data;
+ };
+
+
/**
* This structure contains the information to generate the section header of C-Plane message */
struct xran_cp_header_params {
/**
* This structure to hold the information to generate the sections of C-Plane message */
struct xran_section_gen_info {
- struct xran_section_info info; /**< The information for section */
+ struct xran_section_info info; /**< The information for section */
- uint32_t exDataSize;
- /**< Extension or type 6/7 data size, not supported */
- void *exData;
- /*(< The pointer to the extension or type 6/7 data, not supported */
+ uint32_t exDataSize; /**< The number of Extensions or type 6/7 data */
+ /** the array to store section extension */
+ struct {
+ uint16_t type; /**< the type of section extension */
+ uint16_t len; /**< length of extension data */
+ void *data; /**< pointer to extension data */
+ } exData[XRAN_MAX_NUM_EXTENSIONS];
};
/**
/**< Array of the section information */
};
+/**
+ * This structure to hold the information of RB allocation from PHY
+ * to send data for allocated RBs only. */
+struct xran_cp_rbmap_list {
+ uint16_t grp_id; /**< group id for this entry, reserved for future use */
+
+ uint8_t sym_start; /**< Start symbol ID */
+ uint8_t sym_num; /**< Number of symbols */
+
+ uint16_t rb_start; /**< Start RB position */
+ uint16_t rb_num; /**< Number of RBs */
+
+ uint16_t beam_id; /**< Bean Index */
+ uint8_t comp_meth; /**< Compression method */
+ uint8_t pad0;
+ };
+
-uint16_t xran_get_cplength(int cpLength, int uval);
+uint16_t xran_get_cplength(int cpLength);
int32_t xran_get_freqoffset(int freqOffset, int scs);
int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
uint8_t CC_ID, uint8_t Ant_ID,
uint8_t seq_id);
+int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
+ struct xran_cp_gen_params *result,
+ struct xran_recv_packet_info *pkt_info);
+
int xran_cp_init_sectiondb(void *pHandle);
int xran_cp_free_sectiondb(void *pHandle);
int xran_cp_add_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id,
- struct xran_section_info *info);
+ uint8_t ctx_id, struct xran_section_info *info);
+int xran_cp_add_multisection_info(void *pHandle,
+ uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
+ struct xran_cp_gen_params *gen_info);
struct xran_section_info *xran_cp_find_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id,
- uint16_t section_id);
+ uint8_t ctx_id, uint16_t section_id);
struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id, uint32_t *next);
-int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id);
-int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id);
+ uint8_t ctx_id, uint32_t *next);
+int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
+int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* _XRAN_CP_API_H_ */
/**
- * @brief This file provides public interface to XRAN Front Haul layer implementation as defined in the
- * XRAN-FH.CUS.0-v02.00 spec. Implementation is specific to lls-CU node
- * for 5G NR Radio Access technology
+ * @brief This file provides public interface to xRAN Front Haul layer implementation as defined in the
+ * ORAN-WG4.CUS.0-v01.00 spec. Implementation specific to
+ * Lower Layer Split Central Unit (O-DU): a logical node that includes the eNB/gNB functions as
+ * listed in section 2.1 split option 7-2x, excepting those functions allocated exclusively to the O-RU.
+ * The O-DU controls the operation of O-RUs for 5G NR Radio Access technology
*
- * @file xran_fh_lls_cu.h
+ * @file xran_fh_o_du.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
-#ifndef _XRAN_FH_LLS_CU_H_
-#define _XRAN_FH_LLS_CU_H_
+#ifndef _XRAN_FH_O_DU_H_
+#define _XRAN_FH_O_DU_H_
#ifdef __cplusplus
extern "C" {
* parameters supplied. This may be because a particular
* capability is not supported by the current implementation. */
-/** Macro to calculate TTI number [0:7999] from symbol index [0: 112000-1] used by timing thread */
+#define XRAN_STATUS_INVALID_PACKET (-7)
+/**<
+ * @ingroup xran
+ * Recevied packet does not have correct format. */
+
+/** Macro to calculate TTI number from symbol index used by timing thread */
#define XranGetTtiNum(symIdx, numSymPerTti) (((uint32_t)symIdx / (uint32_t)numSymPerTti))
-/** Macro to calculate Symbol number [0:7] for given slot from symbol index [0: 112000-1] */
+/** Macro to calculate Symbol number for given slot from symbol index */
#define XranGetSymNum(symIdx, numSymPerTti) (((uint32_t)symIdx % (uint32_t)numSymPerTti))
-/** Macro to calculate Frame number [0:99] for given tti [0: 7999] */
+/** Macro to calculate Frame number for given tti */
#define XranGetFrameNum(tti,numSubFramePerSystemFrame, numSlotPerSubFrame) ((uint32_t)tti / ((uint32_t)numSubFramePerSystemFrame * (uint32_t)numSlotPerSubFrame))
-/** Macro to calculate Subframe number [0:9] for given tti [0: 7999] */
+/** Macro to calculate Subframe number for given tti */
#define XranGetSubFrameNum(tti, numSlotPerSubFrame, numSubFramePerSystemFrame) (((uint32_t)tti/(uint32_t)numSlotPerSubFrame) % (uint32_t)numSubFramePerSystemFrame)
-/** Macro to calculate Slot number [0:7] for given tti [0: 7999] */
+/** Macro to calculate Slot number */
#define XranGetSlotNum(tti, numSlotPerSfn) ((uint32_t)tti % ((uint32_t)numSlotPerSfn))
-#define XRAN_PORTS_NUM (1) /**< number of XRAN ports supported */
-#define XRAN_N_FE_BUF_LEN (80)/** Number of TTIs (slots) */
-#define XRAN_MAX_SECTOR_NR (4) /**< Max sectors per XRAN port */
-#define XRAN_MAX_ANTENNA_NR (4) /**< Max antenna per port */
-#define XRAN_NUM_OF_SYMBOL_PER_SLOT ( 14 ) /**< Number of symbols per slot */
+#define XRAN_PORTS_NUM (1) /**< number of XRAN ports (aka O-RU devices) supported */
+#define XRAN_N_FE_BUF_LEN (80) /**< Number of TTIs (slots) */
+#define XRAN_MAX_SECTOR_NR (12) /**< Max sectors per XRAN port */
+#define XRAN_MAX_ANTENNA_NR (4) /**< Max antenna per port */
+#define XRAN_NUM_OF_SYMBOL_PER_SLOT (14) /**< Number of symbols per slot */
+#define XRAN_MAX_TDD_PERIODICITY (80) /**< Max TDD pattern period */
+#define XRAN_MAX_CELLS_PER_PORT (XRAN_MAX_SECTOR_NR) /**< Max cells mapped to XRAN port */
+#define XRAN_COMPONENT_CARRIERS_MAX (XRAN_MAX_SECTOR_NR) /**< number of CCs */
+#define XRAN_NUM_OF_ANT_RADIO (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR) /**< Max Number of Antennas supported for all CC on single XRAN port */
+#define XRAN_MAX_PRBS (275) /**< Max of PRBs per CC per antanna for 5G NR */
-#define XRAN_MAX_CELLS_PER_PORT (4) /**< Max cells mapped to XRAN port */
-#define XRAN_COMPONENT_CARRIERS_MAX XRAN_MAX_SECTOR_NR /**< number of CCs */
-#define XRAN_NUM_OF_ANT_RADIO 16 /**< Max Number of Antennas supported for all CC on single XRAN port */
#define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */
#define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */
-#define XRAN_STRICT_PARM_CHECK (1) /**< enable parameter check for C-plane */
+#define XRAN_STRICT_PARM_CHECK (1) /**< enable parameter check for C-plane */
+
+/* Slot type definition */
+#define XRAN_SLOT_TYPE_INVALID (0) /**< invalid slot type */
+#define XRAN_SLOT_TYPE_DL (1) /**< DL slot */
+#define XRAN_SLOT_TYPE_UL (2) /**< UL slot */
+#define XRAN_SLOT_TYPE_SP (3) /**< Special slot */
+#define XRAN_SLOT_TYPE_FDD (4) /**< FDD slot */
+#define XRAN_SLOT_TYPE_LAST (5) /**< MAX slot */
+
+/* symbol type definition */
+#define XRAN_SYMBOL_TYPE_DL (0) /**< DL symbol */
+#define XRAN_SYMBOL_TYPE_UL (1) /**< UL symbol */
+#define XRAN_SYMBOL_TYPE_GUARD (2) /**< GUARD symbol */
+#define XRAN_SYMBOL_TYPE_FDD (3) /**< FDD symbol */
+
+#define XRAN_NUM_OF_SLOT_IN_TDD_LOOP (80)/**< MAX number of slot for TDD repetition */
//#define _XRAN_DEBUG /**< Enable debug log */
//#define _XRAN_VERBOSE /**< Enable verbose log */
__FILE__, \
__LINE__, ##__VA_ARGS__)
+enum XranFrameDuplexType
+{
+ XRAN_FDD = 0, XRAN_TDD
+};
+
+enum xran_if_state
+{
+ XRAN_INIT = 0,
+ XRAN_RUNNING,
+ XRAN_STOPPED
+};
+
/**
******************************************************************************
* @ingroup xran
XRAN_COMPMETHOD_ULAW = 3,
XRAN_COMPMETHOD_MODULATION = 4,
XRAN_COMPMETHOD_MAX
- };
+};
/**
******************************************************************************
XRAN_CB_MAX /**< max number of callbacks */
};
-typedef int32_t XranStatusInt32; /**< Xran status return value */
+typedef int32_t xran_status_t; /**< Xran status return value */
/** callback function type for Symbol packet */
-typedef void (*XRANFHSYMPROCCB)(void*);
+typedef void (*xran_callback_sym_fn)(void*);
/** Callback function type for TTI event */
-typedef int (*XRANFHTTIPROCCB)(void* );
+typedef int (*xran_fh_tti_callback_fn)(void*);
/** Callback function type packet arrival from transport layer (ETH or IP) */
-typedef void (*XranTransportBlockCallbackFn)(void*, int32_t);
+typedef void (*xran_transport_callback_fn)(void*, int32_t);
+
+/** Callback functions to poll BBdev encoder */
+typedef int16_t (*phy_encoder_poll_fn)(void);
+
+/** Callback functions to poll BBdev secoder */
+typedef int16_t (*phy_decoder_poll_fn)(void);
-/**
-* Component Carrier Initialization
-*/
-typedef struct tagXRANCCINIT
-{
- uint32_t RadioMode; /**< XRAN mode Cat A or Cat B on given CC */
- uint32_t nTxAnt; /**< Number of TX antennas */
- uint32_t nRxAnt; /**< Number of RX antennas */
- uint32_t radiobw; /**< bandwidth id */
- uint32_t dpdk_port; /**< networking layer port id */
- char *dpdk_pcie_eth_dev; /**< pcie device for this cc */
- char *ru_mac_str; /**< mac address of RU */
- uint32_t ulAgc; /**< state of UL AGC (ON/OFF) */
- uint32_t numCell; /**< Number of Cells per port per CC */
- uint32_t phyInsId[XRAN_MAX_CELLS_PER_PORT]; /**< Mapping of Cell ID to CC */
- uint32_t dpdkRxCore; /**< DPDK RX Core */
- uint32_t dpdkTxCore; /**< DPDK TX Core */
-}XRANCCINIT, *PXRANCCINIT;
/** XRAN port enum */
enum xran_vf_ports
XRAN_VF_MAX
};
-/** DPDK IO configuration for XRAN layer */
-typedef struct tagXRAN_IO_LOOP_CFG
+/** XRAN category enum */
+enum xran_category
+{
+ XRAN_CATRGORY_A = 0,
+ XRAN_CATRGORY_B = 1,
+ XRAN_CATRGORY_MAX
+};
+
+/** type of beamforming */
+enum xran_beamforming_type
{
- uint8_t id;
- char *dpdk_dev[XRAN_VF_MAX];
- int core;
- int system_core; /* Needed as DPDK will change your starting core. */
- int pkt_proc_core; /* Needed for packet processing thread. */
- int pkt_aux_core; /* Needed for debug purposes. */
- int timing_core; /* Needed for getting precise time */
- int port[XRAN_VF_MAX]; /* This is auto-detected, no need to set. */
-}XRAN_IO_LOOP_CFG, *PXRAN_IO_LOOP_CFG;
+ XRAN_BEAM_ID_BASED = 0, /**< beam index based */
+ XRAN_BEAM_WEIGHT, /**< beam forming weights */
+ XRAN_BEAM_ATTRIBUTE, /**< beam index based */
+};
-/** XRAN spec section 3.1.3.1.6 ecpriRtcid / ecpriPcid define */
-typedef struct tagXRANEAXCIDCONFIG
+/** state of bbdev with xran */
+enum xran_bbdev_init
{
+ XRAN_BBDEV_NOT_USED = -1, /**< BBDEV is disabled */
+ XRAN_BBDEV_MODE_HW_OFF = 0, /**< BBDEV is enabled for SW sim mode */
+ XRAN_BBDEV_MODE_HW_ON = 1, /**< BBDEV is enable for HW */
+ XRAN_BBDEV_MODE_MAX
+};
+
+/** DPDK IO configuration for XRAN layer */
+struct xran_io_cfg {
+ uint8_t id; /**< should be (0) for O-DU or (1) O-RU (debug) */
+ char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */
+ char *bbdev_dev[1]; /**< BBDev dev name */
+ int32_t bbdev_mode; /**< DPDK for BBDev */
+ int32_t core; /**< reservd */
+ int32_t system_core; /**< reservd */
+ int32_t pkt_proc_core; /**< reservd */
+ int32_t pkt_aux_core; /**< reservd */
+ int32_t timing_core; /**< core used by xRAN */
+ int32_t port[XRAN_VF_MAX]; /**< VFs ports */
+};
+
+/** XRAN spec section 3.1.3.1.6 ecpriRtcid / ecpriPcid define */
+struct xran_eaxcid_config {
uint16_t mask_cuPortId; /**< Mask CU PortId */
uint16_t mask_bandSectorId; /**< Mask Band */
uint16_t mask_ccId; /**< Mask CC */
uint8_t bit_cuPortId; /**< bandsectorId + ccId + ruportId */
uint8_t bit_bandSectorId; /**< ccId + ruPortId */
- uint8_t bit_ccId; /**< ruportId */
- uint8_t bit_ruPortId; /**< 0 */
-}XRANEAXCIDCONFIG, *PXRANEAXCIDCONFIG;
+ uint8_t bit_ccId; /**< ruportId */
+ uint8_t bit_ruPortId; /**< 0 */
+};
/**
* XRAN Front haul interface initialization settings
*/
-typedef struct tagXRANFHINIT
-{
- uint32_t llscuId; /**< lls-cu ID */
- uint32_t nSec; /**< number of sectors, shall be 1 */
- XRANCCINIT ccCfg[XRAN_COMPONENT_CARRIERS_MAX]; /**< configuration of each CCs */
- XRANEAXCIDCONFIG eAxCId_conf; /**< config of ecpriRtcid/ecpriPcid */
- uint32_t radio_iface; /**< enable/disable radio */
- uint32_t dpdkMasterCore; /**< master core of DPDK */
- uint32_t dpdkMemorySize; /**< huge pages allocation for DPDK */
- uint32_t dpdkIrqMode; /**< DPDK IRQ or PMD mode */
+struct xran_fh_init {
+ struct xran_io_cfg io_cfg;/**< DPDK IO for XRAN */
+ struct xran_eaxcid_config eAxCId_conf; /**< config of ecpriRtcid/ecpriPcid */
+
uint32_t dpdkBasebandFecMode; /**< DPDK Baseband FEC device mode (0-SW, 1-HW) */
char *dpdkBasebandDevice; /**< DPDK Baseband device address */
- uint32_t singleThreadTxRx;
- uint32_t bbuPoolCores; /**< DPDK cores for BBU pool */
- uint32_t radioEnabled; /**< reserved */
- uint32_t powerSaveEn; /**< reserved */
- char *filePrefix; /**< DPDK prefix */
- XRAN_IO_LOOP_CFG io_cfg;/**< DPDK IO for XRAN */
- uint8_t xranMode; /**< mode: lls-CU or RU */
- int8_t *p_lls_cu_addr; /**< lls-CU Ethernet Mac Address */
- int8_t *p_ru_addr; /**< RU Ethernet Mac Address */
- uint32_t ttiPeriod; /**< TTI period */
+ char *filePrefix; /**< DPDK prefix */
+
+ enum xran_category xranCat; /**< mode: Catergory A or Category B */
+
+ uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
+ xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
+ int8_t *p_o_du_addr; /**< O-DU Ethernet Mac Address */
+ int8_t *p_o_ru_addr; /**< O-RU Ethernet Mac Address */
uint16_t Tadv_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_min_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta4_min; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta4_max; /**< Table 2 7 : xRAN Delay Management Model Parameters */
- uint8_t enableCP; /**< enable C-plane */
- uint8_t cp_vlan_tag; /**< C-plane vlan tag */
- uint8_t up_vlan_tag; /**< U-plane vlan tag */
- int32_t debugStop; /**< enable auto stop */
-} XRANFHINIT, *PXRANFHINIT;
+ uint8_t enableCP; /**< enable C-plane */
+ uint8_t prachEnable; /**< enable PRACH */
+ uint8_t cp_vlan_tag; /**< C-plane vlan tag */
+ uint8_t up_vlan_tag; /**< U-plane vlan tag */
+ int32_t debugStop; /**< enable auto stop */
+ int32_t debugStopCount; /**< enable auto stop after number of Tx packets */
+ int32_t DynamicSectionEna; /**< enable dynamic C-Plane section allocation */
+};
-/** XRAN Playback format */
-typedef enum {
- XRAN_RADIO_PLAYBACK_TIME_DOMAIN = 0,
- XRAN_RADIO_PLAYBACK_FREQ_DOMAIN = 1
-} XranPlaybackFormatEnum;
+struct xran_cp_bf_weight{
+ int16_t weight[64];
+};
+struct xran_cp_bf_attribute{
+ int16_t weight[4];
+};
+struct xran_cp_bf_precoding{
+ int16_t weight[4];
+};
+
+/** PRB element structure */
+struct xran_prb_elm {
+ int16_t nRBStart; /**< start RB of RB allocation */
+ int16_t nRBSize; /**< number of RBs used */
+ int16_t nStartSymb; /**< start symbol ID */
+ int16_t numSymb; /**< number of symbol */
+ int16_t nBeamIndex; /**< beam index for given PRB */
+ int16_t compMethod; /**< compression index for given PRB */
+ int16_t BeamFormingType;
+ union {
+ struct xran_cp_bf_attribute bf_attribute;
+ struct xran_cp_bf_precoding bf_precoding;
+ };
+};
+
+/** PRB map structure */
+struct xran_prb_map {
+ uint8_t dir; /**< DL or UL direction */
+ uint8_t xran_port; /**< xran id of given RU [0-(XRAN_PORTS_NUM-1)] */
+ uint16_t band_id; /**< xran band id */
+ uint16_t cc_id; /**< componnent carrier id [0 - (XRAN_MAX_SECTOR_NR-1)] */
+ uint16_t ru_port_id; /**< RU device antenna port id [0 - (XRAN_MAX_ANTENNA_NR-1) */
+ uint16_t tti_id; /**< xRAN slot id [0 - (max tti-1)] */
+ uint8_t start_sym_id; /**< start symbol Id [0-13] */
+ uint8_t bf_weight_update; /**need to update beam weight or not*/
+ uint32_t nPrbElm; /**< total number of PRBs for given map [0- (XRAN_MAX_PRBS-1)] */
+ struct xran_prb_elm prbMap[XRAN_MAX_PRBS];
+ struct xran_cp_bf_weight bf_weight;
+};
/* PRACH config required for XRAN based FH */
-typedef struct tagXRANPRACHCONFIG
+struct xran_prach_config
{
- /**** word 5 *****/
/* PRACH config*/
- /** PRACH Configuration Index*/
- uint8_t nPrachConfIdx;
- /** PRACH Sub-carrier spacing
+ uint8_t nPrachConfIdx; /**< PRACH Configuration Index*/
+ uint8_t nPrachSubcSpacing;
+ /**< PRACH Sub-carrier spacing
Value:0->1
For below 6GHz the values indicate 15kHz or 30kHz
For above 6GHz the values indicate 60kHz or 120kHz*/
- /*PRACH zeroCorrelationZoneConfig */
- uint8_t nPrachSubcSpacing;
- /** PRACH zeroCorrelationZoneConfig */
- uint8_t nPrachZeroCorrConf;
- /** PRACH restrictedSetConfig */
- uint8_t nPrachRestrictSet;
-
- /**** word 6 *****/
- /** PRACH Root Sequence Index */
- uint16_t nPrachRootSeqIdx;
- /** PRACH prach-frequency-start */
- uint16_t nPrachFreqStart;
-
- /** PRACH prach-frequency-offset */
- int32_t nPrachFreqOffset;
- /** PRACH Filter index */
- uint8_t nPrachFilterIdx;
-}XRANPRACHCONFIG, *PXRANPRACHCONFIG;
-
-/** XRAN front haul playback configuration (not supported in 19.03) */
-typedef struct tagXRANFHPLAYBACK
-{
- XranPlaybackFormatEnum TxPlayFormatType; /**< type of play back files [Time|Freq] */
-
- unsigned long TxPlayBufAddr[XRAN_NUM_OF_ANT_RADIO]; /**< pointer to buffers to play */
- uint32_t TxPlayBufSize; /**< Buffer size */
-
- char* TxPlayFileName[XRAN_NUM_OF_ANT_RADIO]; /**< files to play */
- uint32_t TxPlayFileSize; /**< expected the same size for all Ant */
-
-}XRANPLAYBACKCONFIG,*PXRANPLAYBACKCONFIG;
-
-/** XRAN front haul logging configuration (not supported in 19.03) */
-typedef struct tagXRANFHLOGCONF
-{
- /* logging */
- unsigned long TxLogBufAddr;
- uint32_t TxLogBufSize;
-
- unsigned long TxLogIfftInAddr;
- uint32_t TxLogIfftInSize;
-
- unsigned long TxLogIfft1200InAddr;
- uint32_t TxLogIfft1200InSize;
-
- unsigned long RxLogFftOutAddr;
- uint32_t RxLogFftOutSize;
-
- unsigned long RxLogFftOutExpAddr;
- uint32_t RxLogFftOutExpSize;
-
- unsigned long RxLogFftOutGainAddr;
- uint32_t RxLogFftOutGainSize;
-
- unsigned long RxLogBufAddr;
- uint32_t RxLogBufSize;
-
- unsigned long RxLogAlawBufAddr;
- uint32_t RxLogAlawBufSize;
+ uint8_t nPrachZeroCorrConf; /**< PRACH zeroCorrelationZoneConfig */
+ uint8_t nPrachRestrictSet; /**< PRACH restrictedSetConfig */
+ uint16_t nPrachRootSeqIdx; /**< PRACH Root Sequence Index */
+ uint16_t nPrachFreqStart; /**< PRACH prach-frequency-start */
+ int32_t nPrachFreqOffset; /**< PRACH prach-frequency-offset */
+ uint8_t nPrachFilterIdx; /**< PRACH Filter index */
+};
- unsigned long RxLogPrachBufAddr;
- uint32_t RxLogPrachBufSize;
+/** XRAN slot configuration */
+struct xran_slot_config {
+ uint8_t nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT]; /**< Defines the Symbol type for all 14 symbols in a slot. 0: DL, 1: UL, 2: Guard */
+ uint8_t reserved[2];
+};
- uint32_t cfg_dl_iq_buf_enabled;
- uint32_t cfg_ul_iq_buf_enabled;
+/** XRAN front haul frame config */
+struct xran_frame_config {
+ uint8_t nFrameDuplexType; /**< Frame Duplex type: 0 -> FDD, 1 -> TDD */
+ uint8_t nNumerology; /**< Numerology, determine sub carrier spacing, Value: 0->4
+ 0: 15khz, 1: 30khz, 2: 60khz
+ 3: 120khz, 4: 240khz */
+ uint8_t nTddPeriod; /**< TDD period */
+ struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
+ /**< TDD Slot configuration - If nFrameDuplexType = TDD(1), then this config defines the slot config type for each slot.*/
+ /* The number of slots need to be equal to nTddPeriod */
+};
-}XRANFHLOGCONF, *PXRANFHLOGCONF;
+/** XRAN-PHY interface byte order */
+enum xran_input_byte_order {
+ XRAN_NE_BE_BYTE_ORDER = 0, /**< Network byte order (Big endian), xRAN lib doesn't do swap */
+ XRAN_CPU_LE_BYTE_ORDER /**< CPU byte order (Little endian), xRAN lib does do swap */
+};
-/** XRAN front haul frame config */
-typedef struct tagXRANFRAMECONFIG
-{
- /** Frame Duplex type: 0 -> FDD, 1 -> TDD */
- uint8_t nFrameDuplexType;
- /** Numerology, determine sub carrier spacing, Value: 0->4
- 0: 15khz, 1: 30khz, 2: 60khz
- 3: 120khz, 4: 240khz */
- uint8_t nNumerology;
- /** TDD period */
- uint8_t nTddPeriod;
-}XRANFRAMECONFIG, *PXRANFRAMECONFIG;
-
-/** XRAN front haul BBU pooling config */
-typedef struct tagXRANBBUPOOLCONFIG
-{
- uint32_t isBbuPool; /**< FH running with BBU pool */
-}XRANBBUPOOLCONFIG, *PXRANBBUPOOLCONFIG;
+/** XRAN-PHY interface I and Q order */
+enum xran_input_i_q_order {
+ XRAN_I_Q_ORDER = 0, /**< I , Q */
+ XRAN_Q_I_ORDER /**< Q , I */
+};
/** XRAN front haul IQ compression settings */
-typedef struct tagXRANRUCONFIG
-{
+struct xran_ru_config {
uint8_t iqWidth; /**< IQ bit width */
uint8_t compMeth; /**< Compression method */
uint8_t fftSize; /**< FFT Size */
-}XRANRUCONFIG, *PXRANRUCONFIG;
-
-/** XRAN front haul Phase compensation settings */
-typedef struct
-{
- uint32_t nSecNum;
- uint32_t nPhaseCompFlag;
- uint32_t nDlArfcn[XRAN_MAX_SECTOR_NR];
- uint32_t nUlArfcn[XRAN_MAX_SECTOR_NR];
-}XRANPHASECompConfig;
+ enum xran_input_byte_order byteOrder; /**< Order of bytes in int16_t in buffer. Big or little endian */
+ enum xran_input_i_q_order iqOrder; /**< order of IQs in the buffer */
+};
/**
* @ingroup xran
- *XRAN front haul general configuration */
-typedef struct tagXRANFHCONFIG
-{
+ * XRAN front haul general configuration */
+struct xran_fh_config {
uint32_t dpdk_port; /**< DPDK port number used for FH */
uint32_t sector_id; /**< Band sector ID for FH */
uint32_t nCC; /**< number of Component carriers supported on FH */
- uint32_t neAxc; /**< number of eAxc supported on FH */
- XRANPLAYBACKCONFIG playback_conf;/**< configuration of playback of IQs supported with FH */
- XRANFHLOGCONF log_conf; /**< config of logging functionality supported by FH */
- XRANFHTTIPROCCB ttiCb; /**< call back for TTI event */
+ uint32_t neAxc; /**< number of eAxc supported on one CC*/
+ uint16_t nDLFftSize; /**< DL FFT size */
+ uint16_t nULFftSize; /**< UL FFT size */
+ uint16_t nDLRBs; /**< DL PRB */
+ uint16_t nULRBs; /**< UL PRB */
+ uint32_t nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+ uint32_t nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
+ uint32_t nDLCenterFreqARFCN; /**< center frerquency for DL in MHz */
+ uint32_t nULCenterFreqARFCN; /**< center frerquency for UL in MHz */
+ xran_fh_tti_callback_fn ttiCb; /**< call back for TTI event */
void *ttiCbParam; /**< parameters of call back function */
- XRANPRACHCONFIG prach_conf; /**< PRACH specific configurations for FH */
- XRANFRAMECONFIG frame_conf; /**< frame config */
- XRANBBUPOOLCONFIG bbu_conf; /**< BBU pool config */
- XRANRUCONFIG ru_conf; /**< config of RU as per XRAN spec */
- XRANPHASECompConfig phase_compensation; /**< phase compensation settings */
-}XRANFHCONFIG, *PXRANFHCONFIG;
+ struct xran_prach_config prach_conf; /**< PRACH specific configurations for FH */
+ struct xran_frame_config frame_conf; /**< frame config */
+ struct xran_ru_config ru_conf; /**< config of RU as per XRAN spec */
+
+ phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
+ phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
+
+ uint32_t log_level; /**< configuration of log level */
+};
+
+/**
+ * @ingroup xran
+ * XRAN front haul statistic counters according to Table 7 1 : Common Counters for both DL and UL */
+struct xran_common_counters{
+ uint64_t Rx_on_time; /**< Data was received on time (applies to user data reception window) */
+ uint64_t Rx_early; /**< Data was received too early (applies to user data reception window) */
+ uint64_t Rx_late; /**< Data was received too late (applies to user data reception window) */
+ uint64_t Rx_corrupt; /**< Corrupt/Incorrect header packet */
+ uint64_t Rx_pkt_dupl; /**< Duplicated packet */
+ uint64_t Total_msgs_rcvd; /**< Total messages received (on all links) */
+};
/**
* @ingroup xran
* CC instance handle pointer type */
-typedef void * XranCcInstanceHandleVoidP;
+typedef void * xran_cc_handle_t;
/**
*****************************************************************************
* buffer segment may contain several equally sized elements.
*
*****************************************************************************/
-typedef struct XRANFlatBuffer
+struct xran_flat_buffer
{
uint32_t nElementLenInBytes;
/**< The Element length specified in bytes.
/**< The data pointer is a virtual address, however the actual data pointed
* to is required to be in contiguous physical memory unless the field
requiresPhysicallyContiguousMemory in CpaInstanceInfo is false. */
-} XRANFlatBufferStruct;
+ void *pCtrl;
+ /**< pointer to control section coresponding to data buffer */
+};
/**
*****************************************************************************
* the pPrivateMetaData memory.
*
*****************************************************************************/
-typedef struct XRANBufferList
+struct xran_buffer_list
{
uint32_t nNumBuffers;
/**< Number of pointers */
- XRANFlatBufferStruct *pBuffers;
+ struct xran_flat_buffer *pBuffers;
/**< Pointer to an unbounded array containing the number of CpaFlatBuffers
* defined by nNumBuffers */
void *pUserData;
* cpaCyBufferListGetMetaSize. If cpaCyBufferListGetMetaSize returns a size
* of zero no memory needs to be allocated, and this parameter can be NULL.
*/
-} XRANBufferListStruct;
+};
/**
* @ingroup xran
* 0 - on success
* Error codes returned via rte_errno
*/
-int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle);
+int32_t xran_init(int argc, char *argv[], struct xran_fh_init *p_xran_fh_init, char *appName, void ** pHandle);
/**
* @ingroup xran
* @param nNumInstances
* total number of instances of CC
* @param pSectorInstanceHandles
- * Pointer to XranCcInstanceHandleVoidP where to store Handle pointer
+ * Pointer to xran_cc_handle_t where to store Handle pointer
*
* @return
* 0 - on success
*/
int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
- XranCcInstanceHandleVoidP * pSectorInstanceHandles);
+ xran_cc_handle_t * pSectorInstanceHandles);
/**
* @ingroup xran
* Pointer to XRAN layer handle for given CC
* @param nPoolIndex
* buffer pool identification
- * @param ppVirtAddr
+ * @param ppData
* Pointer to pointer where to store address of new buffer
+ * @param ppCtrl
+ * Pointer to pointer where to store address of internal private control information
+ *
*
* @return
* 0 - on success
*/
-int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr);
+int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl);
/**
* @ingroup xran
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
- * @param pVirtAddr
+ * @param pData
* Pointer to buffer
+ * @param pData
+ * Pointer to internal private control information
*
* @return
* 0 - on success
*/
-int32_t xran_bm_free_buffer(void * pHandle, void *pVirtAddr);
+int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl);
/**
* @ingroup xran
* Pointer to XRAN layer handle for given CC
* @param pSrcBuffer
* list of memory buffers to use to fetch IQs from PHY to XRAN layer (DL)
+ * @param pSrcCpBuffer
+ * list of memory buffers to use to configure C-plane (DL)
* @param pDstBuffer
* list of memory buffers to use to deliver IQs from XRAN layer to PHY (UL)
- * @param XranTransportBlockCallbackFn pCallback
+ * @param pDstCpBuffer
+ * list of memory buffers to use to configure C-plane (UL)
+ * @param xran_transport_callback_fn pCallback
* Callback function to call with arrival of all packets for given CC for given symbol
* @param pCallbackTag
* Parameters of Callback function
* 0 - on success
* -1 - on error
*/
-int32_t xran_5g_fronthault_config (void * pHandle,
- XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XranTransportBlockCallbackFn pCallback,
- void *pCallbackTag);
+ int32_t xran_5g_fronthault_config (void * pHandle,
+ struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ xran_transport_callback_fn pCallback,
+ void *pCallbackTag);
/**
* @ingroup xran
* Pointer to XRAN layer handle for given CC
* @param pDstBuffer
* list of memory buffers to use to deliver PRACH IQs from xran layer to PHY
- * @param XranTransportBlockCallbackFn pCallback
+ * @param xran_transport_callback_fn pCallback
* Callback function to call with arrival of PRACH packets for given CC
* @param pCallbackTag
* Parameters of Callback function
* -1 - on error
*/
int32_t xran_5g_prach_req (void * pHandle,
- XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XranTransportBlockCallbackFn pCallback,
+ struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ xran_transport_callback_fn pCallback,
void *pCallbackTag);
-/**
- * @ingroup xran
- *
- * Function configures phase compensation for RU via XRAN layer with given handle
- *
- * @param pHandle
- * Pointer to XRAN layer handle for given CC
- * @param nTxPhaseCps
- * TX(DL) phase compensation settings
- * @param nTxPhaseCps
- * RX(UL) phase compensation settings
- * @param nSectorId
- * Sector id to use with given settings
- *
- * @return
- * 0 - on success
- */
-int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
- uint32_t nTxPhaseCps,
- uint32_t nRxPhaseCps,
- uint8_t nSectorId);
/**
* @ingroup xran
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
- * @param PXRANFHCONFIG pConf
+ * @param pointer to struct xran_fh_config pConf
* Pointer to XRAN configuration structure with specific settings to use
*
* @return
* 0 - on success
*/
-int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf);
+int32_t xran_open(void *pHandle, struct xran_fh_config* pConf);
/**
* @ingroup xran
* 0 - in case of success
* -1 - in case of failure
*/
-int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb, uint8_t ant);
+int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant);
/**
* @ingroup xran
* 0 - in case of success
* -1 - in case of failure
*/
-int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id);
+int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id);
/**
* @ingroup xran
*/
int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond);
+/**
+ * @ingroup xran
+ *
+ * Function retrun XRAN layer common counters for given handle
+ *
+ * @param pHandle
+ * Pointer to XRAN layer handle for given CC
+ *
+ * @param pStats
+ * Pointer to pointer of common counter structure
+ *
+ * @return
+ * 0 - on success
+ */
+int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats);
+
+enum xran_if_state xran_get_if_state(void);
+
+
#ifdef __cplusplus
}
#endif
-#endif /* _XRAN_FH_LLS_CU_H_*/
+#endif /* _XRAN_FH_O_DU_H_*/
*
*******************************************************************************/
-#ifndef _MLOG_LNX_XRAN_H_
-#define _MLOG_LNX_XRAN_H_
+
+#ifndef _XRAN_MLOG_LNX_H_
+#define _XRAN_MLOG_LNX_H_
#ifdef __cplusplus
extern "C"
{
#endif
+#ifdef MLOG_ENABLED
+#include <mlog_lnx.h>
+#else
+
+/* stubs for MLOG functions */
#define MLOG_FALSE ( 0 )
#define MLogOpen(a, b, c, d, e) MLOG_FALSE
#define MLogAddTestCase(a, b) MLOG_FALSE
#define MLogAddPowerStats(a, b, c, d, e) MLOG_FALSE
+#endif /* MLOG_ENABLED */
+
#ifdef __cplusplus
}
#endif /* #ifdef __cplusplus */
-#endif /* #ifndef _MLOG_LNX_H_ */
+#endif /* #ifndef _XRAN_MLOG_LNX_H_ */
*
*******************************************************************************/
-
/**
* @brief Definitions and support functions to process XRAN packet
* @file xran_pkt.h
* @author Intel Corporation
**/
-/* XRAN-FH.CUS.0-v02.01.03 xRAN Front haul Working Group Control, User and Synchronization Plane Specification */
+/* ORAN-WG4.CUS.0-v01.00 O-RAN Fronthaul Working Group
+ Control, User and Synchronization Plane Specification
+*/
/*
* Layer common to data and control packets
#ifndef _XRAN_PKT_H_
#define _XRAN_PKT_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <rte_common.h>
#include <rte_ether.h>
#include <rte_byteorder.h>
-
/**
*****************************************************************************
* @file xran_pkt.h
*****************************************************************************/
struct ecpri_seq_id
{
- uint8_t seq_id:8; /**< Sequence ID */
- uint8_t sub_seq_id:7; /**< Subsequence ID */
- uint8_t e_bit:1; /**< E bit */
+ uint8_t seq_id:8; /**< Sequence ID */
+ uint8_t sub_seq_id:7; /**< Subsequence ID */
+ uint8_t e_bit:1; /**< E bit */
} __rte_packed;
* Structure holds common eCPRI header as per
* Table 3 1 : eCPRI Transport Header Field Definitions
*****************************************************************************/
-struct xran_ecpri_hdr
+struct xran_ecpri_cmn_hdr
{
- uint8_t ecpri_concat:1; /**< This parameter indicates when eCPRI concatenation is in use
- (allowing multiple eCPRI messages in a single Ethernet payload).
- NOTE: This parameter is part of the eCPRI common header. */
- uint8_t ecpri_resv:3; /**< This parameter is reserved for eCPRI future use.
- NOTE: This parameter is part of the eCPRI common header. */
- uint8_t ecpri_ver:4; /**< This parameter indicates the eCPRI protocol version.
- NOTE: This parameter is part of the eCPRI common header. */
- uint8_t ecpri_mesg_type:8; /**< This parameter indicates the type of service conveyed by
- the message type. NOTE: This parameter is part of the eCPRI
- common header. NOTE: In this version of the specification,
- only values "0000 0000b" and "0000 0010b" and "0000 0101b" are used. */
- rte_be16_t ecpri_payl_size:16; /**< This parameter is the size in bytes of the payload part
- of the corresponding eCPRI message. It does not include any padding bytes
- following the eCPRI message. The maximum supported payload size is 216-1,
- but the actual size may be further limited by the maximum payload size of
- the underlying transport network. NOTE: This parameter is part of the
- eCPRI common header. */
-
- rte_be16_t ecpri_xtc_id; /**< 3.1.3.1.6 This parameter is a component_eAxC identifier (c_eAxC ID) and
- identifies the specific data flow associated with each C-Plane (ecpriRtcid) or
- U-Plane (ecpriPcid) message. It is the analog of CPRI's "AxC" (antenna-carrier)
- value so is designated here as "eAxC" ("e" for "extended" to accommodate multiple
- bands and multiple component carriers). In addition, the "eAxC" is divided into
- "component eAxC" parts (c_eAxC) because multiple lls-CU processors may contribute
- to a single eAxC and must be identified for correct data routing. */
-
- struct ecpri_seq_id ecpri_seq_id; /**< This parameter provides unique message identification and ordering on
- two different levels. The first octet of this parameter is the Sequence ID, which is used to identify ordering of
- messages within an eAxC message stream. The Sequence ID field increments and wraps independently for each U-Plane
- eAxC DL, U-Plane eAxC UL, C-Plane eAxC DL, and C-Plane eAxC UL, even if they share the same eAxC ID.
- The Sequence ID is used to verify that all messages are received and also to reorder messages that are received out of order.
- The second octet of this parameter is the Subsequence ID. The Subsequence ID is used to verify ordering and implement
- reordering when radio-transport-level (eCPRI or IEEE-1914.3) fragmentation occurs.
- Radio-transport (eCPRI or IEEE-1914.3) fragmentation is a method of splitting U-plane messages containing one or
- more sections whose length exceeds the maximum packet or message length of the underlying protocol.
- The Subsequence ID field consists of a 7 bit Subsequence counter and a single bit field, called E-bit.
- The Subsequence number increments starting from zero for each fragment of a U-plane message. The E bit
- is used to indicate the last message of the radio-transport level fragments. It is always set to zero
- except for the last message of the U-plane fragment. In the case of C-plane messages radio-transport
- fragmentation is not allowed, therefore the Subsequence ID shall be set to zero, and the E bit set to one.
- See Section 3.1.4 for a description of the fragmentation process.
- NOTE: As an alternative to radio-transport-level fragmentation, application fragmentation can be implemented.
- In this case the application can take the responsibility to ensure all transport messages are not too long
- (fit within the necessary transport payload size). When this "application layer fragmentation" is used,
- the subsequence identifier shall always be set to "0", and the E-bit set to "1" (See Section 3.1.4). */
-
+ uint8_t ecpri_concat:1; /**< 3.1.3.1.3 eCPRI concatenation indicator */
+ uint8_t ecpri_resv:3; /**< 3.1.3.1.2 eCPRI reserved */
+ uint8_t ecpri_ver:4; /**< 3.1.3.1.1 eCPRI protocol revision, defined in XRAN_ECPRI_VER */
+ uint8_t ecpri_mesg_type; /**< 3.1.3.1.4 eCPRI message type, defined in ecpri_msg_type */
+ uint16_t ecpri_payl_size; /**< 3.1.3.1.5 eCPRI payload size, without common header and any padding bytes */
} __rte_packed;
/**
* @ingroup xran_common_pkt
*
* @description
- * Structure holds complete xran packet header
- * 3.1.1 Ethernet Encapsulation
+ * Structure holds eCPRI transport header as per
+ * Table 3 1 : eCPRI Transport Header Field Definitions
*****************************************************************************/
-struct xran_pkt_hdr
+struct xran_ecpri_hdr
{
- struct ether_hdr eth_hdr; /**< Ethernet Header */
- struct vlan_hdr vlan_hdr; /**< VLAN Header */
- struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
-};
+ struct xran_ecpri_cmn_hdr cmnhdr;
+ rte_be16_t ecpri_xtc_id; /**< 3.1.3.1.6 real time control data / IQ data transfer message series identifier */
+ struct ecpri_seq_id ecpri_seq_id; /**< 3.1.3.1.7 message identifier */
+} __rte_packed;
+
/**
******************************************************************************
*/
} __rte_packed;
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ * Structure holds common xran packet header
+ * 3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct xran_pkt_comm_hdr
+{
+ struct ether_hdr eth_hdr; /**< Ethernet Header */
+ struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
*
*******************************************************************************/
-
/**
* @brief This file provides the definition of Control Plane Messages
* for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
#ifndef _XRAN_PKT_CP_H_
#define _XRAN_PKT_CP_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**********************************************************************
* Common structures for C/U-plane
* Section headers definition for C-Plane.
* Section type 6 and 7 are not present since those have different fields.
*/
-struct xran_cp_radioapp_section_header { // 8bytes, need the conversion for byte order
+struct xran_cp_radioapp_section_header { /* 8bytes, need the conversion for byte order */
union {
struct {
uint32_t reserved:16;
} s5;
} u;
- uint32_t numPrbc:8; /**< 5.4.5.6 number of contiguous PRBs per control section */
+ uint32_t numPrbc:8; /**< 5.4.5.6 number of contiguous PRBs per control section 0000 0000b = all PRBs */
uint32_t startPrbc:10; /**< 5.4.5.4 starting PRB of control section */
uint32_t symInc:1; /**< 5.4.5.3 symbol number increment command XRAN_SYMBOLNUMBER_xxxx */
uint32_t rb:1; /**< 5.4.5.2 resource block indicator, XRAN_RBIND_xxx */
} __attribute__((__packed__));
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * Beamforming Weights Extension Type(ExtType 1) defined in 5.4.7.1
+ * The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext1 {
+ /* variable length, need to be careful to convert byte order
+ * - does not need to convert first 3 bytes */
+ uint8_t extType:7; /**< 5.4.6.1 extension type */
+ uint8_t ef:1; /**< 5.4.6.2 extension flag */
+ uint8_t extLen; /**< 5.4.6.3 extension length, in 32bits words */
+ uint8_t bfwCompMeth:4; /**< 5.4.7.1.1 Beamforming weight Compression method */
+ uint8_t bfwIqWidth:4; /**< 5.4.7.1.1 Beamforming weight IQ bit width */
+
+ /*
+ * would be better to use bit manipulation directly to add these parameters
+ *
+ * bfwCompParam
+ * (bfwI, bfwQ)+
+ * ......
+ * padding for 4-byte alignment
+ */
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * Beamforming Attributes Extension Type(ExtType 2) defined in 5.4.7.2
+ * The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext2 {
+ /* variable length, need to be careful to convert byte order
+ * - first 4 bytes can be converted at once
+ */
+ uint32_t bfZe3ddWidth:3; /**< 5.4.7.2.1 beamforming zenith beamwidth parameter bitwidth, Table 5-21 */
+ uint32_t bfAz3ddWidth:3; /**< 5.4.7.2.1 beamforming azimuth beamwidth parameter bitwidth, Table 5-20 */
+ uint32_t bfaCompResv1:2;
+ uint32_t bfZePtWidth:3; /**< 5.4.7.2.1 beamforming zenith pointing parameter bitwidth, Table 5-19 */
+ uint32_t bfAzPtWidth:3; /**< 5.4.7.2.1 beamforming azimuth pointing parameter bitwidth, Table 5-18 */
+ uint32_t bfaCompResv0:2;
+ uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint32_t extType:7; /**< 5.4.6.1 extension type */
+ uint32_t ef:1; /**< 5.4.6.2 extension flag */
+
+ /*
+ * would be better to use bit manipulation directly to add these parameters
+ *
+ * bfAzPt: var by bfAzPtWidth
+ * bfZePt: var by bfZePtWidth
+ * bfAz3dd: var by bfAz3ddWidth
+ * bfZe3dd: var by bfZe3ddWidth
+ * bfAzSI:5 (including zero-padding for unused bits)
+ * bfZeSI:3
+ * padding for 4-byte alignment
+ *
+ */
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * DL Precoding Extension Type(ExtType 3) for first data layer.
+ * Defined in 5.4.7.3 Table 5-22.
+ * Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
+ * The structure is reordered for byte order conversion. Not supported.
+ */
+struct xran_cp_radioapp_section_ext3_first {
+ /* 16 bytes, need to convert byte order for two parts
+ * - 8 / 8 bytes
+ */
+ uint32_t reserved1:8;
+ uint32_t crsSymNum:4; /**< 5.4.7.3.6 CRS symbol number indication */
+ uint32_t reserved0:3;
+ uint32_t crsShift:1; /**< 5.4.7.3.7 CRS shift used for DL transmission */
+ uint32_t crsReMask:12; /**< 5.4.7.3.5 CRS resource element mask */
+ uint32_t txScheme:4; /**< 5.4.7.3.3 transmission scheme */
+ uint32_t numLayers:4; /**< 5.4.7.3.4 number of layers used for DL transmission */
+ uint32_t layerId:4; /**< 5.4.7.3.2 Layer ID for DL transmission */
+ uint32_t codebookIndex:8; /**< 5.4.7.3.1 precoder codebook used for transmission */
+ uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint32_t extType:7; /**< 5.4.6.1 extension type */
+ uint32_t ef:1; /**< 5.4.6.2 extension flag */
+
+ uint16_t beamIdAP3; /**< 5.4.7.3.10 beam id to be used for antenna port 3 */
+ uint16_t beamIdAP2; /**< 5.4.7.3.9 beam id to be used for antenna port 2 */
+ uint16_t beamIdAP1; /**< 5.4.7.3.8 beam id to be used for antenna port 1 */
+ uint16_t reserved2;
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * DL Precoding Extension Type(ExtType 3) for non-first data layer.
+ * Defined in 5.4.7.3 Table 5-23.
+ * Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
+ * The structure is reordered for byte order conversion. Not supported.
+ */
+struct xran_cp_radioapp_section_ext3_non_first {
+ /* 4 bytes, need to convert byte order at once */
+ uint32_t numLayers:4; /**< 5.4.7.3.4 number of layers used for DL transmission */
+ uint32_t layerId:4; /**< 5.4.7.3.2 Layer ID for DL transmission */
+ uint32_t codebookIndex:8; /**< 5.4.7.3.1 precoder codebook used for transmission */
+
+ uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint32_t extType:7; /**< 5.4.6.1 extension type */
+ uint32_t ef:1; /**< 5.4.6.2 extension flag */
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * Modulation Compression Parameter Extension Type(ExtType 4), 5.4.7.4
+ * Only applies to section type 1 and 3.
+ * The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext4 {
+ /* 4 bytes, need to convert byte order at once */
+ uint32_t modCompScaler:15; /**< 5.4.7.4.2 modulation compression scaler value */
+ uint32_t csf:1; /**< 5.4.7.4.1 constellation shift flag */
+
+ uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint32_t extType:7; /**< 5.4.6.1 extension type */
+ uint32_t ef:1; /**< 5.4.6.2 extension flag */
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * Modulation Compression Additional Parameter Extension Type(ExtType 5) for one scaler value.
+ * Defined in 5.4.7.5 Table 5-26
+ * Only applies to section type 1 3, and 5.
+ * The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext5_1 {
+ /* 8 bytes, need to convert byte order at once */
+ uint32_t reserved:20;
+ uint32_t mcScaleOffset:15; /**< 5.4.7.5.3 scaling value for modulation compression */
+ uint32_t csf:1; /**< 5.4.7.5.2 constellation shift flag */
+ uint32_t mcScaleReMask:12; /**< 5.4.7.5.1 modulation compression power scale RE mask */
+
+ uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint32_t extType:7; /**< 5.4.6.1 extension type */
+ uint32_t ef:1; /**< 5.4.6.2 extension flag */
+ } __attribute__((__packed__));
+
+/**
+ * @ingroup xran_cp_pkt
+ *
+ * @description
+ * Modulation Compression Additional Parameter Extension Type(ExtType 5) for two scaler values.
+ * Defined in 5.4.7.5 Table 5-27
+ * Only applies to section type 1 3, and 5.
+ * The structure is reordered for byte order conversion.
+ */
+struct xran_cp_radioapp_section_ext5_2 {
+ /* 12 bytes, need to convert byte order for two parts respectively
+ * - 2 and 8 bytes, reserved1 would be OK if it is zero
+ */
+ uint16_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
+ uint16_t extType:7; /**< 5.4.6.1 extension type */
+ uint16_t ef:1; /**< 5.4.6.2 extension flag */
+
+ uint32_t reserved0:8;
+ uint32_t mcScaleOffset2:15; /**< 5.4.7.5.3 scaling value for modulation compression */
+ uint32_t csf2:1; /**< 5.4.7.5.2 constellation shift flag */
+ uint32_t mcScaleReMask2:12; /**< 5.4.7.5.1 modulation compression power scale RE mask */
+ uint32_t mcScaleOffset1:15; /**< 5.4.7.5.3 scaling value for modulation compression */
+ uint32_t csf1:1; /**< 5.4.7.5.2 constellation shift flag */
+ uint32_t mcScaleReMask1:12; /**< 5.4.7.5.1 modulation compression power scale RE mask */
+
+ uint16_t reserved1;
+ } __attribute__((__packed__));
+
/**********************************************************
* Scheduling and Beam-forming Commands 5.4.2
**********************************************************/
// Payload start from here // 5.4.5.16 ~ 5.4.5.32
} __attribute__((__packed__));
+#ifdef __cplusplus
+}
+#endif
#endif /* _XRAN_PKT_CP_H_ */
*
*******************************************************************************/
-
/**
* @brief Definitions and support functions to process XRAN packet
* @file xran_pkt_up.h
#ifndef _XRAN_PKT_UP_H_
#define _XRAN_PKT_UP_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "xran_pkt.h"
#define IQ_PAIR_NUM_IN_RB 12
uint32_t sect_id:12; /**< 5.4.5.1 section identifier */
};
}fields;
- } __attribute__((__packed__));
+} __rte_packed;
/*
uint8_t compShift:4;
uint8_t compBitWidth:4;
} uLaw;
- } __attribute__((__packed__));
+} __rte_packed;
/*
{
int16_t i_sample:IQ_BITS; /**< This parameter is the In-phase sample value */
int16_t q_sample:IQ_BITS; /**< This parameter is the Quadrature sample value */
-} __rte_packed;;
+} __rte_packed;
+
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ * Structure holds complete xran u-plane packet header
+ * 3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct xran_up_pkt_hdr
+{
+ struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
+ struct radio_app_common_hdr app_hdr; /**< eCPRI Transport Header */
+ struct data_section_hdr data_sec_hdr;
+} __rte_packed;
+
+
+/**
+ ******************************************************************************
+ * @ingroup xran_common_pkt
+ *
+ * @description
+ * Structure holds complete ethernet and xran u-plane packet header
+ * 3.1.1 Ethernet Encapsulation
+ *****************************************************************************/
+struct eth_xran_up_pkt_hdr
+{
+ struct ether_hdr eth_hdr;
+ struct xran_up_pkt_hdr xran_hdr;
+}__rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
#endif
*
*******************************************************************************/
-
/**
* @brief This file provides interface to synchronization related APIs (PTP/1588)
* for XRAN.
#ifndef _XRAN_SYNC_API_H_
#define _XRAN_SYNC_API_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @brief Function checks if machine is synchronized using PTP for Linux
* software.
*/
int xran_is_synchronized(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _XRAN_SYNC_API_H_ */
*
*******************************************************************************/
-
/**
* @brief This file provides interface to Timing for XRAN.
*
#ifndef _XRAN_TIMER_H
#define _XRAN_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
long poll_next_tick(long interval_ns);
long sleep_next_tick(long interval);
-int timing_set_debug_stop(int value);
+int timing_set_debug_stop(int value, int count);
int timing_get_debug_stop(void);
inline uint64_t timing_get_current_second(void);
+int timing_set_numerology(uint8_t value);
+
+#ifdef __cplusplus
+}
+#endif
#endif
*
*******************************************************************************/
-
/**
* @brief This file provides the definitions for Transport layer (eCPRI) API.
*
#ifndef _XRAN_TRANSPORT_H_
#define _XRAN_TRANSPORT_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <rte_common.h>
#include <rte_mbuf.h>
uint8_t bandSectorId;
uint8_t ccId;
uint8_t ruPortId;
- };
+};
-/**
- * @brief Compose ecpriRtcid/ecpriPcid
- *
- * @param CU_Port_ID CU Port ID
- * @param BanbSector_ID Band Sector ID
- * @param CC_ID Component Carrier ID
- * @param Ant_ID RU Port ID (antenna ID)
- * @return uint16_t composed ecpriRtcid/ecpriPcid
- */
-uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID);
+struct xran_recv_packet_info {
+ int ecpri_version;
+ enum ecpri_msg_type msg_type;
+ int payload_len;
+ struct xran_eaxc_info eaxc;
+ int seq_id;
+ int subseq_id;
+ int ebit;
+};
-/**
- * @brief Decompose ecpriRtcid/ecpriPcid
- *
- * @param cid composed ecpriRtcid/ecpriPcid (network byte order)
- * @param result the pointer of the structure to store decomposed values
- * @return none
- */
-void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result);
-/**
- * @brief modify the payload size of eCPRI header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet which has eCPRI header already
- * @param size payload size to be updated
- * @return none
- */
+int xran_get_ecpri_hdr_size(void);
void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size);
+uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID);
+void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result);
+
+int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
+ uint8_t CC_ID, uint8_t Ant_ID,
+ uint8_t seq_id,
+ struct xran_ecpri_hdr **ecpri_hdr);
+
+int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
+ struct xran_ecpri_hdr **ecpri_hdr,
+ struct xran_recv_packet_info *pkt_info);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
*
*******************************************************************************/
-
/**
* @brief This file provides the definitions for User Plane Messages APIs.
*
#ifndef _XRAN_UP_API_H_
#define _XRAN_UP_API_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <rte_common.h>
#include <rte_mbuf.h>
#include "xran_pkt.h"
#include "xran_pkt_up.h"
-#define XRAN_BYTE_ORDER_SWAP
-
/*
* structure used for storing packet parameters needed for generating
* a data packet
uint8_t *subframe_id,
uint8_t *slot_id,
uint8_t *symb_id,
- struct ecpri_seq_id *seq_id);
+ struct ecpri_seq_id *seq_id,
+ uint16_t *num_prbu,
+ uint16_t *start_prbu,
+ uint16_t *sym_inc,
+ uint16_t *rb,
+ uint16_t *sect_id);
int xran_prepare_iq_symbol_portion_no_comp(
struct rte_mbuf *mbuf,
const void *iq_data_start,
+ const enum xran_input_byte_order iq_buf_byte_order,
const uint32_t iq_data_num_bytes,
struct xran_up_pkt_gen_no_compression_params *params,
uint8_t CC_ID,
uint8_t Ant_ID,
- uint8_t seq_id);
+ uint8_t seq_id,
+ uint32_t do_copy);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* _XRAN_UP_API_H_ */
* @author Intel Corporation
**/
+#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "ethernet.h"
#include "ethdi.h"
-#ifndef MLOG_ENABLED
-#include "../src/mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_fh_o_du.h"
+#include "xran_mlog_lnx.h"
+#include "xran_printf.h"
#include "../src/xran_lib_mlog_tasks_id.h"
+#define BURST_RX_IO_SIZE 48
+
struct xran_ethdi_ctx g_ethdi_ctx = { 0 };
enum xran_if_state xran_if_current_state = XRAN_STOPPED;
res = xran_enqueue_mbuf(mb, ctx->tx_ring[ETHDI_CP_VF]);
return res;
}
-
+#if 0
void xran_ethdi_stop_tx()
{
struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
rte_timer_stop_sync(&ctx->timer_tx);
}
-
+#endif
struct {
uint16_t ethertype;
return xran_handle_ether(rte_be_to_cpu_16(eth_hdr->ether_type), pkt, rx_time);
}
+#if 0
+//-------------------------------------------------------------------------------------------
+/** @ingroup xran
+ *
+ * @param[in] port - DPDK ETH port id
+ *
+ * @return void
+ *
+ * @description
+ * Prints statistics of usage of DPDK port
+ *
+**/
+//-------------------------------------------------------------------------------------------
+void xran_ethdi_ports_stats(void)
+{
+ struct rte_eth_stats stats;
+ struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+ int32_t i = 0;
+
+ for(i = 0; i < ETHDI_VF_MAX; i++){
+ /* Get stats (extended stats includes common stats) */
+ rte_eth_stats_get(ctx->io_cfg.port[i], &stats);
+ printf("DPDK stats:\n");
+ printf("** Port %hhu **\n", ctx->io_cfg.port[i]);
+ printf("ierrors:\t%lu\n", stats.ierrors);
+ printf("oerrors:\t%lu\n", stats.oerrors);
+ printf("ipackets:\t%lu\n", stats.ipackets);
+ printf("opackets:\t%lu\n", stats.opackets);
+ printf("imissed:\t%lu\n", stats.imissed);
+ printf("rx_nombuf:\t%lu\n", stats.rx_nombuf);
+ }
+ return ;
+}
+#endif
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void check_port_link_status(uint8_t portid)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+ uint8_t count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+
+ printf("\nChecking link status");
+ fflush(stdout);
+ for (count = 0; count <= MAX_CHECK_TIME; count++) {
+ all_ports_up = 1;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(portid, &link);
+
+ /* print link status if flag set */
+ if (print_flag == 1) {
+ if (link.link_status)
+ printf("Port %d Link Up - speed %u "
+ "Mbps - %s\n", (uint8_t)portid,
+ (unsigned)link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ printf("Port %d Link Down\n",
+ (uint8_t)portid);
+ }
+ /* clear all_ports_up flag if any link down */
+ if (link.link_status == ETH_LINK_DOWN) {
+ all_ports_up = 0;
+ break;
+ }
+ /* after finally printing all link status, get out */
+ if (print_flag == 1)
+ break;
+
+ if (all_ports_up == 0) {
+ printf(".");
+ fflush(stdout);
+ rte_delay_ms(CHECK_INTERVAL);
+ }
+ /* set the print_flag if all ports up or timeout */
+ if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+ print_flag = 1;
+ printf(" ... done\n");
+ }
+ }
+}
int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr,
uint16_t cp_vlan, uint16_t up_vlan)
{
- uint16_t port[2] = {0, 0};
+ uint16_t port[2] = {0xffff, 0xffff};
struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
int i;
char core_mask[20];
- char *argv[] = { name, core_mask, "-m3072", "--proc-type=auto",
- "--file-prefix", name, "-w", "0000:00:00.0" };
+ char bbdev_wdev[32] = "";
+ char bbdev_vdev[32] = "";
+
+ char *argv[] = { name, "-c ffffffff", "-n2", "--socket-mem=8192", "--proc-type=auto",
+ "--file-prefix", name, "-w", "0000:00:00.0", bbdev_wdev, bbdev_vdev};
if (io_cfg == NULL)
return 0;
+ if(io_cfg->bbdev_mode != XRAN_BBDEV_NOT_USED){
+ printf("BBDEV_FEC_ACCL_NR5G\n");
+ if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_ON){
+ // hw-accelerated bbdev
+ printf("hw-accelerated bbdev %s\n", io_cfg->bbdev_dev[0]);
+ sprintf(bbdev_wdev, "-w %s", io_cfg->bbdev_dev[0]);
+ } else if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_OFF){
+ // hw-accelerated bbdev disable
+ if(io_cfg->bbdev_dev[0]){
+ printf("hw-accelerated bbdev disable %s\n", io_cfg->bbdev_dev[0]);
+ sprintf(bbdev_wdev, "-b %s", io_cfg->bbdev_dev[0]);
+ }
+ sprintf(bbdev_wdev, "%s", "--vdev=baseband_turbo_sw");
+ } else {
+ rte_panic("Cannot init DPDK incorrect [bbdev_mode %d]\n", io_cfg->bbdev_mode);
+ }
+ }
snprintf(core_mask, sizeof(core_mask), "-c%x",
(1 << io_cfg->core) |
for (i = 0; i <= ID_BROADCAST; i++) /* Initialize all as broadcast */
memset(&ctx->entities[i], 0xFF, sizeof(ctx->entities[0]));
+ printf("%s: Calling rte_eal_init:", __FUNCTION__);
+ for (i = 0; i < RTE_DIM(argv); i++)
+ {
+ printf("%s ", argv[i]);
+ }
+ printf("\n");
+
+
/* This will return on system_core, which is not necessarily the
* one we're on right now. */
if (rte_eal_init(RTE_DIM(argv), argv) < 0)
xran_init_mbuf_pool();
+
/* Timers. */
rte_timer_subsystem_init();
rte_timer_init(&ctx->timer_ping);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
for (i = 0; i < ETHDI_VF_MAX; i ++){
- if (rte_eth_dev_attach(io_cfg->dpdk_dev[i], &port[i]) != 0 ||
- rte_eth_dev_count_avail() == 0)
- errx(1, "Network port doesn't exist.");
- xran_init_port(port[i], p_lls_cu_addr); /* we only have 1 port at this stage */
+ if(io_cfg->dpdk_dev[i]){
+ if (rte_eth_dev_attach(io_cfg->dpdk_dev[i], &port[i]) != 0 ||
+ rte_eth_dev_count_avail() == 0)
+ errx(1, "Network port doesn't exist.");
+ xran_init_port(port[i], p_lls_cu_addr);
+ } else {
+ printf("no DPDK port provided\n");
+ }
if(i==0){
ctx->tx_ring[i] = rte_ring_create("tx_ring_up", NUM_MBUFS,
rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ);
ctx->pkt_dump_ring[i] = rte_ring_create("pkt_dump_ring_cp", NUM_MBUFS,
rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ);
}
+ if(io_cfg->dpdk_dev[i])
+ check_port_link_status(port[i]);
}
} else {
rte_panic("ethdi_dpdk_io_loop() failed to start with RTE_PROC_SECONDARY\n");
PANIC_ON(ctx->tx_ring == NULL, "failed to allocate tx ring");
PANIC_ON(ctx->rx_ring == NULL, "failed to allocate rx ring");
PANIC_ON(ctx->pkt_dump_ring == NULL, "failed to allocate pkt dumping ring");
- for (i = 0; i < ETHDI_VF_MAX; i++)
+ for (i = 0; i < ETHDI_VF_MAX; i++){
ctx->io_cfg.port[i] = port[i];
+ print_dbg("port_id 0x%04x\n", ctx->io_cfg.port[i]);
+ }
- rte_eth_macaddr_get(port[ETHDI_UP_VF], &ctx->entities[io_cfg->id]);
- ether_addr_copy(p_ru_addr, &ctx->entities[ID_RU]);
-
- /* Start the actual IO thread */
- if (rte_eal_remote_launch(xran_ethdi_dpdk_io_loop, &ctx->io_cfg, *lcore_id))
- rte_panic("ethdi_dpdk_io_loop() failed to start\n");
+ if(io_cfg->dpdk_dev[ETHDI_UP_VF]){
+ rte_eth_macaddr_get(port[ETHDI_UP_VF], &ctx->entities[io_cfg->id]);
+ ether_addr_copy(p_ru_addr, &ctx->entities[ID_RU]);
+ }
return 1;
}
}
}
+int32_t process_dpdk_io(void)
+{
+ struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+ const struct xran_io_loop_cfg *const cfg = &(xran_ethdi_get_ctx()->io_cfg);
+ const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
+ int port_id = 0;
+
+ for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++){
+ struct rte_mbuf *mbufs[BURST_RX_IO_SIZE];
+ if(port[port_id] == 0xFF);
+ /* RX */
+ const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_RX_IO_SIZE);
+ if (rxed != 0){
+ unsigned enq_n = 0;
+ long t1 = MLogTick();
+ enq_n = rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL);
+ if(rxed - enq_n)
+ rte_panic("error enq\n");
+ MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick());
+ }
+
+ /* TX */
+ const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]);
+
+ if (XRAN_STOPPED == xran_if_current_state)
+ return -1;
+ }
+
+ if (XRAN_STOPPED == xran_if_current_state)
+ return -1;
+
+ return 0;
+}
+#if 0
+static inline void xran_process_rx_burst(struct rte_mbuf *mbufs[], uint16_t n_mbufs,
+ uint64_t rx_time)
+{
+ int i;
+
+ if (!n_mbufs)
+ return;
+
+ for (i = 0; i < n_mbufs; ++i)
+ {
+ if (xran_ethdi_filter_packet(mbufs[i], rx_time) == MBUF_FREE)
+ rte_pktmbuf_free(mbufs[i]);
+ }
+
+#ifdef DPDKIO_LATENCY_DEBUG
+ struct timeval tv_now, tv_diff;
+
+ gettimeofday(&tv_now, NULL);
+ if (n_mbufs > 1)
+ nlog("Warning - received %d mbufs in a row", n_mbufs);
+
+ timersub(&tv_now, &rx_time, &tv_diff);
+ nlog("rx processing took %d usec", tv_diff.tv_usec);
+#endif
+}
/*
* This is the main DPDK-IO loop.
*/
int xran_ethdi_dpdk_io_loop(void *io_loop_cfg)
{
- struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
- const struct xran_io_loop_cfg *const cfg = io_loop_cfg;
- const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
- int port_id = 0;
struct sched_param sched_param;
int res = 0;
+ struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx();
+ const struct xran_io_loop_cfg *const cfg = &(xran_ethdi_get_ctx()->io_cfg);
+ const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]};
printf("%s [PORT: %d %d] [CPU %2d] [PID: %6d]\n", __FUNCTION__, port[ETHDI_UP_VF], port[ETHDI_CP_VF] , rte_lcore_id(), getpid());
printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
- if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
- {
+ if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))) {
printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
}
- for (;;) {
- for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++){
- struct rte_mbuf *mbufs[BURST_SIZE];
- /* RX */
- const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_SIZE);
- if (rxed != 0){
- long t1 = MLogTick();
- rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL);
- MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick());
- }
-
- /* TX */
- const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]);
- if (rxed | sent)
- continue; /* more packets might be waiting in queues */
-
- rte_pause(); /* short pause, optimize memory access */
- if (XRAN_STOPPED == xran_if_current_state)
- break;
- }
-
- if (XRAN_STOPPED == xran_if_current_state)
- break;
+ for (;;){
+ if(process_dpdk_io()!=0)
+ break;
}
fflush(stderr);
fflush(stdout);
puts("IO loop finished");
- //for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++)
- // xran_ethdi_port_stats(port[port_id]);
-
return 0;
}
+#endif
+
*
*******************************************************************************/
-
/**
* @brief This file has all definitions for the Ethernet Data Interface Layer
* @file ethdi.h
#include <rte_timer.h>
#include "ethernet.h"
+#include "xran_fh_o_du.h"
#define XRAN_THREAD_DEFAULT_PRIO (98)
#define TX_TIMER_INTERVAL ((rte_get_timer_hz() / 1000000000L)*interval_us*1000) /* nanosec */
#define TX_RX_LOOP_TIME rte_get_timer_hz() / 1
-extern enum xran_if_state xran_if_current_state;
-
-enum xran_if_state
-{
- XRAN_RUNNING,
- XRAN_STOPPED
-};
-
enum xran_ping_states
{
PING_IDLE,
{
uint8_t id;
char *dpdk_dev[ETHDI_VF_MAX];
+ char *bbdev_dev[1];
+ int bbdev_mode;
int core;
int system_core; /* Needed as DPDK will change your starting core. */
int pkt_proc_core; /* Needed for packet processing thread. */
MBUF_FREE
};
+extern enum xran_if_state xran_if_current_state;
extern uint8_t ping_dst_id;
extern struct ether_addr entities_addrs[];
int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg,
int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr,
uint16_t cp_vlan, uint16_t up_vlan);
-int xran_ethdi_dpdk_io_loop(void *);
struct rte_mbuf *xran_ethdi_mbuf_alloc(void);
int xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype);
int xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype);
+#if 0
void xran_ethdi_stop_tx(void);
+void xran_ethdi_ports_stats(void);
+int xran_ethdi_dpdk_io_loop(void *);
+#endif
int xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time);
+int32_t process_dpdk_io(void);
#ifdef __cplusplus
#include "ethdi.h"
/* Our mbuf pools. */
-struct rte_mempool *_eth_mbuf_pool;
-struct rte_mempool *_eth_mbuf_pool_rx;
-struct rte_mempool *_eth_mbuf_pool_small;
-struct rte_mempool *_eth_mbuf_pool_big;
+struct rte_mempool *_eth_mbuf_pool = NULL;
+struct rte_mempool *_eth_mbuf_pool_inderect = NULL;
+struct rte_mempool *_eth_mbuf_pool_rx = NULL;
+struct rte_mempool *_eth_mbuf_pool_small = NULL;
+struct rte_mempool *_eth_mbuf_pool_big = NULL;
+
+struct rte_mempool *socket_direct_pool = NULL;
+struct rte_mempool *socket_indirect_pool = NULL;
+
/*
* Make sure the ring indexes are big enough to cover buf space x2
#define RINGSIZE sizeof(io_ring.buf)
#define RINGMASK (RINGSIZE - 1)
+int __xran_delayed_msg(const char *fmt, ...)
+{
+#if 0
+ va_list ap;
+ int msg_len;
+ char localbuf[RINGSIZE];
+ ring_idx old_head, new_head;
+ ring_idx copy_len;
+
+ /* first prep a copy of the message on the local stack */
+ va_start(ap, fmt);
+ msg_len = vsnprintf(localbuf, RINGSIZE, fmt, ap);
+ va_end(ap);
+
+ /* atomically reserve space in the ring */
+ for (;;) {
+ old_head = io_ring.head; /* snapshot head */
+ /* free always within range of [0, RINGSIZE] - proof by induction */
+ const ring_idx free = RINGSIZE - (old_head - io_ring.tail);
+
+ copy_len = RTE_MIN(msg_len, free);
+ if (copy_len <= 0)
+ return 0; /* vsnprintf error or ringbuff full. Drop log. */
+
+ new_head = old_head + copy_len;
+ RTE_ASSERT((ring_idx)(new_head - io_ring.tail) <= RINGSIZE);
+
+ if (likely(__atomic_compare_exchange_n(&io_ring.head, &old_head,
+ new_head, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)))
+ break;
+ }
+
+ /* Now copy data in at ease. */
+ const int copy_start = (old_head & RINGMASK);
+ if (copy_start < (new_head & RINGMASK)) /* no wrap */
+ memcpy(io_ring.buf + copy_start, localbuf, copy_len);
+ else { /* wrap-around */
+ const int chunk_len = RINGSIZE - copy_start;
+
+ memcpy(io_ring.buf + copy_start, localbuf, chunk_len);
+ memcpy(io_ring.buf, localbuf + chunk_len, copy_len - chunk_len);
+ }
+
+ /* wait for previous writes to complete before updating read_head. */
+ while (io_ring.read_head != old_head)
+ rte_pause();
+ io_ring.read_head = new_head;
+
+
+ return copy_len;
+ #endif
+ return 0;
+}
/*
* Display part of the message stored in the ring buffer.
* Might require multiple calls to print the full message.
* Will return 0 when nothing left to print.
*/
+#if 0
int xran_show_delayed_message(void)
{
ring_idx tail = io_ring.tail;
return written; /* next invocation will print the rest if any */
}
-
+#endif
void xran_init_mbuf_pool(void)
{
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
_eth_mbuf_pool = rte_pktmbuf_pool_create("mempool", NUM_MBUFS,
MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());
+#ifdef XRAN_ATTACH_MBUF
+ _eth_mbuf_pool_inderect = rte_pktmbuf_pool_create("mempool_indirect", NUM_MBUFS,
+ MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());*/
+#endif
_eth_mbuf_pool_rx = rte_pktmbuf_pool_create("mempool_rx", NUM_MBUFS,
MBUF_CACHE, 0, MBUF_POOL_ELEMENT, rte_socket_id());
_eth_mbuf_pool_small = rte_pktmbuf_pool_create("mempool_small",
NUM_MBUFS_BIG, 0, 0, MBUF_POOL_ELM_BIG, rte_socket_id());
} else {
_eth_mbuf_pool = rte_mempool_lookup("mempool");
+ _eth_mbuf_pool_inderect = rte_mempool_lookup("mempool_indirect");
_eth_mbuf_pool_rx = rte_mempool_lookup("mempool_rx");
_eth_mbuf_pool_small = rte_mempool_lookup("mempool_small");
_eth_mbuf_pool_big = rte_mempool_lookup("mempool_big");
}
if (_eth_mbuf_pool == NULL)
rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
+#ifdef XRAN_ATTACH_MBUF
+ if (_eth_mbuf_pool_inderect == NULL)
+ rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
+#endif
if (_eth_mbuf_pool_rx == NULL)
rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
if (_eth_mbuf_pool_small == NULL)
rte_panic("Cannot create small mbuf pool: %s\n", rte_strerror(rte_errno));
if (_eth_mbuf_pool_big == NULL)
rte_panic("Cannot create big mbuf pool: %s\n", rte_strerror(rte_errno));
+
+ if (socket_direct_pool == NULL)
+ socket_direct_pool = _eth_mbuf_pool;
+
+ if (socket_indirect_pool == NULL)
+ socket_indirect_pool = _eth_mbuf_pool_inderect;
}
/* Init NIC port, then start the port */
void xran_init_port(int p_id, struct ether_addr *p_lls_cu_addr)
{
- char buf[ETHER_ADDR_FMT_SIZE];
- struct ether_addr eth_addr;
+ static uint16_t nb_rxd = BURST_SIZE;
+ static uint16_t nb_txd = BURST_SIZE;
+ struct ether_addr addr;
struct rte_eth_rxmode rxmode =
{ .split_hdr_size = 0,
.max_rx_pkt_len = MAX_RX_LEN,
.rxmode = rxmode,
.txmode = txmode
};
- struct ether_addr pDstEthAddr;
-
struct rte_eth_rxconf rxq_conf;
struct rte_eth_txconf txq_conf;
const char *drv_name = "";
int sock_id = rte_eth_dev_socket_id(p_id);
- // ether_format_addr(buf, sizeof(buf), p_lls_cu_addr);
- // printf("port %d set mac address %s\n", p_id, buf);
- // rte_eth_dev_default_mac_addr_set(p_id, p_lls_cu_addr);
-
rte_eth_dev_info_get(p_id, &dev_info);
if (dev_info.driver_name)
drv_name = dev_info.driver_name;
printf("initializing port %d for TX, drv=%s\n", p_id, drv_name);
- /* In order to receive packets from any server need to add broad case address
- * for the port*/
- pDstEthAddr.addr_bytes[0] = 0xFF;
- pDstEthAddr.addr_bytes[1] = 0xFF;
- pDstEthAddr.addr_bytes[2] = 0xFF;
-
- pDstEthAddr.addr_bytes[3] = 0xFF;
- pDstEthAddr.addr_bytes[4] = 0xFF;
- pDstEthAddr.addr_bytes[5] = 0xFF;
-
- rte_eth_macaddr_get(p_id, ð_addr);
- ether_format_addr(buf, sizeof(buf), ð_addr);
- printf("port %d mac address %s\n", p_id, buf);
-
- struct ether_addr addr;
rte_eth_macaddr_get(p_id, &addr);
-// rte_eth_dev_mac_addr_add(p_id, &pDstEthAddr,1);
- // rte_eth_dev_mac_addr_add(p_id, &addr, 1);
-
printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
(unsigned)p_id,
if (ret < 0)
rte_panic("Cannot configure port %u (%d)\n", p_id, ret);
+ ret = rte_eth_dev_adjust_nb_rx_tx_desc(p_id, &nb_rxd,&nb_txd);
+
+ if (ret < 0) {
+ printf("\n");
+ rte_exit(EXIT_FAILURE, "Cannot adjust number of "
+ "descriptors: err=%d, port=%d\n", ret, p_id);
+ }
+ printf("Port %u: nb_rxd %d nb_txd %d\n", p_id, nb_rxd, nb_txd);
+
/* Init RX queues */
rxq_conf = dev_info.default_rxconf;
- ret = rte_eth_rx_queue_setup(p_id, 0, BURST_SIZE,
+ ret = rte_eth_rx_queue_setup(p_id, 0, nb_rxd,
sock_id, &rxq_conf, _eth_mbuf_pool_rx);
if (ret < 0)
rte_panic("Cannot init RX for port %u (%d)\n",
/* Init TX queues */
txq_conf = dev_info.default_txconf;
- ret = rte_eth_tx_queue_setup(p_id, 0, BURST_SIZE, sock_id, &txq_conf);
+ ret = rte_eth_tx_queue_setup(p_id, 0, nb_txd, sock_id, &txq_conf);
if (ret < 0)
rte_panic("Cannot init TX for port %u (%d)\n",
p_id, ret);
if (ret < 0)
rte_panic("Cannot start port %u (%d)\n", p_id, ret);
- rte_eth_promiscuous_enable(p_id);
+// rte_eth_promiscuous_enable(p_id);
}
+#if 0
void xran_memdump(void *addr, int len)
{
int i;
#endif
}
-
/* Prepend ethernet header, possibly vlan tag. */
-void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci)
+void xran_add_eth_hdr(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb)
{
/* add in the ethernet header */
struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mb, sizeof(*h));
}
#endif
#ifdef VLAN_SUPPORT
- mb->vlan_tci = vlan_tci;
- dlog("Inserting vlan tag of %d", vlan_tci);
+ mb->vlan_tci = FLEXRAN_UP_VLAN_TAG;
+ dlog("Inserting vlan tag of %d", FLEXRAN_UP_VLAN_TAG);
rte_vlan_insert(&mb);
#endif
}
+int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb)
+{
+ xran_add_eth_hdr(dst, ETHER_TYPE_ETHDI, mb);
+
+ if (rte_eth_tx_burst(mb->port, 0, &mb, 1) == 1)
+ return 1;
+
+ elog("packet sending failed on port %d", mb->port);
+ rte_pktmbuf_free(mb);
+
+ return 0; /* fail */
+}
+
int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len)
{
struct rte_mbuf *mbufs[BURST_SIZE];
return 1;
}
+
+#endif
+
+/* Prepend ethernet header, possibly vlan tag. */
+void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci)
+{
+ /* add in the ethernet header */
+ struct ether_hdr *h = (struct ether_hdr *)rte_pktmbuf_mtod(mb, struct ether_hdr*);
+
+ PANIC_ON(h == NULL, "mbuf prepend of ether_hdr failed");
+
+ /* Fill in the ethernet header. */
+ rte_eth_macaddr_get(mb->port, &h->s_addr); /* set source addr */
+ h->d_addr = *dst; /* set dst addr */
+ h->ether_type = rte_cpu_to_be_16(ethertype); /* ethertype too */
+
+#if defined(DPDKIO_DEBUG) && DPDKIO_DEBUG > 1
+ {
+ char dst[ETHER_ADDR_FMT_SIZE] = "(empty)";
+ char src[ETHER_ADDR_FMT_SIZE] = "(empty)";
+
+ nlog("*** packet for TX below (len %d) ***", rte_pktmbuf_pkt_len(mb));
+ ether_format_addr(src, sizeof(src), &h->s_addr);
+ ether_format_addr(dst, sizeof(dst), &h->d_addr);
+ nlog("src: %s dst: %s ethertype: %.4X", src, dst, ethertype);
+ }
+#endif
+#ifdef VLAN_SUPPORT
+ mb->vlan_tci = vlan_tci;
+ dlog("Inserting vlan tag of %d", vlan_tci);
+ rte_vlan_insert(&mb);
+#endif
+}
+
+
*
*******************************************************************************/
-
/**
* @brief This file has all definitions for the Ethernet Data Interface Layer
* @file ethernet.h
#include <rte_ether.h>
#include <rte_mbuf.h>
-#define BURST_SIZE 64
+#define BURST_SIZE 4096
//#define VLAN_SUPPORT
#define FLEXRAN_UP_VLAN_TAG 2
#define ETHER_TYPE_SYNC 0xBEFE
#define ETHER_TYPE_START_TX 0xCEFE
-#define NUM_MBUFS 262144
+#define NUM_MBUFS 65536
#define MBUF_CACHE 256
#define MBUF_POOL_ELM_SMALL 1500 /* regular ethernet MTU, most compatible */
extern struct rte_mempool *_eth_mbuf_pool;
extern struct rte_mempool *_eth_mbuf_pool_small;
extern struct rte_mempool *_eth_mbuf_pool_big;
+extern struct rte_mempool *socket_direct_pool;
+extern struct rte_mempool *socket_indirect_pool;
/* Do NOT change the order of this enum and below
* - need to be in sync with the table of handlers in testue.c */
void xran_init_port(int port, struct ether_addr *p_lls_cu_addr);
void xran_add_eth_hdr_vlan(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb, uint16_t vlan_tci);
-int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb);
-
-int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len);
+#if 0
void xran_memdump(void *addr, int len);
-
+void xran_add_eth_hdr(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *);
+int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb);
+int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len);
+int xran_show_delayed_message(void);
+#endif
/*
* Print a message after all critical processing done.
* Mt-safe. 4 variants - normal, warning, error and debug log.
*/
-
-#define nlog(m, ...)
-#define delayed_message /* this is the old alias for this function */
-#define wlog(m, ...)
-#define elog(m, ...)
+int __xran_delayed_msg(const char *fmt, ...);
+#define nlog(m, ...) __xran_delayed_msg("%s(): " m "\n", __FUNCTION__, ##__VA_ARGS__)
+#define delayed_message nlog /* this is the old alias for this function */
+#define wlog(m, ...) nlog("WARNING: " m, ##__VA_ARGS__)
+#define elog(m, ...) nlog("ERROR: " m, ##__VA_ARGS__)
#ifdef DEBUG
-# define dlog(m, ...)
+# define dlog(m, ...) nlog("DEBUG: " m, ##__VA_ARGS__)
#else
# define dlog(m, ...)
#endif
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+/**
+ * @brief xRAN application frgamentation for U-plane packets
+ *
+ * @file xran_app_frag.c
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_mempool.h>
+#include <rte_debug.h>
+
+#include "xran_app_frag.h"
+#include "xran_cp_api.h"
+#include "xran_pkt_up.h"
+#include "xran_printf.h"
+#include "xran_common.h"
+
+/* Fragment alignment */
+#define XRAN_PAYLOAD_RB_ALIGN (N_SC_PER_PRB*(IQ_BITS/8)*2) /**< at least 12*4=48 bytes per one RB */
+
+static inline void __fill_xranhdr_frag(struct xran_up_pkt_hdr *dst,
+ const struct xran_up_pkt_hdr *src, uint16_t rblen_bytes,
+ uint16_t rboff_bytes, struct xran_section_info *sectinfo, uint32_t mf, uint8_t *seqid)
+{
+ struct data_section_hdr loc_data_sec_hdr;
+ struct xran_ecpri_hdr loc_ecpri_hdr;
+
+ rte_memcpy(dst, src, sizeof(*dst));
+
+ if(dst->ecpri_hdr.ecpri_seq_id.seq_id != *seqid - 1){
+ /* not first fragment, incease seq id */
+ dst->ecpri_hdr.ecpri_seq_id.seq_id = *seqid++;
+ }
+
+ loc_data_sec_hdr.fields.all_bits = rte_be_to_cpu_32(dst->data_sec_hdr.fields.all_bits);
+
+ /* update RBs */
+ loc_data_sec_hdr.fields.start_prbu = sectinfo->startPrbc + rboff_bytes/(N_SC_PER_PRB*(IQ_BITS/8*2));
+ loc_data_sec_hdr.fields.num_prbu = rblen_bytes/(N_SC_PER_PRB*(IQ_BITS/8*2));
+
+ print_dbg("sec [%d %d] pkt [%d %d] rboff_bytes %d rblen_bytes %d\n",sectinfo->startPrbc, sectinfo->numPrbc, loc_data_sec_hdr.fields.start_prbu, loc_data_sec_hdr.fields.num_prbu,
+ rboff_bytes, rblen_bytes);
+
+ dst->data_sec_hdr.fields.all_bits = rte_cpu_to_be_32(loc_data_sec_hdr.fields.all_bits);
+
+ /* update length */
+ dst->ecpri_hdr.cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
+ sizeof(struct data_section_hdr) + rblen_bytes + xran_get_ecpri_hdr_size());
+}
+
+
+static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
+{
+ uint32_t i;
+ for (i = 0; i != num; i++)
+ rte_pktmbuf_free(mb[i]);
+}
+
+/**
+ * XRAN fragmentation.
+ *
+ * This function implements the application fragmentation of XRAN packets.
+ *
+ * @param pkt_in
+ * The input packet.
+ * @param pkts_out
+ * Array storing the output fragments.
+ * @param mtu_size
+ * Size in bytes of the Maximum Transfer Unit (MTU) for the outgoing XRAN
+ * datagrams. This value includes the size of the XRAN headers.
+ * @param pool_direct
+ * MBUF pool used for allocating direct buffers for the output fragments.
+ * @param pool_indirect
+ * MBUF pool used for allocating indirect buffers for the output fragments.
+ * @return
+ * Upon successful completion - number of output fragments placed
+ * in the pkts_out array.
+ * Otherwise - (-1) * <errno>.
+ */
+int32_t
+xran_app_fragment_packet(struct rte_mbuf *pkt_in, /* eth hdr is prepended */
+ struct rte_mbuf **pkts_out,
+ uint16_t nb_pkts_out,
+ uint16_t mtu_size,
+ struct rte_mempool *pool_direct,
+ struct rte_mempool *pool_indirect,
+ struct xran_section_info *sectinfo,
+ uint8_t *seqid)
+{
+ struct rte_mbuf *in_seg = NULL;
+ uint32_t out_pkt_pos = 0, in_seg_data_pos = 0;
+ uint32_t more_in_segs;
+ uint16_t fragment_offset, frag_size;
+ uint16_t frag_bytes_remaining;
+ struct eth_xran_up_pkt_hdr *in_hdr;
+ struct xran_up_pkt_hdr *in_hdr_xran;
+
+ /*
+ * Ensure the XRAN payload length of all fragments is aligned to a
+ * multiple of 48 bytes (1 RB with IQ of 16 bits each)
+ */
+ frag_size = ((mtu_size - sizeof(struct eth_xran_up_pkt_hdr) - RTE_PKTMBUF_HEADROOM)/XRAN_PAYLOAD_RB_ALIGN)*XRAN_PAYLOAD_RB_ALIGN;
+
+
+ print_dbg("frag_size %d\n",frag_size);
+
+ in_hdr = rte_pktmbuf_mtod(pkt_in, struct eth_xran_up_pkt_hdr *);
+
+ in_hdr_xran = &in_hdr->xran_hdr;
+
+ /* Check that pkts_out is big enough to hold all fragments */
+ if (unlikely(frag_size * nb_pkts_out <
+ (uint16_t)(pkt_in->pkt_len - sizeof (struct xran_up_pkt_hdr)))){
+ print_err("-EINVAL\n");
+ return -EINVAL;
+ }
+
+ in_seg = pkt_in;
+ in_seg_data_pos = sizeof(struct eth_xran_up_pkt_hdr);
+ out_pkt_pos = 0;
+ fragment_offset = 0;
+
+ more_in_segs = 1;
+ while (likely(more_in_segs)) {
+ struct rte_mbuf *out_pkt = NULL, *out_seg_prev = NULL;
+ uint32_t more_out_segs;
+ struct xran_up_pkt_hdr *out_hdr;
+
+ /* Allocate direct buffer */
+ out_pkt = rte_pktmbuf_alloc(pool_direct);
+ if (unlikely(out_pkt == NULL)) {
+ print_err("pool_direct -ENOMEM\n");
+ __free_fragments(pkts_out, out_pkt_pos);
+ return -ENOMEM;
+ }
+
+ print_dbg("[%d] out_pkt %p\n",more_in_segs, out_pkt);
+
+ /* Reserve space for the XRAN header that will be built later */
+ //out_pkt->data_len = sizeof(struct xran_up_pkt_hdr);
+ //out_pkt->pkt_len = sizeof(struct xran_up_pkt_hdr);
+ if(rte_pktmbuf_append(out_pkt, sizeof(struct xran_up_pkt_hdr)) ==NULL){
+ rte_panic("sizeof(struct xran_up_pkt_hdr)");
+ }
+ frag_bytes_remaining = frag_size;
+
+ out_seg_prev = out_pkt;
+ more_out_segs = 1;
+ while (likely(more_out_segs && more_in_segs)) {
+ uint32_t len;
+#ifdef XRAN_ATTACH_MBUF
+ struct rte_mbuf *out_seg = NULL;
+
+ /* Allocate indirect buffer */
+ print_dbg("Allocate indirect buffer \n");
+ out_seg = rte_pktmbuf_alloc(pool_indirect);
+ if (unlikely(out_seg == NULL)) {
+ print_err("pool_indirect -ENOMEM\n");
+ rte_pktmbuf_free(out_pkt);
+ __free_fragments(pkts_out, out_pkt_pos);
+ return -ENOMEM;
+ }
+
+ print_dbg("[%d %d] out_seg %p\n",more_out_segs, more_in_segs, out_seg);
+ out_seg_prev->next = out_seg;
+ out_seg_prev = out_seg;
+
+ /* Prepare indirect buffer */
+ rte_pktmbuf_attach(out_seg, in_seg);
+#endif
+ len = frag_bytes_remaining;
+ if (len > (in_seg->data_len - in_seg_data_pos)) {
+ len = in_seg->data_len - in_seg_data_pos;
+ }
+#ifdef XRAN_ATTACH_MBUF
+ out_seg->data_off = in_seg->data_off + in_seg_data_pos;
+ out_seg->data_len = (uint16_t)len;
+ out_pkt->pkt_len = (uint16_t)(len +
+ out_pkt->pkt_len);
+ out_pkt->nb_segs += 1;
+#else
+{
+ char* pChar = rte_pktmbuf_mtod(in_seg, char*);
+ void *iq_src = (pChar + in_seg_data_pos);
+ void *iq_dst = rte_pktmbuf_append(out_pkt, len);
+
+ print_dbg("rte_pktmbuf_attach\n");
+ if(iq_src && iq_dst)
+ rte_memcpy(iq_dst, iq_src, len);
+ else
+ print_err("iq_src %p iq_dst %p\n len %d room %d\n", iq_src, iq_dst, len, rte_pktmbuf_tailroom(out_pkt));
+}
+#endif
+ in_seg_data_pos += len;
+ frag_bytes_remaining -= len;
+
+ /* Current output packet (i.e. fragment) done ? */
+ if (unlikely(frag_bytes_remaining == 0))
+ more_out_segs = 0;
+
+ /* Current input segment done ? */
+ if (unlikely(in_seg_data_pos == in_seg->data_len)) {
+ in_seg = in_seg->next;
+ in_seg_data_pos = 0;
+
+ if (unlikely(in_seg == NULL))
+ more_in_segs = 0;
+ }
+ }
+
+ /* Build the XRAN header */
+ print_dbg("Build the XRAN header\n");
+ out_hdr = rte_pktmbuf_mtod(out_pkt, struct xran_up_pkt_hdr *);
+
+ __fill_xranhdr_frag(out_hdr, in_hdr_xran,
+ (uint16_t)out_pkt->pkt_len - sizeof(struct xran_up_pkt_hdr),
+ fragment_offset, sectinfo, more_in_segs, seqid);
+
+ fragment_offset = (uint16_t)(fragment_offset +
+ out_pkt->pkt_len - sizeof(struct xran_up_pkt_hdr));
+
+ //out_pkt->l3_len = sizeof(struct xran_up_pkt_hdr);
+
+ /* Write the fragment to the output list */
+ pkts_out[out_pkt_pos] = out_pkt;
+ print_dbg("out_pkt_pos %d data_len %d pkt_len %d\n", out_pkt_pos, out_pkt->data_len, out_pkt->pkt_len);
+ out_pkt_pos ++;
+ //rte_pktmbuf_dump(stdout, out_pkt, 96);
+ }
+
+ return out_pkt_pos;
+}
+
+
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+/**
+ * @brief Header file for functions to perform application level fragmentation
+ *
+ * @file xran_app_frag.h
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#ifndef _XRAN_APP_FRAG_
+#define _XRAN_APP_FRAG_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <rte_config.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_byteorder.h>
+
+#include "xran_fh_o_du.h"
+#include "xran_cp_api.h"
+
+int32_t xran_app_fragment_packet(struct rte_mbuf *pkt_in, /* eth hdr is prepended */
+ struct rte_mbuf **pkts_out,
+ uint16_t nb_pkts_out,
+ uint16_t mtu_size,
+ struct rte_mempool *pool_direct,
+ struct rte_mempool *pool_indirect,
+ struct xran_section_info *sectinfo,
+ uint8_t *seqid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XRAN_APP_FRAG_ */
+
*
*******************************************************************************/
-#ifndef _XRAN_COMMON_
-#define _XRAN_COMMON_
-
/**
* @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
* U-plane
#include "ethdi.h"
#include "xran_pkt.h"
#include "xran_pkt_up.h"
-#include "xran_cp_api.h"
#include "xran_up_api.h"
+#include "xran_lib_mlog_tasks_id.h"
+
#include "../src/xran_printf.h"
+#include <rte_mbuf.h>
+#include "xran_mlog_lnx.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#define MBUFS_CNT 16
-#define MBUFS_CNT 256
+extern long interval_us;
extern int xran_process_rx_sym(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id,
+ uint32_t *mb_free);
+
+
+extern int xran_process_prach_sym(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id);
+
+extern int32_t xran_pkt_validate(void *arg,
+ struct rte_mbuf *mbuf,
void *iq_data_start,
uint16_t size,
uint8_t CC_ID,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
- uint8_t symb_id);
+ uint8_t symb_id,
+ struct ecpri_seq_id *seq_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id);
+long rx_counter = 0;
+long tx_counter = 0;
int process_mbuf(struct rte_mbuf *pkt)
{
struct ecpri_seq_id seq;
static int symbol_total_bytes = 0;
int num_bytes = 0;
- struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
+ struct xran_device_ctx * p_x_ctx = xran_dev_get_ctx();
+
uint8_t CC_ID = 0;
uint8_t Ant_ID = 0;
uint8_t frame_id = 0;
uint8_t slot_id = 0;
uint8_t symb_id = 0;
+ uint16_t num_prbu;
+ uint16_t start_prbu;
+ uint16_t sym_inc;
+ uint16_t rb;
+ uint16_t sect_id;
+ void *pHandle = NULL;
+ uint8_t num_eAxc = xran_get_num_eAxc(pHandle);
+ int ret = MBUF_FREE;
+ uint32_t mb_free = 0;
+ int32_t valid_res = 0;
+
+
+ if(p_x_ctx->xran2phy_mem_ready == 0)
+ return MBUF_FREE;
+
num_bytes = xran_extract_iq_samples(pkt,
&iq_samp_buf,
&CC_ID,
&subframe_id,
&slot_id,
&symb_id,
- &seq);
- if (num_bytes <= 0)
- return -1;
+ &seq,
+ &num_prbu,
+ &start_prbu,
+ &sym_inc,
+ &rb,
+ §_id);
+
+ if (num_bytes <= 0){
+ print_err("num_bytes is wrong [%d]\n", num_bytes);
+ return MBUF_FREE;
+ }
- symbol_total_bytes += num_bytes;
-
- if (seq.e_bit == 1) {
- print_dbg("Completed receiving symbol %d, size=%d bytes\n",
- symb_id, symbol_total_bytes);
-
- if (symbol_total_bytes)
- xran_process_rx_sym(NULL,
- iq_samp_buf,
- symbol_total_bytes,
- CC_ID,
- Ant_ID,
- frame_id,
- subframe_id,
- slot_id,
- symb_id);
- symbol_total_bytes = 0;
+ valid_res = xran_pkt_validate(NULL,
+ pkt,
+ iq_samp_buf,
+ num_bytes,
+ CC_ID,
+ Ant_ID,
+ frame_id,
+ subframe_id,
+ slot_id,
+ symb_id,
+ &seq,
+ num_prbu,
+ start_prbu,
+ sym_inc,
+ rb,
+ sect_id);
+
+ if(valid_res != 0) {
+ print_err("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes);
+ return MBUF_FREE;
}
- return 0;
+ if (Ant_ID >= num_eAxc && p_x_ctx->fh_init.prachEnable) // PRACH packet has ruportid = num_eAxc + ant_id
+ {
+ Ant_ID -= num_eAxc;
+ if (seq.e_bit == 1) {
+
+ print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",
+ symb_id, num_bytes);
+
+ xran_process_prach_sym(NULL,
+ pkt,
+ iq_samp_buf,
+ num_bytes,
+ CC_ID,
+ Ant_ID,
+ frame_id,
+ subframe_id,
+ slot_id,
+ symb_id,
+ num_prbu,
+ start_prbu,
+ sym_inc,
+ rb,
+ sect_id);
+ }
+ else {
+ print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
+ }
+ } else {
+ symbol_total_bytes += num_bytes;
+
+ if (seq.e_bit == 1) {
+ print_dbg("Completed receiving symbol %d, size=%d bytes\n",
+ symb_id, symbol_total_bytes);
+
+ if (symbol_total_bytes){
+ int res = xran_process_rx_sym(NULL,
+ pkt,
+ iq_samp_buf,
+ symbol_total_bytes,
+ CC_ID,
+ Ant_ID,
+ frame_id,
+ subframe_id,
+ slot_id,
+ symb_id,
+ num_prbu,
+ start_prbu,
+ sym_inc,
+ rb,
+ sect_id,
+ &mb_free);
+ if(res == symbol_total_bytes)
+ ret = mb_free;
+ else
+ print_err("res != symbol_total_bytes\n");
+ }
+ symbol_total_bytes = 0;
+ }
+ else {
+ print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
+ }
+ }
+
+ return ret;
}
static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compression_hdr *compr_hdr)
}
/* Send a single 5G symbol over multiple packets */
-int send_symbol_ex(enum xran_pkt_dir direction,
+int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
uint16_t section_id,
+ struct rte_mbuf *mb,
struct rb_map *data,
+ const enum xran_input_byte_order iq_buf_byte_order,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
int prb_num,
uint8_t CC_ID,
uint8_t RU_Port_ID,
- uint8_t seq_id)
+ uint8_t seq_id,
+ uint32_t do_copy)
{
- const int n_bytes = prb_num * N_SC_PER_PRB * sizeof(struct rb_map);
- int sent;
+ int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+
+ int32_t prep_bytes;
+
+ int16_t nPktSize = sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) +
+ sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes;
uint32_t off;
struct xran_up_pkt_gen_no_compression_params xp = { 0 };
+ n_bytes = RTE_MIN(n_bytes, XRAN_MAX_MBUF_LEN);
+
/* radio app header */
xp.app_params.data_direction = direction;
xp.app_params.payl_ver = 1;
/* network byte order */
xp.sec_hdr.fields.all_bits = rte_cpu_to_be_32(xp.sec_hdr.fields.all_bits);
- struct rte_mbuf *mb = xran_ethdi_mbuf_alloc();
-
if (mb == NULL){
MLogPrint(NULL);
errx(1, "out of mbufs after %d packets", 1);
}
- sent = xran_prepare_iq_symbol_portion_no_comp(mb,
+ prep_bytes = xran_prepare_iq_symbol_portion_no_comp(mb,
data,
+ iq_buf_byte_order,
n_bytes,
&xp,
CC_ID,
RU_Port_ID,
- seq_id);
- if (sent <= 0)
+ seq_id,
+ do_copy);
+ if (prep_bytes <= 0)
errx(1, "failed preparing symbol");
- xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
+ rte_pktmbuf_pkt_len(mb) = nPktSize;
+ rte_pktmbuf_data_len(mb) = nPktSize;
+
+#ifdef DEBUG
+ printf("Symbol %2d prep_bytes (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
+#endif
+
+ return prep_bytes;
+}
+
+/* Send a single 5G symbol over multiple packets */
+int send_symbol_ex(enum xran_pkt_dir direction,
+ uint16_t section_id,
+ struct rte_mbuf *mb,
+ struct rb_map *data,
+ const enum xran_input_byte_order iq_buf_byte_order,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symbol_no,
+ int prb_start,
+ int prb_num,
+ uint8_t CC_ID,
+ uint8_t RU_Port_ID,
+ uint8_t seq_id)
+{
+ uint32_t do_copy = 0;
+ int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+
+ if (mb == NULL){
+ char * pChar = NULL;
+ mb = xran_ethdi_mbuf_alloc(); /* will be freede by ETH */
+ if(mb == NULL){
+ MLogPrint(NULL);
+ errx(1, "out of mbufs after %d packets", 1);
+ }
+ pChar = rte_pktmbuf_append(mb, sizeof(struct xran_ecpri_hdr)+ sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes);
+ if(pChar == NULL){
+ MLogPrint(NULL);
+ errx(1, "incorrect mbuf size %d packets", 1);
+ }
+ pChar = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
+ if(pChar == NULL){
+ MLogPrint(NULL);
+ errx(1, "incorrect mbuf size %d packets", 1);
+ }
+ do_copy = 1; /* new mbuf hence copy of IQs */
+ }else {
+ rte_pktmbuf_refcnt_update(mb, 1); /* make sure eth won't free our mbuf */
+ }
+
+ int32_t sent = prepare_symbol_ex(direction,
+ section_id,
+ mb,
+ data,
+ iq_buf_byte_order,
+ frame_id,
+ subframe_id,
+ slot_id,
+ symbol_no,
+ prb_start,
+ prb_num,
+ CC_ID,
+ RU_Port_ID,
+ seq_id,
+ do_copy);
+
+ if(sent){
+ tx_counter++;
+ xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
+ } else {
+
+ }
+
+
#ifdef DEBUG
printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
return sent;
}
-int send_cpmsg_dlul(void *pHandle, enum xran_pkt_dir dir,
- uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
- uint8_t startsym, uint8_t numsym, int prb_num,
- uint16_t beam_id,
- uint8_t cc_id, uint8_t ru_port_id,
- uint8_t seq_id)
+int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
+ struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)
{
- struct xran_cp_gen_params params;
- struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
- struct rte_mbuf *mbuf;
- int ret, nsection, i;
-
-
- params.dir = dir;
- params.sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels
- params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD;
- params.hdr.frameId = frame_id;
- params.hdr.subframeId = subframe_id;
- params.hdr.slotId = slot_id;
- params.hdr.startSymId = startsym; // start Symbol ID
- params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
- params.hdr.compMeth = xran_get_conf_compmethod(pHandle);
+ int ret = 0, nsection, i;
+ uint8_t frame_id = params->hdr.frameId;
+ uint8_t subframe_id = params->hdr.subframeId;
+ uint8_t slot_id = params->hdr.slotId;
+ uint8_t dir = params->dir;
+
+ nsection = params->numSections;
+
+ /* add in the ethernet header */
+ struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+ xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
+ tx_counter++;
+ for(i=0; i<nsection; i++)
+ xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id,
+ (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
+ §_geninfo[i].info);
+
+ return (ret);
+}
+
+int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
+ enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+ uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,
+ uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t seq_id, uint8_t symInc)
+{
+ int ret = 0, nsection, i;
+
+
+ params->dir = dir;
+ params->sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels
+ params->hdr.filterIdx = XRAN_FILTERINDEX_STANDARD;
+ params->hdr.frameId = frame_id;
+ params->hdr.subframeId = subframe_id;
+ params->hdr.slotId = slot_id;
+ params->hdr.startSymId = startsym; // start Symbol ID
+ params->hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
+ params->hdr.compMeth = comp_method;
nsection = 0;
- sect_geninfo[nsection].info.type = params.sectionType;
+ sect_geninfo[nsection].info.type = params->sectionType; // for database
+ sect_geninfo[nsection].info.startSymId = params->hdr.startSymId; // for database
+ sect_geninfo[nsection].info.iqWidth = params->hdr.iqWidth; // for database
+ sect_geninfo[nsection].info.compMeth = params->hdr.compMeth; // for database
sect_geninfo[nsection].info.id = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
sect_geninfo[nsection].info.rb = XRAN_RBIND_EVERY;
- sect_geninfo[nsection].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
- sect_geninfo[nsection].info.startPrbc = 0;
- sect_geninfo[nsection].info.numPrbc = NUM_OF_PRB_IN_FULL_BAND,
+ sect_geninfo[nsection].info.symInc = symInc;
+ sect_geninfo[nsection].info.startPrbc = prb_start;
+ sect_geninfo[nsection].info.numPrbc = prb_num;
sect_geninfo[nsection].info.numSymbol = numsym;
sect_geninfo[nsection].info.reMask = 0xfff;
sect_geninfo[nsection].info.beamId = beam_id;
- sect_geninfo[nsection].info.ef = 0; // no extension
+ sect_geninfo[nsection].info.ef = 0;
sect_geninfo[nsection].exDataSize = 0;
- sect_geninfo[nsection].exData = NULL;
+// sect_geninfo[nsection].exData = NULL;
nsection++;
- params.numSections = nsection;
- params.sections = sect_geninfo;
+ params->numSections = nsection;
+ params->sections = sect_geninfo;
- mbuf = xran_ethdi_mbuf_alloc();
if(unlikely(mbuf == NULL)) {
print_err("Alloc fail!\n");
return (-1);
- }
+ }
- ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id);
- if(ret < 0) {
+ ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, ru_port_id, seq_id);
+ if(ret < 0){
print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
frame_id, subframe_id, slot_id, dir);
- }
- else {
- xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
- for(i=0; i<nsection; i++)
- xran_cp_add_section_info(pHandle,
- dir, cc_id, ru_port_id, subframe_id, slot_id,
- §_geninfo[i].info);
- }
+ rte_pktmbuf_free(mbuf);
+ }
return (ret);
}
-int send_cpmsg_prach(void *pHandle,
+int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx,
uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
- uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id,
- uint8_t seq_id)
+ uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id)
{
- struct xran_cp_gen_params params;
- struct xran_section_gen_info sect_geninfo[8];
- struct rte_mbuf *mbuf;
int i, nsection, ret;
- struct xran_lib_ctx *pxran_lib_ctx = xran_lib_get_ctx();
xRANPrachCPConfigStruct *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
+ uint16_t timeOffset;
+ uint16_t nNumerology = pxran_lib_ctx->fh_cfg.frame_conf.nNumerology;
+ if(unlikely(mbuf == NULL)) {
+ print_err("Alloc fail!\n");
+ return (-1);
+ }
#if 0
printf("%d:%d:%d:%d - filter=%d, startSym=%d[%d:%d], numSym=%d, occasions=%d, freqOff=%d\n",
frame_id, subframe_id, slot_id, prach_port_id,
pPrachCPConfig->occassionsInPrachSlot,
pPrachCPConfig->freqOffset);
#endif
-
- params.dir = XRAN_DIR_UL;
- params.sectionType = XRAN_CP_SECTIONTYPE_3;
- params.hdr.filterIdx = pPrachCPConfig->filterIdx;
- params.hdr.frameId = frame_id;
- params.hdr.subframeId = subframe_id;
- params.hdr.slotId = slot_id;
- params.hdr.startSymId = pPrachCPConfig->startSymId;
- params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
- params.hdr.compMeth = xran_get_conf_compmethod(pHandle);
+ timeOffset = pPrachCPConfig->timeOffset; //this is the CP value per 38.211 tab 6.3.3.1-1&2
+ timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
+ if (pPrachCPConfig->startSymId > 0)
+ {
+ timeOffset += (pPrachCPConfig->startSymId * 2048) >> nNumerology;
+ if ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME >> 1)))
+ timeOffset += 16;
+ }
+ params->dir = XRAN_DIR_UL;
+ params->sectionType = XRAN_CP_SECTIONTYPE_3;
+ params->hdr.filterIdx = pPrachCPConfig->filterIdx;
+ params->hdr.frameId = frame_id;
+ params->hdr.subframeId = subframe_id;
+ params->hdr.slotId = slot_id;
+ params->hdr.startSymId = pPrachCPConfig->startSymId;
+ params->hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
+ params->hdr.compMeth = xran_get_conf_compmethod(pHandle);
/* use timeOffset field for the CP length value for prach sequence */
- params.hdr.timeOffset = pPrachCPConfig->timeOffset;
- params.hdr.fftSize = xran_get_conf_fftsize(pHandle);
- params.hdr.scs = xran_get_conf_prach_scs(pHandle);
- params.hdr.cpLength = 0;
+ params->hdr.timeOffset = timeOffset;
+ params->hdr.fftSize = xran_get_conf_fftsize(pHandle);
+ params->hdr.scs = xran_get_conf_prach_scs(pHandle);
+ params->hdr.cpLength = 0;
nsection = 0;
- sect_geninfo[nsection].info.type = params.sectionType;
- sect_geninfo[nsection].info.id = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
- sect_geninfo[nsection].info.rb = XRAN_RBIND_EVERY;
- sect_geninfo[nsection].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
- sect_geninfo[nsection].info.startPrbc = pPrachCPConfig->startPrbc;
- sect_geninfo[nsection].info.numPrbc = pPrachCPConfig->numPrbc,
- sect_geninfo[nsection].info.numSymbol = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;
- sect_geninfo[nsection].info.reMask = 0xfff;
- sect_geninfo[nsection].info.beamId = beam_id;
- sect_geninfo[nsection].info.freqOffset= pPrachCPConfig->freqOffset;
-
- sect_geninfo[nsection].info.ef = 0; // no extension
- sect_geninfo[nsection].exDataSize = 0;
- sect_geninfo[nsection].exData = NULL;
- nsection++;
+ sect_geninfo[nsection].info.type = params->sectionType; // for database
+ sect_geninfo[nsection].info.startSymId = params->hdr.startSymId; // for database
+ sect_geninfo[nsection].info.iqWidth = params->hdr.iqWidth; // for database
+ sect_geninfo[nsection].info.compMeth = params->hdr.compMeth; // for database
+ sect_geninfo[nsection].info.id = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
+ sect_geninfo[nsection].info.rb = XRAN_RBIND_EVERY;
+ sect_geninfo[nsection].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
+ sect_geninfo[nsection].info.startPrbc = pPrachCPConfig->startPrbc;
+ sect_geninfo[nsection].info.numPrbc = pPrachCPConfig->numPrbc,
+ sect_geninfo[nsection].info.numSymbol = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;
+ sect_geninfo[nsection].info.reMask = 0xfff;
+ sect_geninfo[nsection].info.beamId = beam_id;
+ sect_geninfo[nsection].info.freqOffset = pPrachCPConfig->freqOffset;
- params.numSections = nsection;
- params.sections = sect_geninfo;
+ pxran_lib_ctx->prach_last_symbol[cc_id] = sect_geninfo[nsection].info.startSymId + sect_geninfo[nsection].info.numSymbol - 1;
- mbuf = xran_ethdi_mbuf_alloc();
- if(unlikely(mbuf == NULL)) {
- print_err("Alloc fail!\n");
- return (-1);
- }
+ sect_geninfo[nsection].info.ef = 0;
+ sect_geninfo[nsection].exDataSize = 0;
+// sect_geninfo[nsection].exData = NULL;
+ nsection++;
- ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, prach_port_id, seq_id);
- if(ret < 0) {
- print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
- return (ret);
- }
- else {
- xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
- for(i=0; i < nsection; i++)
- xran_cp_add_section_info(pHandle,
- XRAN_DIR_UL, cc_id, prach_port_id, subframe_id, slot_id,
- §_geninfo[i].info);
- }
+ params->numSections = nsection;
+ params->sections = sect_geninfo;
- return (ret);
+ ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, prach_port_id, seq_id);
+ if(ret < 0){
+ print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
+ rte_pktmbuf_free(mbuf);
+ }
+ return ret;
}
struct rte_mbuf *mbufs[MBUFS_CNT];
int i;
uint32_t remaining;
+ uint64_t t1;
const uint16_t dequeued = rte_ring_dequeue_burst(r, (void **)mbufs,
RTE_DIM(mbufs), &remaining);
if (!dequeued)
return 0;
+
+ t1 = MLogTick();
for (i = 0; i < dequeued; ++i) {
if (xran_ethdi_filter_packet(mbufs[i], 0) == MBUF_FREE)
rte_pktmbuf_free(mbufs[i]);
}
+ MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
return remaining;
}
-int ring_processing_thread(void *args)
+int32_t ring_processing_func(void)
{
- struct timespec tv = {0};
- int64_t prev_nsec = 0;
- uint8_t is_timer_set = 0;
struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
+ struct xran_device_ctx *const pxran_lib_ctx = xran_dev_get_ctx();
+
+ rte_timer_manage();
+
+ /* UP first */
+ if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
+ return 0;
+ /* CP next */
+ if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
+ return 0;
+
+ if (pxran_lib_ctx->bbdev_dec)
+ pxran_lib_ctx->bbdev_dec();
+
+ if (pxran_lib_ctx->bbdev_enc)
+ pxran_lib_ctx->bbdev_enc();
+
+ if (XRAN_STOPPED == xran_if_current_state)
+ return -1;
+
+ return 0;
+}
+
+int ring_processing_thread(void *args)
+{
struct sched_param sched_param;
int res = 0;
printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
- if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
- {
+ if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){
printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
}
- for (;;) {
- if (!is_timer_set) {
- if (clock_gettime(CLOCK_REALTIME, &tv) != 0)
- err(1, "gettimeofday() failed");
- if (tv.tv_nsec % 125000 < prev_nsec % 125000) { /* crossed an 125ms boundary */
- rte_timer_manage(); /* timers only run on IO core */
- is_timer_set = 1;
- }
- prev_nsec = tv.tv_nsec;
- } else {
- rte_timer_manage();
- }
- /* UP first */
- if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
- continue;
- /* CP next */
- if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
- continue;
-
- if (XRAN_STOPPED == xran_if_current_state)
+ for (;;)
+ if(ring_processing_func() != 0)
break;
- }
puts("Pkt processing thread finished.");
return 0;
}
-#endif /* _XRAN_COMMON_ */
*
*******************************************************************************/
-
/**
* @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
* U-plane
#ifndef _XRAN_COMMON_H_
#define _XRAN_COMMON_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <stdio.h>
#include <unistd.h>
+#include <sys/param.h>
+
#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_timer.h>
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
#include "xran_pkt_up.h"
+#include "xran_cp_api.h"
+
+#define O_DU 0
+#define O_RU 1
-#define APP_LLS_CU 0
-#define APP_RU 1
-#define NUM_OF_PRB_IN_FULL_BAND (66)
#define N_SC_PER_PRB 12
+#define MAX_N_FULLBAND_SC 273
#define N_SYM_PER_SLOT 14
-#define N_FULLBAND_SC (NUM_OF_PRB_IN_FULL_BAND*N_SC_PER_PRB)
-#define MAX_ANT_CARRIER_SUPPORTED 16
-/* 0.125, just for testing */
-#define SLOTNUM_PER_SUBFRAME 8
+#define SUBFRAME_DURATION_US 1000
+#define SLOTNUM_PER_SUBFRAME (SUBFRAME_DURATION_US/interval_us)
#define SUBFRAMES_PER_SYSTEMFRAME 10
#define SLOTS_PER_SYSTEMFRAME (SLOTNUM_PER_SUBFRAME*SUBFRAMES_PER_SYSTEMFRAME)
-#define PDSCH_PAYLOAD_SIZE (N_FULLBAND_SC*4)
-#define NUM_OF_SLOT_IN_TDD_LOOP (80)
-#define IQ_PLAYBACK_BUFFER_BYTES (NUM_OF_SLOT_IN_TDD_LOOP*N_SYM_PER_SLOT*N_FULLBAND_SC*4L)
-/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples. The payload length is 3356 octets.*/
-#define PRACH_PLAYBACK_BUFFER_BYTES (10*839*4L)
+/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples for long sequence or 144*14 (max) for short sequence. The payload length is 3356 octets.*/
+#define PRACH_PLAYBACK_BUFFER_BYTES (144*14*4L)
-#define XRAN_MAX_NUM_SECTIONS (NUM_OF_PRB_IN_FULL_BAND) // TODO: need to decide proper value
+#define XRAN_MAX_NUM_SECTIONS (N_SYM_PER_SLOT*2) /* just an example, no special meaning on this number */
+ /* and this is the configuration of M-plane */
-#define XRAN_MAX_MBUF_LEN 9600 /**< jummbo frame */
-#define NSEC_PER_SEC 1000000000
+#define XRAN_MAX_MBUF_LEN 9600 /**< jumbo frame */
+#define NSEC_PER_SEC 1000000000L
#define TIMER_RESOLUTION_CYCLES 1596*1 /* 1us */
#define XRAN_RING_SIZE 512 /*4*14*8 pow of 2 */
#define XRAN_NAME_MAX_LEN (64)
#define XRAN_RING_NUM (3)
-#define MAX_NUM_OF_XRAN_CTX (2)
-#define XranIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
-#define XranDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
-
#define XranDiffSymIdx(prevSymIdx, currSymIdx, numTotalSymIdx) ((prevSymIdx > currSymIdx) ? ((currSymIdx + numTotalSymIdx) - prevSymIdx) : (currSymIdx - prevSymIdx))
-#define XRAN_SYM_JOB_SIZE 512
-
-struct send_symbol_cb_args
-{
- struct rb_map *samp_buf;
- uint8_t *symb_id;
-};
-
-struct pkt_dump
-{
- int num_samp;
- int num_bytes;
- uint8_t symb;
- struct ecpri_seq_id seq;
-} __rte_packed;
+#define XRAN_MLOG_VAR 0 /**< enable debug variables to mlog */
/* PRACH configuration table defines */
#define XRAN_PRACH_CANDIDATE_PREAMBLE (2)
uint8_t numSymbol;
uint16_t timeOffset;
int32_t freqOffset;
+ uint8_t nrofPrachInSlot;
uint8_t occassionsInPrachSlot;
uint8_t x;
uint8_t y[XRAN_PRACH_CANDIDATE_Y];
uint8_t isPRACHslot[XRAN_PRACH_CANDIDATE_SLOT];
}xRANPrachCPConfigStruct;
+#define XRAN_MAX_POOLS_PER_SECTOR_NR 3 /**< TX_OUT, RX_IN, PRACH_IN */
-typedef struct DeviceHandleInfo
+typedef struct sectorHandleInfo
{
/**< Structure that contains the information to describe the
* instance i.e service type, virtual function, package Id etc..*/
uint16_t nIndex;
+ uint16_t nXranPort;
/* Unique ID of an handle shared between phy layer and library */
/**< number of antennas supported per link*/
uint32_t nBufferPoolIndex;
/**< Buffer poolIndex*/
- struct rte_mempool * p_bufferPool[XRAN_MAX_SECTOR_NR];
- uint32_t bufferPoolElmSz[XRAN_MAX_SECTOR_NR];
- uint32_t bufferPoolNumElm[XRAN_MAX_SECTOR_NR];
+ struct rte_mempool * p_bufferPool[XRAN_MAX_POOLS_PER_SECTOR_NR];
+ uint32_t bufferPoolElmSz[XRAN_MAX_POOLS_PER_SECTOR_NR];
+ uint32_t bufferPoolNumElm[XRAN_MAX_POOLS_PER_SECTOR_NR];
-}XranLibHandleInfoStruct;
+}XranSectorHandleInfo, *PXranSectorHandleInfo;
typedef void (*XranSymCallbackFn)(struct rte_timer *tim, void* arg);
// -1 means that DL packet to be transmitted is not ready in BS
int32_t nSegTransferred; // number of data segments has been transmitted or received
struct rte_mbuf *pData[XRAN_N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
- XRANBufferListStruct sBufferList;
+ struct xran_buffer_list sBufferList;
} BbuIoBufCtrlStruct;
struct xran_sym_job {
#define XranIncrementJob(i) ((i >= (XRAN_SYM_JOB_SIZE-1)) ? 0 : (i+1))
-struct xran_lib_ctx
+#define XRAN_MAX_PKT_BURST_PER_SYM 32
+#define XRAN_MAX_PACKET_FRAG 9
+
+#define MBUF_TABLE_SIZE (2 * MAX(XRAN_MAX_PKT_BURST_PER_SYM, XRAN_MAX_PACKET_FRAG))
+
+struct mbuf_table {
+ uint16_t len;
+ struct rte_mbuf *m_table[MBUF_TABLE_SIZE];
+};
+
+struct xran_device_ctx
{
- uint8_t llscu_id;
uint8_t sector_id;
- XRANEAXCIDCONFIG eAxc_id_cfg;
- XRANFHINIT xran_init_cfg;
- XRANFHCONFIG xran_fh_cfg;
- XranLibHandleInfoStruct* pDevHandle;
+ uint8_t xran_port_id;
+ struct xran_eaxcid_config eAxc_id_cfg;
+ struct xran_fh_init fh_init;
+ struct xran_fh_config fh_cfg;
+ uint32_t enablePrach;
xRANPrachCPConfigStruct PrachCPConfig;
uint32_t enableCP;
- char ring_name[XRAN_RING_NUM][XRAN_MAX_SECTOR_NR][RTE_RING_NAMESIZE];
- struct rte_ring *dl_sym_idx_ring[XRAN_MAX_SECTOR_NR];
- struct rte_ring *xran2phy_ring[XRAN_MAX_SECTOR_NR];
- struct rte_ring *xran2prach_ring[XRAN_MAX_SECTOR_NR];
-
- struct xran_sym_job sym_job[XRAN_SYM_JOB_SIZE];
- uint32_t sym_job_idx;
+ int32_t DynamicSectionEna;
BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
+ BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
/* buffers lists */
- XRANFlatBufferStruct sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
- XRANFlatBufferStruct sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
- XRANFlatBufferStruct sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
- XranTransportBlockCallbackFn pCallback[XRAN_MAX_SECTOR_NR];
+ xran_transport_callback_fn pCallback[XRAN_MAX_SECTOR_NR];
void *pCallbackTag[XRAN_MAX_SECTOR_NR];
- XranTransportBlockCallbackFn pPrachCallback[XRAN_MAX_SECTOR_NR];
+ xran_transport_callback_fn pPrachCallback[XRAN_MAX_SECTOR_NR];
void *pPrachCallbackTag[XRAN_MAX_SECTOR_NR];
XranSymCallbackFn pSymCallback[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
int32_t sym_up; /**< when we start sym 0 of up with respect to OTA time as measured in symbols */
int32_t sym_up_ul;
- XRANFHTTIPROCCB ttiCb[XRAN_CB_MAX];
+ xran_fh_tti_callback_fn ttiCb[XRAN_CB_MAX];
void *TtiCbParam[XRAN_CB_MAX];
uint32_t SkipTti[XRAN_CB_MAX];
int xran2phy_mem_ready;
int rx_packet_symb_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ int rx_packet_prach_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
int rx_packet_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
+ int rx_packet_prach_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
+ int prach_start_symbol[XRAN_MAX_SECTOR_NR];
+ int prach_last_symbol[XRAN_MAX_SECTOR_NR];
+
int phy_tti_cb_done;
+
+ struct rte_mempool *direct_pool;
+ struct rte_mempool *indirect_pool;
+ struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
+
+ struct xran_common_counters fh_counters;
+
+ phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
+ phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
};
+extern long rx_counter;
+extern long tx_counter;
+
extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_fdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_tdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
extern const xRANPrachConfigTableStruct gxranPrachDataTable_mmw[XRAN_PRACH_CONFIG_TABLE_SIZE];
-extern const xRANPrachPreambleLRAStruct gxranPreambleforLRA[XRAN_PRACH_PREAMBLE_FORMAT_OF_ABC];
+extern const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13];
int process_mbuf(struct rte_mbuf *pkt);
int process_ring(struct rte_ring *r);
int send_symbol_ex(enum xran_pkt_dir direction,
uint16_t section_id,
+ struct rte_mbuf *mb,
struct rb_map *data,
+ const enum xran_input_byte_order iq_buf_byte_order,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
uint8_t RU_Port_ID,
uint8_t seq_id);
-int send_cpmsg_dlul(void *pHandle, enum xran_pkt_dir dir,
- uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
- uint8_t startsym, uint8_t numsym, int prb_num,
- uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id,
- uint8_t seq_id);
+int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
+ uint16_t section_id,
+ struct rte_mbuf *mb,
+ struct rb_map *data,
+ const enum xran_input_byte_order iq_buf_byte_order,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symbol_no,
+ int prb_start,
+ int prb_num,
+ uint8_t CC_ID,
+ uint8_t RU_Port_ID,
+ uint8_t seq_id,
+ uint32_t do_copy);
-int send_cpmsg_prach(void *pHandle,
- uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
- uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id,
- uint8_t seq_id);
+int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
+ struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id);
-uint8_t xran_get_max_sections(void *pHandle);
+int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
+ enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+ uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,
+ uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t seq_id, uint8_t symInc);
-XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle);
+int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx,
+ uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
+ uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id);
+
+struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle);
uint8_t xran_get_conf_prach_scs(void *pHandle);
uint8_t xran_get_conf_fftsize(void *pHandle);
uint8_t xran_get_conf_numerology(void *pHandle);
uint8_t xran_get_num_cc(void *pHandle);
uint8_t xran_get_num_eAxc(void *pHandle);
-uint8_t xran_get_llscuid(void *pHandle);
-uint8_t xran_get_sectorid(void *pHandle);
-struct xran_lib_ctx *xran_lib_get_ctx(void);
+struct xran_device_ctx *xran_dev_get_ctx(void);
uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
+int32_t ring_processing_func(void);
+int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx);
+
+#ifdef __cplusplus
+}
+#endif
#endif
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+#include "xran_compression.hpp"
+#include <complex>
+#include <algorithm>
+#include <immintrin.h>
+
+void
+BlockFloatCompander::BlockFloatCompress_AVX512(const ExpandedData& dataIn, CompressedData* dataOut)
+{
+ __m512i maxAbs = __m512i();
+
+ /// Load data and find max(abs(RB))
+ const __m512i* rawData = reinterpret_cast<const __m512i*>(dataIn.dataExpanded);
+ static constexpr int k_numInputLoopIts = BlockFloatCompander::k_numRB / 4;
+
+#pragma unroll(k_numInputLoopIts)
+ for (int n = 0; n < k_numInputLoopIts; ++n)
+ {
+ /// Re-order the next 4RB in input data into 3 registers
+ /// Input SIMD vectors are:
+ /// [A A A A A A A A A A A A B B B B]
+ /// [B B B B B B B B C C C C C C C C]
+ /// [C C C C D D D D D D D D D D D D]
+ /// Re-ordered SIMD vectors are:
+ /// [A A A A B B B B C C C C D D D D]
+ /// [A A A A B B B B C C C C D D D D]
+ /// [A A A A B B B B C C C C D D D D]
+ static constexpr uint8_t k_msk1 = 0b11111100; // Copy first lane of src
+ static constexpr int k_shuff1 = 0x41;
+ const auto z_w1 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 0], k_msk1, rawData[3 * n + 1], rawData[3 * n + 2], k_shuff1);
+
+ static constexpr uint8_t k_msk2 = 0b11000011; // Copy middle two lanes of src
+ static constexpr int k_shuff2 = 0xB1;
+ const auto z_w2 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 1], k_msk2, rawData[3 * n + 0], rawData[3 * n + 2], k_shuff2);
+
+ static constexpr uint8_t k_msk3 = 0b00111111; // Copy last lane of src
+ static constexpr int k_shuff3 = 0xBE;
+ const auto z_w3 = _mm512_mask_shuffle_i64x2(rawData[3 * n + 2], k_msk3, rawData[3 * n + 0], rawData[3 * n + 1], k_shuff3);
+
+ /// Perform max abs on these 3 registers
+ const auto abs16_1 = _mm512_abs_epi16(z_w1);
+ const auto abs16_2 = _mm512_abs_epi16(z_w2);
+ const auto abs16_3 = _mm512_abs_epi16(z_w3);
+ const auto maxAbs_12 = _mm512_max_epi16(abs16_1, abs16_2);
+ const auto maxAbs_123 = _mm512_max_epi16(maxAbs_12, abs16_3);
+
+ /// Perform horizontal max over each lane
+ /// Swap 64b in each lane and compute max
+ static const auto k_perm64b = _mm512_set_epi64(6, 7, 4, 5, 2, 3, 0, 1);
+ auto maxAbsPerm = _mm512_permutexvar_epi64(k_perm64b, maxAbs_123);
+ auto maxAbsHorz = _mm512_max_epi16(maxAbs_123, maxAbsPerm);
+
+ /// Swap each pair of 32b in each lane and compute max
+ static const auto k_perm32b = _mm512_set_epi32(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+ maxAbsPerm = _mm512_permutexvar_epi32(k_perm32b, maxAbsHorz);
+ maxAbsHorz = _mm512_max_epi16(maxAbsHorz, maxAbsPerm);
+
+ /// Swap each IQ pair in each lane (via 32b rotation) and compute max
+ maxAbsPerm = _mm512_rol_epi32(maxAbsHorz, BlockFloatCompander::k_numBitsIQ);
+ maxAbsHorz = _mm512_max_epi16(maxAbsHorz, maxAbsPerm);
+
+ /// Insert values into maxAbs
+ /// Use sliding mask to insert wanted values into maxAbs
+ /// Pairs of values will be inserted and corrected outside of loop
+ static const auto k_select4RB = _mm512_set_epi32(28, 24, 20, 16, 28, 24, 20, 16,
+ 28, 24, 20, 16, 28, 24, 20, 16);
+ static constexpr uint16_t k_expMsk[k_numInputLoopIts] = { 0x000F, 0x00F0, 0x0F00, 0xF000 };
+ maxAbs = _mm512_mask_permutex2var_epi32(maxAbs, k_expMsk[n], k_select4RB, maxAbsHorz);
+ }
+
+ /// Convert to 32b by removing repeated values in maxAbs
+ static const auto k_upperWordMask = _mm512_set_epi64(0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+ 0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+ 0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
+ 0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF);
+ maxAbs = _mm512_and_epi64(maxAbs, k_upperWordMask);
+
+ /// Compute exponent and store for later use
+ static constexpr int k_expTotShiftBits = 32 - BlockFloatCompander::k_iqWidth + 1;
+ const auto totShiftBits = _mm512_set1_epi32(k_expTotShiftBits);
+ const auto lzCount = _mm512_lzcnt_epi32(maxAbs);
+ const auto exponent = _mm512_sub_epi32(totShiftBits, lzCount);
+ int8_t storedExp[BlockFloatCompander::k_numRB] = {};
+ static constexpr uint16_t k_expWriteMask = 0xFFFF;
+ _mm512_mask_cvtepi32_storeu_epi8(storedExp, k_expWriteMask, exponent);
+
+ /// Shift 1RB by corresponding exponent and write exponent and data to output
+ /// Output data is packed exponent first followed by corresponding compressed RB
+#pragma unroll(BlockFloatCompander::k_numRB)
+ for (int n = 0; n < BlockFloatCompander::k_numRB; ++n)
+ {
+ const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(dataIn.dataExpanded + n * BlockFloatCompander::k_numREReal);
+ auto compData = _mm512_srai_epi16(*rawDataIn, storedExp[n]);
+
+ dataOut->dataCompressed[n * (BlockFloatCompander::k_numREReal + 1)] = storedExp[n];
+ static constexpr uint32_t k_rbMask = 0x00FFFFFF; // Write mask for 1RB (24 values)
+ _mm512_mask_cvtepi16_storeu_epi8(dataOut->dataCompressed + n * (BlockFloatCompander::k_numREReal + 1) + 1, k_rbMask, compData);
+ }
+}
+
+
+void
+BlockFloatCompander::BlockFloatExpand_AVX512(const CompressedData& dataIn, ExpandedData* dataOut)
+{
+#pragma unroll(BlockFloatCompander::k_numRB)
+ for (int n = 0; n < BlockFloatCompander::k_numRB; ++n)
+ {
+ /// Expand 1RB of data
+ const __m256i* rawDataIn = reinterpret_cast<const __m256i*>(dataIn.dataCompressed + n * (BlockFloatCompander::k_numREReal + 1) + 1);
+ const auto compData16 = _mm512_cvtepi8_epi16(*rawDataIn);
+ const auto expData = _mm512_slli_epi16(compData16, *(dataIn.dataCompressed + n * (BlockFloatCompander::k_numREReal + 1)));
+
+ /// Write expanded data to output
+ static constexpr uint8_t k_rbMask64 = 0b00111111; // 64b write mask for 1RB (24 int16 values)
+ _mm512_mask_storeu_epi64(dataOut->dataExpanded + n * BlockFloatCompander::k_numREReal, k_rbMask64, expData);
+ }
+}
+
+
+void
+BlockFloatCompander::BlockFloatCompress_Basic(const ExpandedData& dataIn, CompressedData* dataOut)
+{
+ int16_t maxAbs[BlockFloatCompander::k_numRB];
+ for (int rb = 0; rb < BlockFloatCompander::k_numRB; ++rb)
+ {
+ // Find max abs value for this RB
+ maxAbs[rb] = 0;
+ for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+ {
+ auto dataIdx = rb * BlockFloatCompander::k_numREReal + re;
+ int16_t dataAbs = (int16_t)std::abs(dataIn.dataExpanded[dataIdx]);
+ maxAbs[rb] = std::max(maxAbs[rb], dataAbs);
+ }
+
+ // Find exponent
+ static constexpr int k_expTotShiftBits16 = 16 - BlockFloatCompander::k_iqWidth + 1;
+ auto thisExp = (int8_t)(k_expTotShiftBits16 - __lzcnt16(maxAbs[rb]));
+ auto expIdx = rb * (BlockFloatCompander::k_numREReal + 1);
+ dataOut->dataCompressed[expIdx] = thisExp;
+
+ // ARS data by exponent
+ for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+ {
+ auto dataIdxIn = rb * BlockFloatCompander::k_numREReal + re;
+ auto dataIdxOut = (expIdx + 1) + re;
+ dataOut->dataCompressed[dataIdxOut] = (int8_t)(dataIn.dataExpanded[dataIdxIn] >> thisExp);
+ }
+ }
+}
+
+
+void
+BlockFloatCompander::BlockFloatExpand_Basic(const CompressedData& dataIn, ExpandedData* dataOut)
+{
+ // Expand data
+ for (int rb = 0; rb < BlockFloatCompander::k_numRB; ++rb)
+ {
+ for (int re = 0; re < BlockFloatCompander::k_numREReal; ++re)
+ {
+ auto dataIdxOut = rb * BlockFloatCompander::k_numREReal + re;
+ auto expIdx = rb * (BlockFloatCompander::k_numREReal + 1);
+ auto dataIdxIn = (expIdx + 1) + re;
+ auto thisData = (int16_t)dataIn.dataCompressed[dataIdxIn];
+ auto thisExp = (int16_t)dataIn.dataCompressed[expIdx];
+ dataOut->dataExpanded[dataIdxOut] = (int16_t)(thisData << thisExp);
+ }
+ }
+}
*
*******************************************************************************/
-
/**
* @brief This file provides the API functions to build Control Plane Messages
* for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
#include "xran_common.h"
#include "xran_transport.h"
#include "xran_cp_api.h"
-#include "xran_hash.h"
#include "xran_printf.h"
+/**
+ * This structure to store the section information of C-Plane
+ * in order to generate and parse corresponding U-Plane */
struct xran_sectioninfo_db {
- uint32_t max_num;
- uint32_t cur_index;
-#if defined(XRAN_CP_USES_HASHTABLE)
- struct rte_hash *hash;
-#endif
- struct xran_section_info *list;
+ uint32_t cur_index; /**< Current index to store fro this eAXC */
+ struct xran_section_info list[XRAN_MAX_NUM_SECTIONS]; /**< The array of section information */
};
+static struct xran_sectioninfo_db sectiondb[XRAN_MAX_SECTIONDB_CTX][XRAN_DIR_MAX][XRAN_COMPONENT_CARRIERS_MAX][XRAN_MAX_ANTENNA_NR*2];
-static struct xran_sectioninfo_db *sectiondb[XRAN_DIR_MAX];
+/**
+ * @brief Initialize section database.
+ * Allocate required memory space to store section information.
+ * Each eAxC allocates dedicated storage and the entry size is the maximum number of sections.
+ * Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
+ */
int xran_cp_init_sectiondb(void *pHandle)
{
- int i, j, k;
- uint32_t size;
- uint16_t cid;
- struct xran_sectioninfo_db *ptr;
- uint8_t num_eAxc;
+ int ctx, dir, cc, ant;
+ for(ctx=0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++)
+ for(dir=0; dir < XRAN_DIR_MAX; dir++)
+ for(cc=0; cc < XRAN_COMPONENT_CARRIERS_MAX; cc++)
+ for(ant=0; ant < XRAN_MAX_ANTENNA_NR*2; ant++)
+ sectiondb[ctx][dir][cc][ant].cur_index = 0;
-#if !defined(PRACH_USES_SHARED_PORT)
- num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
- num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
- for(i=0; i < XRAN_DIR_MAX; i++) {
- size = (xran_get_num_cc(pHandle) * num_eAxc * sizeof(struct xran_sectioninfo_db));
- print_log("Allocation Size for Section DB : %d (%dx%dx%ld)", size
- , xran_get_num_cc(pHandle)
- , num_eAxc
- , sizeof(struct xran_sectioninfo_db));
- sectiondb[i] = malloc(size);
-
- if(sectiondb[i] == NULL) {
- print_err("Allocation Failed for Section DB!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
- }
-
- for(j=0; j < xran_get_num_cc(pHandle); j++) { // CC
- for(k=0; k < num_eAxc; k++) { // antenna
- ptr = sectiondb[i] + num_eAxc*j + k;
-
- ptr->max_num = xran_get_max_sections(pHandle);
- ptr->cur_index = 0;
-
- // allicate array to store section information
- size = sizeof(struct xran_section_info)*xran_get_max_sections(pHandle);
- print_log("Allocation Size for list : %d (%ldx%d)", size,
- sizeof(struct xran_section_info),
- xran_get_max_sections(pHandle));
- ptr->list = malloc(size);
- if(ptr-> list == NULL) {
- print_err("Allocation Failed for Section DB!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
- }
-
-#if defined(XRAN_CP_USES_HASHTABLE)
- // Create hash table for section information
- cid = rte_be_to_cpu_16(xran_compose_cid(xran_get_llscuid(pHandle), xran_get_sectorid(pHandle), j, k));
- print_log("Creating hash for %04X", cid);
- ptr->hash = xran_section_init_hash(i, cid, xran_get_max_sections(pHandle));
-#endif
- }
- }
- }
-
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
+/**
+ * @brief Release and free section database
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ */
int xran_cp_free_sectiondb(void *pHandle)
{
- int i, j, k;
- uint32_t size;
- struct xran_sectioninfo_db *ptr;
- uint8_t num_eAxc;
-
-#if !defined(PRACH_USES_SHARED_PORT)
- num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
- num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
- for(i=0; i < XRAN_DIR_MAX; i++) {
- for(j=0; j < xran_get_num_cc(pHandle); j++) { // CC
- for(k=0; k < num_eAxc; k++) { // antenna
- ptr = sectiondb[i] + num_eAxc*j + k;
-
-#if defined(XRAN_CP_USES_HASHTABLE)
- xran_section_free_hash(ptr->hash);
-#endif
- if(ptr->list != NULL)
- free(ptr->list);
- else print_err("list is NULL");
- }
- }
- if(sectiondb[i] != NULL)
- free(sectiondb[i]);
- else print_err("sectiondb[%d] is NULL", i);
- }
-
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
-static struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
- uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+static inline struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
+ uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
{
struct xran_sectioninfo_db *ptr;
- uint8_t num_eAxc;
- if(unlikely(dir>=XRAN_DIR_MAX)) {
+
+ if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
+ print_err("Invalid Context id - %d", ctx_id);
+ return (NULL);
+ }
+
+ if(unlikely(dir >= XRAN_DIR_MAX)) {
print_err("Invalid direction - %d", dir);
return (NULL);
}
- if(unlikely(cc_id >= xran_get_num_cc(pHandle))) {
+ if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
print_err("Invalid CC id - %d", cc_id);
return (NULL);
}
-#if !defined(PRACH_USES_SHARED_PORT)
- num_eAxc = xran_get_num_eAxc(pHandle) * 2;
-#else
- num_eAxc = xran_get_num_eAxc(pHandle);
-#endif
-
- if(unlikely(ruport_id >= num_eAxc)) {
+ if(unlikely(ruport_id >= XRAN_MAX_ANTENNA_NR*2)) {
print_err("Invalid eAxC id - %d", ruport_id);
return (NULL);
}
- ptr = sectiondb[dir] + xran_get_num_eAxc(pHandle)*cc_id + ruport_id;
+ ptr = §iondb[ctx_id][dir][cc_id][ruport_id];
return(ptr);
}
-static struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
+static inline struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
{
if(unlikely(ptr == NULL))
return (NULL);
- if(unlikely(ptr->max_num < index)) {
+ if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
print_err("Index is out of range - %d", index);
return (NULL);
}
return(&(ptr->list[index]));
}
+/**
+ * @brief Add a section information of C-Plane to dabase.
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @param dir
+ * Direction of C-Plane message for the section to store
+ * @param cc_id
+ * CC ID of C-Plane message for the section to store
+ * @param ruport_id
+ * RU port ID of C-Plane message for the section to store
+ * @param ctx_id
+ * Context index for the section database
+ * @param info
+ * The information of this section to store
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARAM, if direction, CC ID or RU port ID is incorrect
+ * XRAN_STATUS_RESOURCE, if no more space to add on database
+ */
int xran_cp_add_section_info(void *pHandle,
- uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id,
+ uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
struct xran_section_info *info)
{
struct xran_sectioninfo_db *ptr;
struct xran_section_info *list;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL)) {
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
- if(unlikely(ptr->cur_index >= ptr->max_num)) {
+ if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
print_err("No more space to add section information!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
+ return (XRAN_STATUS_RESOURCE);
}
list = xran_get_section_info(ptr, ptr->cur_index);
rte_memcpy(list, info, sizeof(struct xran_section_info));
-#if defined(XRAN_CP_USES_HASHTABLE)
- xran_section_add_hash(ptr->hash, info->id, ptr->cur_index);
-#endif
ptr->cur_index++;
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
int xran_cp_add_multisection_info(void *pHandle,
- uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id,
- uint8_t num_sections, struct xran_section_gen_info *gen_info)
+ uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
+ struct xran_cp_gen_params *gen_info)
{
int i;
+ uint8_t dir, num_sections;
struct xran_sectioninfo_db *ptr;
struct xran_section_info *list;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+
+ dir = gen_info->dir;
+ num_sections = gen_info->numSections;
+
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL)) {
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
- if(unlikely(ptr->cur_index >= (ptr->max_num+num_sections))) {
+ if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
print_err("No more space to add section information!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
+ return (XRAN_STATUS_RESOURCE);
}
list = xran_get_section_info(ptr, ptr->cur_index);
for(i=0; i<num_sections; i++) {
- rte_memcpy(&list[i], &gen_info[i].info, sizeof(struct xran_section_info));
-#if defined(XRAN_CP_USES_HASHTABLE)
- xran_section_add_hash(ptr->hash, gen_info[i].info.id, ptr->cur_index);
-#endif
+ rte_memcpy(&list[i], &gen_info->sections[i].info, sizeof(struct xran_section_info));
ptr->cur_index++;
}
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
+/**
+ * @brief Find a section information of C-Plane from dabase
+ * by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @param dir
+ * The direction of the section to find
+ * @param cc_id
+ * The CC ID of the section to find
+ * @param ruport_id
+ * RU port ID of the section to find
+ * @param ctx_id
+ * Context index for the section database
+ * @param section_id
+ * The ID of section to find
+ * @return
+ * The pointer of section information if matched section is found
+ * NULL if failed to find matched section
+ */
struct xran_section_info *xran_cp_find_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id,
- uint16_t section_id)
+ uint8_t ctx_id, uint16_t section_id)
{
- int index;
+ int index, num_index;
struct xran_sectioninfo_db *ptr;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL))
return (NULL);
-#if defined(XRAN_CP_USES_HASHTABLE)
- index = xran_section_lookup(ptr->hash, section_id);
- if(unlikely(index > ptr->max_num)) {
- print_err("Invalid index - %d", index);
- return (NULL);
- }
-
- if(index < 0) {
- print_dbg("No section ID in the list - %d", section_id);
- return (NULL);
- }
+ if(ptr->cur_index > XRAN_MAX_NUM_SECTIONS)
+ num_index = XRAN_MAX_NUM_SECTIONS;
+ else
+ num_index = ptr->cur_index;
- return (xran_get_section_info(ptr, index));
-#else
- for(index=0; index<ptr->cur_index; index++) {
+ for(index=0; index < num_index; index++) {
if(ptr->list[index].id == section_id) {
- print_dbg("Found section info %04X", section_id);
return (xran_get_section_info(ptr, index));
}
}
print_dbg("No section ID in the list - %d", section_id);
return (NULL);
-#endif
-
}
+/**
+ * @brief Iterate each section information of C-Plane
+ * from the database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @param dir
+ * The direction of the section to find
+ * @param cc_id
+ * The CC ID of the section to find
+ * @param ruport_id
+ * RU port ID of the section to find
+ * @param ctx_id
+ * Context index for the section database
+ * @param next
+ * The pointer to store the position of next entry
+ * @return
+ * The pointer of section information in the list
+ * NULL if reached at the end of the list
+ */
struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
- uint8_t subframe_id, uint8_t slot_id, uint32_t *next)
+ uint8_t ctx_id, uint32_t *next)
{
int index;
struct xran_sectioninfo_db *ptr;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL))
return (NULL);
-#if defined(XRAN_CP_USES_HASHTABLE)
- index = xran_section_iterate(ptr->hash, next);
- if(unlikely(index > ptr->max_num)) {
- print_err("Invalid index - %d", index);
- return (NULL);
- }
-
- if(index < 0) {
- print_dbg("No section ID in the list - %d", section_id);
- return (NULL);
- }
-
- return (xran_get_section_info(ptr, index));
-#else
index = *next;
if(*next < ptr->cur_index) {
(*next)++;
return (xran_get_section_info(ptr, index));
}
- else
+ else {
print_dbg("No more sections in the list");
-
- return (NULL);
-#endif
+ return (NULL);
+ }
}
-int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+/**
+ * @brief Get the size of stored entries
+ * for the database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @param dir
+ * The direction of the section to find
+ * @param cc_id
+ * The CC ID of the section to find
+ * @param ruport_id
+ * RU port ID of the section to find
+ * @param ctx_id
+ * Context index for the section database
+ * @return
+ * The size of stored entries
+ * -1 if failed to find matched database
+ */
+int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
{
int i, index;
struct xran_sectioninfo_db *ptr;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL))
return (-1);
return (ptr->cur_index);
}
-int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
+/**
+ * @brief Reset a database of eAxC by given information
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param pHandle
+ * handle for xRAN interface, currently not being used
+ * @param dir
+ * The direction of the section to find
+ * @param cc_id
+ * The CC ID of the section to find
+ * @param ruport_id
+ * RU port ID of the section to find
+ * @param ctx_id
+ * Context index for the section database
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if failed to find matched database
+ */
+int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
{
struct xran_sectioninfo_db *ptr;
- ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
+ ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
if(unlikely(ptr == NULL)) {
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
ptr->cur_index = 0;
-#if defined(XRAN_CP_USES_HASHTABLE)
- xran_section_reset_hash(ptr->hash);
-#endif
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
+
int xran_dump_sectiondb(void)
{
// TODO:
return (0);
}
-
// Cyclic Prefix Length 5.4.4.14
-// CP_length = cpLength * Ts * 2^u, Ts = 1/30.72MHz, if u is N/A, it shall be zero
+// CP_length = cpLength * Ts, Ts = 1/30.72MHz
+// i.e cpLength = CP_length / Ts ?
#define CPLEN_TS (30720000)
-inline uint16_t xran_get_cplength(int cpLength, int uval) // uval = -1 for N/A
+inline uint16_t xran_get_cplength(int CP_length)
{
- return ((cpLength * ((uval<0)?0:(2<<uval))) / (CPLEN_TS));
+ return (CP_length);
}
// Frequency offset 5.4.5.11
-// frequency_offset = freqOffset * SCS * 0.5
-inline int32_t xran_get_freqoffset(int freqOffset, int scs)
+// frequency_offset = freqOffset * SCS * 0.5
+// i.e freqOffset = (frequency_offset *2 )/ SCS ?
+inline int32_t xran_get_freqoffset(int32_t freqOffset, int32_t scs)
{
- return ((freqOffset * scs)>>1);
+ return (freqOffset);
+}
+
+
+static int xran_prepare_sectionext_1(struct rte_mbuf *mbuf,
+ struct xran_sectionext1_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext1 *ext1;
+ uint8_t *data;
+ int parm_size, iq_size;
+ int total_len;
+ static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
+ ext1 = (struct xran_cp_radioapp_section_ext1 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext1 == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ total_len += parm_size;
+
+ ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
+ ext1->ef = last_flag;
+ ext1->bfwCompMeth = params->bfwCompMeth;
+ ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(params->bfwiqWidth);
+
+ switch(params->bfwCompMeth) {
+ case XRAN_BFWCOMPMETHOD_BLKFLOAT:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = (params->bfwCompParam.exponent & 0x0f);
+ break;
+
+ case XRAN_BFWCOMPMETHOD_BLKSCALE:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = params->bfwCompParam.blockScaler;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_ULAW:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = params->bfwCompParam.compBitWidthShift;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_BEAMSPACE:
+#if 0
+ parm_size = ceil(params->bfwNumber/8)*8;
+#else
+ parm_size = params->bfwNumber>>3;
+ if(params->bfwNumber%8) parm_size++;
+ parm_size *= 8;
+#endif
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, params->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
+ total_len += parm_size;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_NONE:
+ default:
+ parm_size = 0;
+ }
+
+ iq_size = params->bfwNumber * params->bfwiqWidth * 2;
+#if 0
+ parm_size = ceil(iq_size/8);
+#else
+ parm_size = iq_size>>3;
+ if(iq_size%8) parm_size++;
+#endif
+
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, params->bfwIQ, parm_size);
+
+ total_len += parm_size;
+ parm_size = total_len % XRAN_SECTIONEXT_ALIGN;
+ if(parm_size) {
+ parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, zeropad, parm_size);
+ total_len += parm_size;
+ }
+
+ ext1->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_2(struct rte_mbuf *mbuf,
+ struct xran_sectionext2_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext2 *ext2;
+ uint8_t *data;
+ int total_len;
+ int parm_size;
+ uint32_t val, shift_val;
+ int val_size;
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
+ ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext2 == NULL) {
+ print_err("Fail to allocate the space for section extension 2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+
+ ext2->extType = XRAN_CP_SECTIONEXTCMD_2;
+ ext2->ef = last_flag;
+ ext2->bfZe3ddWidth = params->bfZe3ddWidth;
+ ext2->bfAz3ddWidth = params->bfAz3ddWidth;
+ ext2->bfZePtWidth = params->bfZePtWidth;
+ ext2->bfAzPtWidth = params->bfAzPtWidth;
+ ext2->bfaCompResv0 = 0;
+ ext2->bfaCompResv1 = 0;
+
+ val = 0;
+ shift_val = 0;
+ if(params->bfAzPtWidth) {
+ val += params->bfAzPt;
+ shift_val += 8 - (params->bfAzPtWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfZePtWidth) {
+ val = val << (params->bfZePtWidth+1);
+ val += params->bfZePt;
+ shift_val += 8 - (params->bfZePtWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfAz3ddWidth) {
+ val = val << (params->bfAz3ddWidth+1);
+ val += params->bfAz3dd;
+ shift_val += 8 - (params->bfAz3ddWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfZe3ddWidth) {
+ val = val << (params->bfZe3ddWidth+1);
+ val += params->bfZe3dd;
+ shift_val += 8 - (params->bfZe3ddWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(val) {
+ val = val << shift_val;
+ val = rte_cpu_to_be_32(val);
+ }
+
+ val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
+ parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
+
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+
+ rte_memcpy(data, &val, val_size);
+ data += val_size;
+ *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
+
+ ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+ *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_4(struct rte_mbuf *mbuf,
+ struct xran_sectionext4_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext4 *ext4;
+ int parm_size;
+ int total_len;
+ int ret;
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
+ ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext4 == NULL) {
+ print_err("Fail to allocate the space for section extension 4");
+ return(XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
+ ext4->ef = last_flag;
+ ext4->modCompScaler = params->modCompScaler;
+ ext4->csf = params->csf?1:0;
+ ext4->extLen = 1;
+
+ *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
+ }
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_5(struct rte_mbuf *mbuf,
+ struct xran_sectionext5_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext5_1 *ext5_1;
+ struct xran_cp_radioapp_section_ext5_2 *ext5_2;
+ int parm_size;
+ int total_len;
+ uint32_t *data;
+
+
+ total_len = 0;
+
+ if(params->num_sets == 1) {
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext5_1);
+ ext5_1 = (struct xran_cp_radioapp_section_ext5_1 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext5_1 == NULL) {
+ print_err("Fail to allocate the space for section extension 5-1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext5_1->extType = XRAN_CP_SECTIONEXTCMD_5;
+ ext5_1->ef = last_flag;
+
+ ext5_1->mcScaleOffset = params->mc[0].mcScaleOffset;
+ ext5_1->csf = params->mc[0].csf;
+ ext5_1->mcScaleReMask = params->mc[0].mcScaleReMask;
+ ext5_1->reserved = 0;
+
+ ext5_1->extLen = 2;
+
+ *(uint64_t *)ext5_1 = rte_cpu_to_be_64(*(uint64_t *)ext5_1);
+ }
+ }
+ else if(params->num_sets == 2) {
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext5_2);
+ ext5_2 = (struct xran_cp_radioapp_section_ext5_2 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext5_2 == NULL) {
+ print_err("Fail to allocate the space for section extension 5-2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext5_2->extType = XRAN_CP_SECTIONEXTCMD_5;
+ ext5_2->ef = last_flag;
+
+ ext5_2->mcScaleOffset1 = params->mc[0].mcScaleOffset;
+ ext5_2->csf1 = params->mc[0].csf;
+ ext5_2->mcScaleReMask1 = params->mc[0].mcScaleReMask;
+ ext5_2->mcScaleOffset2 = params->mc[1].mcScaleOffset;
+ ext5_2->csf2 = params->mc[1].csf;
+ ext5_2->mcScaleReMask2 = params->mc[1].mcScaleReMask;
+
+ ext5_2->reserved0 = 0;
+ ext5_2->reserved1 = 0;
+
+ ext5_2->extLen = 3;
+
+ *(uint64_t *)ext5_2 = rte_cpu_to_be_64(*(uint64_t *)ext5_2);
+ data = (uint32_t *)((uint8_t *)ext5_2 + 8);
+ *data = rte_cpu_to_be_32(*data);
+ }
+ }
+ else {
+ print_err("Invalid number of scalar values - %d", params->num_sets);
+ return (XRAN_STATUS_INVALID_PARAM);
+ }
+
+ return (total_len);
+}
+
+/**
+ * @brief add section extension to C-Plane packet
+ *
+ * @param mbuf
+ * A pointer to the packet buffer
+ * @param params
+ * A porinter to the information to generate a C-Plane packet
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
+{
+ int i, ret;
+ uint32_t totalen;
+ int last_flag;
+ int ext_size;
+
+
+ if(unlikely(params->exDataSize >= XRAN_MAX_NUM_EXTENSIONS)) {
+ print_err("Invalid total number of extensions - %d", params->exDataSize);
+ return (XRAN_STATUS_INVALID_PARAM);
+ }
+
+ totalen = 0;
+
+
+ ret = XRAN_STATUS_SUCCESS;
+
+ for(i=0; i < params->exDataSize; i++) {
+ if(params->exData[i].data == NULL) {
+ print_err("Invalid parameter - extension data %d is NULL", i);
+ ret = XRAN_STATUS_INVALID_PARAM;
+ continue;
+ }
+
+// params->exData[].len
+ last_flag = ((params->exDataSize - i)==1)?0:1;
+ switch(params->exData[i].type) {
+ case XRAN_CP_SECTIONEXTCMD_1:
+ ext_size = xran_prepare_sectionext_1(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_2:
+ ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_4:
+ ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_5:
+ ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
+ break;
+
+ case XRAN_CP_SECTIONEXTCMD_0:
+ case XRAN_CP_SECTIONEXTCMD_3:
+ default:
+ print_err("Extension Type %d is not supported!", params->exData[i].type);
+ ret = XRAN_STATUS_INVALID_PARAM;
+ ext_size = 0;
+ }
+
+ if(ext_size == XRAN_STATUS_RESOURCE) {
+ break;
+ }
+
+ totalen += ext_size;
+ }
+
+ return (totalen);
}
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
*/
static int xran_prepare_section0(
struct xran_cp_radioapp_section0 *section,
#if (XRAN_STRICT_PARM_CHECK)
if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
print_err("Invalid number of Symbols - %d", params->info.numSymbol);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
#endif
- section->hdr.sectionId = params->info.id;
- section->hdr.rb = params->info.rb;
- section->hdr.symInc = params->info.symInc;
- section->hdr.startPrbc = params->info.startPrbc;
- section->hdr.numPrbc = params->info.numPrbc;
+ section->hdr.sectionId = params->info.id;
+ section->hdr.rb = params->info.rb;
+ section->hdr.symInc = params->info.symInc;
+ section->hdr.startPrbc = params->info.startPrbc;
+ section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
section->hdr.u.s0.reMask = params->info.reMask;
section->hdr.u.s0.numSymbol = params->info.numSymbol;
// for network byte order
*((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @brief Fill the section header of type 0 in C-Plane packet
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS always
*/
static int xran_prepare_section0_hdr(
struct xran_cp_radioapp_section0_header *s0hdr,
s0hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
s0hdr->reserved = 0;
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
*/
static int xran_prepare_section1(
struct xran_cp_radioapp_section1 *section,
#if (XRAN_STRICT_PARM_CHECK)
if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
print_err("Invalid number of Symbols - %d", params->info.numSymbol);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
#endif
section->hdr.rb = params->info.rb;
section->hdr.symInc = params->info.symInc;
section->hdr.startPrbc = params->info.startPrbc;
- section->hdr.numPrbc = params->info.numPrbc;
+ section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
section->hdr.u.s1.reMask = params->info.reMask;
section->hdr.u.s1.numSymbol = params->info.numSymbol;
section->hdr.u.s1.beamId = params->info.beamId;
- if(params->info.ef) {
- // TODO: need to handle extension
- print_err("Extension is not supported!");
- section->hdr.u.s1.ef = 0;
-// section->hdr.u.s1.ef = params->info.ef;
- }
- else
- section->hdr.u.s1.ef = 0;
+ section->hdr.u.s1.ef = params->info.ef;
// for network byte order
*((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @brief Fill the section header of type 1 in C-Plane packet
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS always
*/
static int xran_prepare_section1_hdr(
struct xran_cp_radioapp_section1_header *s1hdr,
s1hdr->udComp.udCompMeth = params->hdr.compMeth;
s1hdr->reserved = 0;
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
*/
static int xran_prepare_section3(
struct xran_cp_radioapp_section3 *section,
#if (XRAN_STRICT_PARM_CHECK)
if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
print_err("Invalid number of Symbols - %d", params->info.numSymbol);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
#endif
section->hdr.rb = params->info.rb;
section->hdr.symInc = params->info.symInc;
section->hdr.startPrbc = params->info.startPrbc;
- section->hdr.numPrbc = params->info.numPrbc;
+ section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
section->hdr.u.s3.reMask = params->info.reMask;
section->hdr.u.s3.numSymbol = params->info.numSymbol;
section->freqOffset = rte_cpu_to_be_32(params->info.freqOffset)>>8;
section->reserved = 0;
- if(params->info.ef) {
- // TODO: need to handle extension
- print_err("Extension is not supported!");
- section->hdr.u.s3.ef = 0;
-// section->hdr.u.s3.ef = params->info.ef;
- }
- else
- section->hdr.u.s3.ef = 0;
+ section->hdr.u.s3.ef = params->info.ef;
// for network byte order (header, 8 bytes)
*((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @brief Fill the section header of type 3 in C-Plane packet
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS always
*/
static int xran_prepare_section3_hdr(
struct xran_cp_radioapp_section3_header *s3hdr,
s3hdr->udComp.udIqWidth = params->hdr.iqWidth;
s3hdr->udComp.udCompMeth = params->hdr.compMeth;
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
*/
int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
{
- int i, ret;
+ int i, ret, ext_flag;
uint32_t totalen;
void *section;
int section_size;
section_size = 0;
xran_prepare_section_func = NULL;
print_err("Section Type %d is not supported!", params->sectionType);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
if(unlikely(xran_prepare_section_func == NULL)) {
print_err("Section Type %d is not supported!", params->sectionType);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
for(i=0; i<params->numSections; i++) {
section = rte_pktmbuf_append(mbuf, section_size);
if(section == NULL) {
print_err("Fail to allocate the space for section[%d]!", i);
- return (-XRAN_ERRCODE_OUTOFMEMORY);
- }
-
- if(unlikely(xran_prepare_section_func((void *)section,
- (void *)¶ms->sections[i]) < 0)) {
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_RESOURCE);
}
+ ret = xran_prepare_section_func((void *)section,
+ (void *)¶ms->sections[i]);
+ if(ret < 0)
+ return (ret);
totalen += section_size;
+
+ if(params->sections[i].info.ef) {
+ ret = xran_append_section_extensions(mbuf, ¶ms->sections[i]);
+ if(ret < 0)
+ return (ret);
+ totalen += ret;
+ }
}
return (totalen);
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
*/
static inline int xran_prepare_radioapp_common_header(
struct xran_cp_radioapp_common_header *apphdr,
#if (XRAN_STRICT_PARM_CHECK)
if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
print_err("Invalid direction!");
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
print_err("Invalid Slot ID!");
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
print_err("Invalid Symbol ID!");
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
#endif
apphdr->numOfSections = params->numSections;
apphdr->sectionType = params->sectionType;
- // radio app header has common parts of 4bytes for all section types
+ /* radio app header has common parts of 4bytes for all section types */
*((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
/**
* @param params
* A porinter to the information to generate a C-Plane packet
* @return
- * 0 on success; non zero on failure
+ * The length of added section (>0) on success
+ * XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
*/
int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
{
#if (XRAN_STRICT_PARM_CHECK)
if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
print_err("Invalid Section Type - %d", params->sectionType);
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
#endif
switch(params->sectionType) {
- case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
+ case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section0_hdr;
totalen = sizeof(struct xran_cp_radioapp_section0_header);
break;
- case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
+ case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section1_hdr;
totalen = sizeof(struct xran_cp_radioapp_section1_header);
break;
- case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
+ case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section3_hdr;
totalen = sizeof(struct xran_cp_radioapp_section3_header);
break;
- case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
- case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
- case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
+ case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
+ case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
+ case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
default:
print_err("Section Type %d is not supported!", params->sectionType);
xran_prepare_radioapp_section_hdr_func = NULL;
totalen = 0;
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
if(unlikely(apphdr == NULL)) {
print_err("Fail to reserve the space for radio application header!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
+ return (XRAN_STATUS_RESOURCE);
}
ret = xran_prepare_radioapp_common_header(apphdr, params);
}
if(likely(xran_prepare_radioapp_section_hdr_func)) {
- xran_prepare_radioapp_section_hdr_func(apphdr, params);
+ totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
}
else {
print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
- return (-XRAN_ERRCODE_INVALIDPARAM);
+ return (XRAN_STATUS_INVALID_PARAM);
}
return (totalen);
* @param seq_id
* Sequence ID for this C-Plane message
* @return
- * 0 on success; non zero on failure
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ * XRAN_STATUS_INVALID_PARM if section type is invalid
*/
int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
struct xran_cp_gen_params *params,
struct xran_ecpri_hdr *ecpri_hdr;
- ecpri_hdr = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
- if(unlikely(ecpri_hdr == NULL)) {
- print_err("Fail to allocate the space for eCPRI hedaer!");
- return (-XRAN_ERRCODE_OUTOFMEMORY);
- }
-
- ecpri_hdr->ecpri_ver = XRAN_ECPRI_VER;
- ecpri_hdr->ecpri_resv = 0; // should be zero
- ecpri_hdr->ecpri_concat = 0;
- ecpri_hdr->ecpri_mesg_type = ECPRI_RT_CONTROL_DATA;
- ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
- ecpri_hdr->ecpri_seq_id.seq_id = seq_id;
-
- /* TODO: Transport layer fragmentation is not supported */
- ecpri_hdr->ecpri_seq_id.sub_seq_id = 0;
- ecpri_hdr->ecpri_seq_id.e_bit = 1;
-
- payloadlen = 0;
+ payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
ret = xran_append_radioapp_header(mbuf, params);
if(ret < 0) {
}
payloadlen += ret;
-// printf("Total Payload length = %d\n", payloadlen);
- ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
+ /* set payload length */
+ ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
- return (XRAN_ERRCODE_OK);
+ return (XRAN_STATUS_SUCCESS);
}
+
///////////////////////////////////////
-// for Debug
-int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
+// for RU emulation
+/**
+ * @brief Parse a C-Plane packet (for RU emulation)
+ * Transport layer fragmentation is not supported.
+ *
+ * @ingroup xran_cp_pkt
+ *
+ * @param mbuf
+ * The pointer of the packet buffer to be parsed
+ * @param params
+ * The pointer of structure to store the information of parsed packet
+ * @param eaxc
+ * The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
+ */
+int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
+ struct xran_cp_gen_params *result,
+ struct xran_recv_packet_info *pkt_info)
{
struct xran_ecpri_hdr *ecpri_hdr;
struct xran_cp_radioapp_common_header *apphdr;
int extlen;
- ret = 0;
- ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
- if(ecpri_hdr == NULL) {
- print_err("Invalid packet - eCPRI hedaer!");
- return (-XRAN_ERRCODE_INVALIDPACKET);
- }
-
- /* Process eCPRI header. */
- if(ecpri_hdr->ecpri_ver != XRAN_ECPRI_VER) {
- print_err("Invalid eCPRI version - %d", ecpri_hdr->ecpri_ver);
- ret = -XRAN_ERRCODE_INVALIDPACKET;
- }
-
- if(ecpri_hdr->ecpri_resv != 0) {
- print_err("Invalid reserved field - %d", ecpri_hdr->ecpri_resv);
- ret = -XRAN_ERRCODE_INVALIDPACKET;
- }
-
- if(ecpri_hdr->ecpri_mesg_type != ECPRI_RT_CONTROL_DATA) {
- print_err("Not C-Plane Message - %d", ecpri_hdr->ecpri_mesg_type);
- ret = -XRAN_ERRCODE_INVALIDPACKET;
- }
-#if 0
- printf("[CPlane] [%04X:%03d-%3d-%d] len=%5d\n",
- rte_be_to_cpu_16(ecpri_hdr->ecpri_xtc_id),
- ecpri_hdr->ecpri_seq_id.seq_id, ecpri_hdr->ecpri_seq_id.sub_seq_id,
- ecpri_hdr->ecpri_seq_id.e_bit,
- rte_be_to_cpu_16(ecpri_hdr->ecpri_payl_size));
-#endif
+ ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
+ if(ret < 0 && ecpri_hdr == NULL)
+ return (XRAN_STATUS_INVALID_PACKET);
/* Process radio header. */
apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
if(apphdr == NULL) {
print_err("Invalid packet - radio app hedaer!");
- return (-XRAN_ERRCODE_INVALIDPACKET);
+ return (XRAN_STATUS_INVALID_PACKET);
}
*((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
if(apphdr->payloadVer != XRAN_PAYLOAD_VER) {
print_err("Invalid Payload version - %d", apphdr->payloadVer);
- ret = -XRAN_ERRCODE_INVALIDPACKET;
+ ret = XRAN_STATUS_INVALID_PACKET;
}
result->dir = apphdr->dataDirection;
result->sectionType = apphdr->sectionType;
result->numSections = apphdr->numOfSections;
+#if 0
+ printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
+ pkt_info->payload_len,
+ pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
+ pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
+ result->dir?"DL":"UL",
+ pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
+ result->sectionType, result->numSections,
+ result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
+ result->hdr.startSymId
+ );
+#endif
+
switch(apphdr->sectionType) {
case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
{
result->hdr.timeOffset = hdr->frameStructure.uScs;
result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
//hdr->reserved; /* should be zero */
-
+
section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
if(section == NULL) {
print_err("Invalid packet 0 - radio app hedaer!");
- return (-XRAN_ERRCODE_INVALIDPACKET);
+ return (XRAN_STATUS_INVALID_PACKET);
}
for(i=0; i<result->numSections; i++) {
*((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
print_err("Invalid packet 0 - number of section [%d:%d]!",
result->numSections, i);
result->numSections = i;
- ret = (-XRAN_ERRCODE_INVALIDPACKET);
+ ret = XRAN_STATUS_INVALID_PACKET;
break;
}
}
section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
if(section == NULL) {
print_err("Invalid packet 1 - radio app hedaer!");
- return (-XRAN_ERRCODE_INVALIDPACKET);
+ return (XRAN_STATUS_INVALID_PACKET);
}
for(i=0; i<result->numSections; i++) {
print_err("Invalid packet 1 - number of section [%d:%d]!",
result->numSections, i);
result->numSections = i;
- ret = (-XRAN_ERRCODE_INVALIDPACKET);
+ ret = XRAN_STATUS_INVALID_PACKET;
break;
}
}
section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
if(section == NULL) {
print_err("Invalid packet 3 - radio app hedaer!");
- return (-XRAN_ERRCODE_INVALIDPACKET);
+ return (XRAN_STATUS_INVALID_PACKET);
}
for(i=0; i<result->numSections; i++) {
if(section->reserved) {
print_err("Invalid packet 3 - section[%d:%d]", i, section->reserved);
- ret = -XRAN_ERRCODE_INVALIDPACKET;
+ ret = XRAN_STATUS_INVALID_PACKET;
}
if(section->hdr.u.s3.ef) {
print_err("Invalid packet 3 - number of section [%d:%d]!",
result->numSections, i);
result->numSections = i;
- ret = (-XRAN_ERRCODE_INVALIDPACKET);
+ ret = XRAN_STATUS_INVALID_PACKET;
break;
}
}
case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
default:
- ret = -XRAN_ERRCODE_INVALIDPARAM;
+ ret = XRAN_STATUS_INVALID_PARAM;
print_err("Non-supported Section Type - %d", apphdr->sectionType);
}
result->hdr.iqWidth, result->hdr.compMeth);
for(i=0; i<result->numSections; i++) {
- printf(" >> %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02X numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
+ printf(" >> %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
i, result->sections[i].info.id,
result->sections[i].info.rb,
result->sections[i].info.symInc, result->sections[i].info.numSymbol,
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+/**
+ * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
+ * U-plane
+ * @file xran_common.c
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#include <assert.h>
+#include <err.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "xran_frame_struct.h"
+#include "xran_printf.h"
+
+enum nXranChBwOptions
+{
+ XRAN_BW_5_0_MHZ = 5, XRAN_BW_10_0_MHZ = 10, XRAN_BW_15_0_MHZ = 15, XRAN_BW_20_0_MHZ = 20, XRAN_BW_25_0_MHZ = 25,
+ XRAN_BW_30_0_MHZ = 30, XRAN_BW_40_0_MHZ = 40, XRAN_BW_50_0_MHZ = 50, XRAN_BW_60_0_MHZ = 60, XRAN_BW_70_0_MHZ = 70,
+ XRAN_BW_80_0_MHZ = 80, XRAN_BW_90_0_MHZ = 90, XRAN_BW_100_0_MHZ = 100, XRAN_BW_200_0_MHZ = 200, XRAN_BW_400_0_MHZ = 400
+};
+
+// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+static uint16_t nNumRbsPerSymF1[3][13] =
+{
+ // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+ {25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0}, // Numerology 0 (15KHz)
+ {11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273}, // Numerology 1 (30KHz)
+ {0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135} // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+static uint16_t nNumRbsPerSymF2[2][4] =
+{
+ // 50Mhz 100MHz 200MHz 400MHz
+ {66, 132, 264, 0}, // Numerology 2 (60KHz)
+ {32, 66, 132, 264} // Numerology 3 (120KHz)
+};
+
+// 38.211 - Table 4.2.1
+static uint16_t nSubCarrierSpacing[5] =
+{
+ 15, // mu = 0
+ 30, // mu = 1
+ 60, // mu = 2
+ 120, // mu = 3
+ 240 // mu = 4
+};
+
+// TTI interval in us (slot duration)
+static uint16_t nTtiInterval[4] =
+{
+ 1000, // mu = 0
+ 500, // mu = 1
+ 250, // mu = 2
+ 125, // mu = 3
+};
+
+// F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
+static uint16_t nCpSizeF1[3][13][2] =
+{
+ // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
+ {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, // Numerology 0 (15KHz)
+ {{22, 18}, {44, 36}, {66, 54}, {88, 72}, {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}}, // Numerology 1 (30KHz)
+ { {0, 0}, {26, 18}, {39, 27}, {52, 36}, {52, 36}, {78, 54}, {104, 72}, {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}}, // Numerology 2 (60KHz)
+};
+
+// F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
+static int16_t nCpSizeF2[2][4][2] =
+{
+ // 50Mhz 100MHz 200MHz 400MHz
+ { {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
+ {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
+};
+
+static uint32_t xran_fs_max_slot_num = 8000;
+static uint16_t xran_fs_num_slot_tdd_loop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
+static uint16_t xran_fs_num_dl_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint16_t xran_fs_num_ul_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
+static uint8_t xran_fs_slot_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
+static uint8_t xran_fs_slot_symb_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP][XRAN_NUM_OF_SYMBOL_PER_SLOT] = {{{XRAN_SLOT_TYPE_INVALID}}};
+static float xran_fs_ul_rate[XRAN_MAX_SECTOR_NR] = {0.0};
+static float xran_fs_dl_rate[XRAN_MAX_SECTOR_NR] = {0.0};
+
+uint32_t xran_fs_get_tti_interval(uint8_t nMu)
+{
+ if (nMu < 4)
+ {
+ return nTtiInterval[nMu];
+ }
+ else
+ {
+ printf("ERROR: %s Mu[%d] is not valid, setting to 0\n",__FUNCTION__, nMu);
+ return nTtiInterval[0];
+ }
+}
+
+uint32_t xran_fs_get_scs(uint8_t nMu)
+{
+ if (nMu <= 3)
+ {
+ return nSubCarrierSpacing[nMu];
+ }
+ else
+ {
+ printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ * @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
+ * @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ * @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ * @return Number of RBs in cell
+ *
+ * @description
+ * Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
+{
+ uint32_t error = 1;
+ uint16_t numRBs = 0;
+
+ if (nAbsFrePointA <= 6000000)
+ {
+ // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+ if (nNumerology < 3)
+ {
+ switch(nBandwidth)
+ {
+ case XRAN_BW_5_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][0];
+ error = 0;
+ break;
+ case XRAN_BW_10_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][1];
+ error = 0;
+ break;
+ case XRAN_BW_15_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][2];
+ error = 0;
+ break;
+ case XRAN_BW_20_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][3];
+ error = 0;
+ break;
+ case XRAN_BW_25_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][4];
+ error = 0;
+ break;
+ case XRAN_BW_30_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][5];
+ error = 0;
+ break;
+ case XRAN_BW_40_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][6];
+ error = 0;
+ break;
+ case XRAN_BW_50_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][7];
+ error = 0;
+ break;
+ case XRAN_BW_60_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][8];
+ error = 0;
+ break;
+ case XRAN_BW_70_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][9];
+ error = 0;
+ break;
+ case XRAN_BW_80_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][10];
+ error = 0;
+ break;
+ case XRAN_BW_90_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][11];
+ error = 0;
+ break;
+ case XRAN_BW_100_0_MHZ:
+ numRBs = nNumRbsPerSymF1[nNumerology][12];
+ error = 0;
+ break;
+ default:
+ error = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if ((nNumerology >= 2) && (nNumerology <= 3))
+ {
+ // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
+ switch(nBandwidth)
+ {
+ case XRAN_BW_50_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][0];
+ error = 0;
+ break;
+ case XRAN_BW_100_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][1];
+ error = 0;
+ break;
+ case XRAN_BW_200_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][2];
+ error = 0;
+ break;
+ case XRAN_BW_400_0_MHZ:
+ numRBs = nNumRbsPerSymF2[nNumerology-2][3];
+ error = 0;
+ break;
+ default:
+ error = 1;
+ break;
+ }
+ }
+ }
+
+
+ if (error)
+ {
+ printf("ERROR: %s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA);
+ }
+ else
+ {
+ printf("%s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA, numRBs);
+ }
+
+ return numRBs;
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ * @param[in] center frequency
+ *
+ * @return NR-ARFCN
+ *
+ * @description
+ * This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq)
+{
+ uint32_t nDeltaFglobal,nFoffs,nNoffs;
+ uint32_t nNRARFCN = 0;
+
+ if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
+ {
+ nDeltaFglobal = 5;
+ nFoffs = 0;
+ nNoffs = 0;
+ }
+ else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
+ {
+ nDeltaFglobal = 15;
+ nFoffs = 3000*1000;
+ nNoffs = 600000;
+ }
+ else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
+ {
+ nDeltaFglobal = 60;
+ nFoffs = 24250080;
+ nNoffs = 2016667;
+ }
+ else
+ {
+ printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
+ return (0);
+ }
+
+ nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
+
+ printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
+ return (nNRARFCN);
+}
+
+uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us)
+{
+ xran_fs_max_slot_num = (1000/tti_interval_us)*1000;
+ return xran_fs_max_slot_num;
+}
+
+uint32_t xran_fs_get_max_slot(void)
+{
+ return xran_fs_max_slot_num;
+}
+
+int32_t xran_fs_slot_limit(int32_t nSfIdx)
+{
+ while (nSfIdx < 0) {
+ nSfIdx += xran_fs_max_slot_num;
+ }
+
+ while (nSfIdx >= xran_fs_max_slot_num) {
+ nSfIdx -= xran_fs_max_slot_num;
+ }
+
+ return nSfIdx;
+}
+
+void xran_fs_clear_slot_type(uint32_t nPhyInstanceId)
+{
+ xran_fs_ul_rate[nPhyInstanceId] = 0.0;
+ xran_fs_dl_rate[nPhyInstanceId] = 0.0;
+ xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
+}
+
+int32_t xran_fs_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig)
+{
+ uint32_t nSlotNum, nSymNum, nVal, i, j;
+ uint32_t numDlSym, numUlSym, numGuardSym;
+ uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
+ char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
+
+ // nPhyInstanceId Carrier ID
+ // nFrameDuplexType 0 = FDD 1 = TDD
+ // nTddPeriod Tdd Periodicity
+ // psSlotConfig[80] Slot Config Structure for nTddPeriod Slots
+
+ xran_fs_ul_rate[nPhyInstanceId] = 0.0;
+ xran_fs_dl_rate[nPhyInstanceId] = 0.0;
+ xran_fs_num_slot_tdd_loop[nPhyInstanceId] = nTddPeriod;
+
+ for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+ {
+ xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
+ xran_fs_num_dl_sym_sp[nPhyInstanceId][i] = 0;
+ xran_fs_num_ul_sym_sp[nPhyInstanceId][i] = 0;
+ }
+
+ if (nFrameDuplexType == XRAN_FDD)
+ {
+ for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
+ {
+ xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
+ for(j = 0; j < XRAN_NUM_OF_SYMBOL_PER_SLOT; j++)
+ xran_fs_slot_symb_type[nPhyInstanceId][i][j] = XRAN_SYMBOL_TYPE_FDD;
+ }
+ xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
+ xran_fs_dl_rate[nPhyInstanceId] = 1.0;
+ xran_fs_ul_rate[nPhyInstanceId] = 1.0;
+ }
+ else
+ {
+ for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
+ {
+ numDlSym = 0;
+ numUlSym = 0;
+ numGuardSym = 0;
+ for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
+ {
+ switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
+ {
+ case XRAN_SYMBOL_TYPE_DL:
+ numDlSym++;
+ xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_DL;
+ break;
+ case XRAN_SYMBOL_TYPE_GUARD:
+ xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_GUARD;
+ numGuardSym++;
+ break;
+ default:
+ xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_UL;
+ numUlSym++;
+ break;
+ }
+ }
+
+ print_dbg("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d] ", nSlotNum, numDlSym, numGuardSym, numUlSym);
+
+ if ((numUlSym == 0) && (numGuardSym == 0))
+ {
+ xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
+ numDlSlots++;
+ print_dbg("XRAN_SLOT_TYPE_DL\n");
+ }
+ else if ((numDlSym == 0) && (numGuardSym == 0))
+ {
+ xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
+ numUlSlots++;
+ print_dbg("XRAN_SLOT_TYPE_UL\n");
+ }
+ else
+ {
+ xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
+ numSpSlots++;
+ print_dbg("XRAN_SLOT_TYPE_SP\n");
+
+ if (numDlSym)
+ {
+ numSpDlSlots++;
+ xran_fs_num_dl_sym_sp[nPhyInstanceId][nSlotNum] = numDlSym;
+ }
+ if (numUlSym)
+ {
+ numSpUlSlots++;
+ xran_fs_num_ul_sym_sp[nPhyInstanceId][nSlotNum] = numUlSym;
+ }
+ }
+ print_dbg(" numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
+ }
+
+ xran_fs_dl_rate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
+ xran_fs_ul_rate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
+ }
+
+ print_dbg("%s: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
+ __FUNCTION__, nPhyInstanceId, nFrameDuplexType, nTddPeriod);
+
+ print_dbg("DLRate[%f] ULRate[%f]\n", xran_fs_dl_rate[nPhyInstanceId], xran_fs_ul_rate[nPhyInstanceId]);
+
+ nVal = (xran_fs_num_slot_tdd_loop[nPhyInstanceId] < 10) ? xran_fs_num_slot_tdd_loop[nPhyInstanceId] : 10;
+
+ print_dbg("SlotPattern:\n");
+ print_dbg("Slot: ");
+ for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
+ {
+ print_dbg("%d ", nSlotNum);
+ }
+ print_dbg("\n");
+
+ print_dbg(" %3d ", 0);
+ for (nSlotNum = 0, i = 0; nSlotNum < xran_fs_num_slot_tdd_loop[nPhyInstanceId]; nSlotNum++)
+ {
+ print_dbg("%s ", sSlotPattern[xran_fs_slot_type[nPhyInstanceId][nSlotNum]]);
+ i++;
+ if ((i == 10) && ((nSlotNum+1) < xran_fs_num_slot_tdd_loop[nPhyInstanceId]))
+ {
+ print_dbg("\n");
+ print_dbg(" %3d ", nSlotNum);
+ i = 0;
+ }
+ }
+ print_dbg("\n\n");
+
+ return 0;
+}
+
+int32_t xran_fs_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
+{
+ int32_t nSfIdxMod, nSfType, ret = 0;
+
+ nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
+ nSfType = xran_fs_slot_type[nCellIdx][nSfIdxMod];
+
+ if (nSfType == nType)
+ {
+ ret = 1;
+ }
+ else if (nSfType == XRAN_SLOT_TYPE_SP)
+ {
+ if ((nType == XRAN_SLOT_TYPE_DL) && xran_fs_num_dl_sym_sp[nCellIdx][nSfIdxMod])
+ {
+ ret = 1;
+ }
+
+ if ((nType == XRAN_SLOT_TYPE_UL) && xran_fs_num_ul_sym_sp[nCellIdx][nSfIdxMod])
+ {
+ ret = 1;
+ }
+ }
+ else if (nSfType == XRAN_SLOT_TYPE_FDD)
+ {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx)
+{
+ int32_t nSfIdxMod, nSfType, ret = 0;
+
+ nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
+
+ return xran_fs_slot_symb_type[nCellIdx][nSfIdxMod][nSymbIdx];
+}
+
+
--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2019 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+
+/**
+ * @brief Header file for function to work with 5G NR frame structure and related
+ * routines
+ * @file xran_frame_struct.h
+ * @ingroup group_source_xran
+ * @author Intel Corporation
+ **/
+
+#ifndef _XRAN_FRAME_STRUCT_
+#define _XRAN_FRAME_STRUCT_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "xran_fh_o_du.h"
+
+uint32_t xran_fs_get_tti_interval(uint8_t nMu);
+uint32_t xran_fs_get_scs(uint8_t nMu);
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_nr5g_source_phy_common
+ *
+ * @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
+ * @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
+ * @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
+ *
+ * @return Number of RBs in cell
+ *
+ * @description
+ * Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup phy_cal_nrarfcn
+ *
+ * @param[in] center frequency
+ *
+ * @return NR-ARFCN
+ *
+ * @description
+ * This calculates NR-ARFCN value according to center frequency
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq);
+int32_t xran_fs_slot_limit(int32_t nSlotIdx);
+void xran_fs_clear_slot_type(uint32_t nCcId);
+int32_t xran_fs_set_slot_type(uint32_t nCcId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig);
+int32_t xran_fs_get_slot_type(int32_t nCcId, int32_t nSlotIdx, int32_t nType);
+uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us);
+uint32_t xran_fs_get_max_slot(void);
+int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XRAN_FRAME_STRUCT_ */
+
+++ /dev/null
-/******************************************************************************
-*
-* Copyright (c) 2019 Intel.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-*******************************************************************************/
-
-
-/**
- * @brief Definitions and support functions to process XRAN packet
- * @file xran_hash.h
- * @ingroup group_source_xran
- * @author Intel Corporation
- **/
-
-#ifndef _XRAN_HASH_H
-#define _XRAN_HASH_H
-
-#include <rte_common.h>
-#include <rte_hash.h>
-#include <rte_hash_crc.h>
-
-#define DEFAULT_HASH_FUNC rte_hash_crc
-
-
-struct rte_hash *xran_section_init_hash(uint16_t dir, uint16_t cid, int max_num_sections);
-void xran_section_free_hash(struct rte_hash *hash);
-
-void xran_section_reset_hash(struct rte_hash *hash);
-int xran_section_add_hash(const struct rte_hash *hash, uint16_t section_id, int index);
-int xran_section_lookup(const struct rte_hash *hash, uint16_t section_id);
-int xran_section_iterate(const struct rte_hash *hash, uint32_t *next);
-
-#endif
#ifndef _XRAN_TASK_ID_H_
#define _XRAN_TASK_ID_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define RESOURCE_CORE_0 0
#define RESOURCE_CORE_1 1
#define RESOURCE_CORE_2 2
#define PID_PROCESS_CP_PKT 2700
+#ifdef __cplusplus
+}
+#endif
#endif /* _XRAN_TASK_ID_H_ */
*
*******************************************************************************/
-
/**
* @brief XRAN main functionality module
* @file xran_main.c
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
+#include <malloc.h>
#include <rte_eal.h>
#include <rte_errno.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memzone.h>
+#include <rte_mbuf.h>
#include <rte_ring.h>
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
#include "ethdi.h"
#include "xran_pkt.h"
#include "xran_lib_mlog_tasks_id.h"
#include "xran_timer.h"
#include "xran_common.h"
+#include "xran_frame_struct.h"
#include "xran_printf.h"
+#include "xran_app_frag.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_mlog_lnx.h"
#define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
(((int32_t)otaSym - (int32_t)offSym) - numSymTotal) : \
((int32_t)otaSym - (int32_t)offSym))
-#define MAX_NUM_OF_XRAN_CTX (2)
+#define MAX_NUM_OF_XRAN_CTX (2)
#define XranIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
#define XranDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
+#define MAX_NUM_OF_DPDK_TIMERS (10)
+#define DpdkTiemerIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_DPDK_TIMERS-1)) ? 0 : (ctx+1))
+#define DpdkTiemerDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_DPDK_TIMERS-1) : (ctx-1))
+
+
+//#define XRAN_CREATE_RBMAP /**< generate slot map base on symbols */
+
+
struct xran_timer_ctx {
uint32_t tti_to_process;
};
-static XranLibHandleInfoStruct DevHandle;
-static struct xran_lib_ctx g_xran_lib_ctx = { 0 };
+static xran_cc_handle_t pLibInstanceHandles[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR] = {NULL};
+static struct xran_device_ctx g_xran_dev_ctx[XRAN_PORTS_NUM] = { 0 };
struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX];
static struct rte_timer tti_to_phy_timer[10];
-static struct rte_timer tti_timer;
static struct rte_timer sym_timer;
-static struct rte_timer tx_cp_dl_timer;
-static struct rte_timer tx_cp_ul_timer;
-static struct rte_timer tx_up_timer;
+static struct rte_timer dpdk_timer[MAX_NUM_OF_DPDK_TIMERS];
-static long interval_us = 125;
+long interval_us = 1000;
-uint32_t xran_lib_ota_tti = 0; /* [0:7999] */
-uint32_t xran_lib_ota_sym = 0; /* [0:7] */
-uint32_t xran_lib_ota_sym_idx = 0; /* [0 : 14*8*1000-1] */
+uint32_t xran_lib_ota_tti = 0; /* [0:(1000000/TTI-1)] */
+uint32_t xran_lib_ota_sym = 0; /* [0:1000/TTI-1] */
+uint32_t xran_lib_ota_sym_idx = 0; /* [0 : 14*(1000000/TTI)-1]
+ where TTI is TTI interval in microseconds */
-uint64_t xran_lib_gps_second = 0;
+static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR * 2]; //XRAN_MAX_ANTENNA_NR * 2 for PUSCH and PRACH
+static uint8_t xran_updl_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
+static uint8_t xran_upul_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
-static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR];
-static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
-static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
+static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
+static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2];
void xran_timer_arm(struct rte_timer *tim, void* arg);
+
int xran_process_tx_sym(void *arg);
int xran_process_rx_sym(void *arg,
+ struct rte_mbuf *mbuf,
void *iq_data_start,
uint16_t size,
uint8_t CC_ID,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
- uint8_t symb_id);
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id,
+ uint32_t *mb_free);
+
+int xran_process_prach_sym(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id);
void tti_ota_cb(struct rte_timer *tim, void *arg);
void tti_to_phy_cb(struct rte_timer *tim, void *arg);
void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore);
-struct xran_lib_ctx *xran_lib_get_ctx(void)
+struct xran_device_ctx *xran_dev_get_ctx(void)
{
- return &g_xran_lib_ctx;
+ return &g_xran_dev_ctx[0];
}
-static inline XRANFHCONFIG *xran_lib_get_ctx_fhcfg(void)
+static inline struct xran_fh_config *xran_lib_get_ctx_fhcfg(void)
{
- return (&(xran_lib_get_ctx()->xran_fh_cfg));
+ return (&(xran_dev_get_ctx()->fh_cfg));
}
-inline uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
+uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
{
return (0); // NO BEAMFORMING
}
+enum xran_if_state xran_get_if_state(void)
+{
+ return xran_if_current_state;
+}
+
+int xran_isPRACHSlot(uint32_t subframe_id, uint32_t slot_id)
+{
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
+ int isPRACHslot = 0;
+
+ if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology < 2){
+ //for FR1, in 38.211 tab 6.3.3.2-2&3 it is subframe index
+ if (pPrachCPConfig->isPRACHslot[subframe_id] == 1){
+ if (pPrachCPConfig->nrofPrachInSlot != 1)
+ isPRACHslot = 1;
+ else{
+ if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 0)
+ isPRACHslot = 1;
+ else if (slot_id == 1)
+ isPRACHslot = 1;
+ }
+ }
+ }
+ else if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 3){
+ //for FR2, 38.211 tab 6.3.3.4 it is slot index of 60kHz slot
+ uint32_t slotidx;
+ slotidx = subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
+ if (pPrachCPConfig->nrofPrachInSlot == 2){
+ if (pPrachCPConfig->isPRACHslot[slotidx>>1] == 1)
+ isPRACHslot = 1;
+ }
+ else{
+ if ((pPrachCPConfig->isPRACHslot[slotidx>>1] == 1) && (slotidx % 2 == 1))
+ isPRACHslot = 1;
+ }
+ }
+ else
+ print_err("Numerology %d not supported", p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology);
+ return isPRACHslot;
+}
+
int xran_init_sectionid(void *pHandle)
{
int cell, dir, ant;
return (0);
}
-int xran_init_seqid(void *pHandle)
+int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx)
{
- int cell, dir, ant;
+ int32_t i;
+ uint8_t slotNr;
+ struct xran_prach_config* pPRACHConfig = &(pConf->prach_conf);
+ const xRANPrachConfigTableStruct *pxRANPrachConfigTable;
+ uint8_t nNumerology = pConf->frame_conf.nNumerology;
+ uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
+ xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
- for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
- for(dir=0; dir < XRAN_DIR_MAX; dir++) {
- for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) {
- xran_cp_seq_id_num[cell][dir][ant] = 0;
- }
- }
+ if (nNumerology > 2)
+ pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
+ else if (pConf->frame_conf.nFrameDuplexType == 1)
+ pxRANPrachConfigTable = &gxranPrachDataTable_sub6_tdd[nPrachConfIdx];
+ else
+ pxRANPrachConfigTable = &gxranPrachDataTable_sub6_fdd[nPrachConfIdx];
+
+ uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
+ const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt];
+ memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct));
+ if(pConf->log_level)
+ printf("xRAN open PRACH config: Numerology %u ConfIdx %u, preambleFmrt %u startsymb %u, numSymbol %u, occassionsInPrachSlot %u\n", nNumerology, nPrachConfIdx, preambleFmrt, pxRANPrachConfigTable->startingSym, pxRANPrachConfigTable->duration, pxRANPrachConfigTable->occassionsInPrachSlot);
+
+ pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC; // 3, PRACH preamble format A1~3, B1~4, C0, C2
+ pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
+ pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
+ pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
+ pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
+ pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
+ pPrachCPConfig->x = pxRANPrachConfigTable->x;
+ pPrachCPConfig->nrofPrachInSlot = pxRANPrachConfigTable->nrofPrachInSlot;
+ pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
+ pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
+ if (preambleFmrt >= FORMAT_A1)
+ {
+ pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
+ pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
+ }
+ else
+ {
+ pPrachCPConfig->numSymbol = 1;
+ pPrachCPConfig->occassionsInPrachSlot = 1;
+ }
+
+ if(pConf->log_level)
+ printf("PRACH: x %u y[0] %u, y[1] %u prach slot: %u ..", pPrachCPConfig->x, pPrachCPConfig->y[0], pPrachCPConfig->y[1], pxRANPrachConfigTable->slotNr[0]);
+ pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
+ for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
+ {
+ slotNr = pxRANPrachConfigTable->slotNr[i];
+ if (slotNr > 0){
+ pPrachCPConfig->isPRACHslot[slotNr] = 1;
+ if(pConf->log_level)
+ printf(" %u ..", slotNr);
}
+ }
+ printf("\n");
+ for (i = 0; i < XRAN_MAX_SECTOR_NR; i++){
+ p_xran_dev_ctx->prach_start_symbol[i] = pPrachCPConfig->startSymId;
+ p_xran_dev_ctx->prach_last_symbol[i] = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol * pPrachCPConfig->occassionsInPrachSlot - 1;
+ }
+ if(pConf->log_level){
+ printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]);
+ }
- return (0);
+ return (XRAN_STATUS_SUCCESS);
}
inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
print_err("Invalid CC ID - %d", cc_id);
return (0);
}
- if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { //for PRACH, ant_id starts from num_ant
print_err("Invalid antenna ID - %d", ant_id);
return (0);
- }
+ }
/* if new slot has been started,
* then initializes section id again for new start */
if(xran_section_id_curslot[cc_id][ant_id] != slot_id) {
xran_section_id[cc_id][ant_id] = 0;
xran_section_id_curslot[cc_id][ant_id] = slot_id;
- }
-
+ }
+
return(xran_section_id[cc_id][ant_id]++);
}
-inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
+int xran_init_seqid(void *pHandle)
+{
+ int cell, dir, ant;
+
+ for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
+ for(dir=0; dir < XRAN_DIR_MAX; dir++) {
+ for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++)
+ xran_cp_seq_id_num[cell][dir][ant] = 0;
+ }
+ for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++)
+ xran_updl_seq_id_num[cell][ant] = 0;
+ for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++)
+ xran_upul_seq_id_num[cell][ant] = 0;
+ }
+
+ return (0);
+}
+
+static inline uint8_t xran_get_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id)
{
if(dir >= XRAN_DIR_MAX) {
print_err("Invalid direction - %d", dir);
print_err("Invalid CC ID - %d", cc_id);
return (0);
}
- if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
print_err("Invalid antenna ID - %d", ant_id);
return (0);
}
return(xran_cp_seq_id_num[cc_id][dir][ant_id]++);
}
+static inline uint8_t xran_get_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (0);
+ }
+ if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (0);
+ }
-inline int xran_update_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+ /* Only U-Plane DL needs to get sequence ID in O-DU */
+ return(xran_updl_seq_id_num[cc_id][ant_id]++);
+}
+static inline uint8_t *xran_get_updl_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
{
- return (0);
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (0);
+ }
+ if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (0);
+ }
+
+ /* Only U-Plane DL needs to get sequence ID in O-DU */
+ return(&xran_updl_seq_id_num[cc_id][ant_id]);
+}
+static inline int8_t xran_check_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+{
+
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (-1);
+ }
+
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (-1);
+ }
+
+ /* O-DU needs to check the sequence ID of U-Plane UL from O-RU */
+ xran_upul_seq_id_num[cc_id][ant_id]++;
+ if(xran_upul_seq_id_num[cc_id][ant_id] == seq_id) { /* expected sequence */
+ return (XRAN_STATUS_SUCCESS);
+ } else {
+ print_err("expected seqid %u received %u, slot %u, ant %u cc %u", xran_upul_seq_id_num[cc_id][ant_id], seq_id, slot_id, ant_id, cc_id);
+ xran_upul_seq_id_num[cc_id][ant_id] = seq_id; // for next
+ return (-1);
+ }
}
//////////////////////////////////////////
// For RU emulation
-static struct xran_section_gen_info cpSections[255];
+static inline uint8_t xran_get_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (0);
+ }
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (0);
+ }
+
+ return(xran_upul_seq_id_num[cc_id][ant_id]++);
+}
+static inline uint8_t *xran_get_upul_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
+{
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (0);
+ }
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (0);
+ }
+
+ return(&xran_upul_seq_id_num[cc_id][ant_id]);
+}
+static inline int8_t xran_check_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t seq_id)
+{
+ if(dir >= XRAN_DIR_MAX) {
+ print_err("Invalid direction - %d", dir);
+ return (-1);
+ }
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (-1);
+ }
+ if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (-1);
+ }
+
+ xran_cp_seq_id_num[cc_id][dir][ant_id]++;
+ if(xran_cp_seq_id_num[cc_id][dir][ant_id] == seq_id) { /* expected sequence */
+ return (0);
+ }
+ else {
+ xran_cp_seq_id_num[cc_id][dir][ant_id] = seq_id;
+ return (-1);
+ }
+}
+static inline int8_t xran_check_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id)
+{
+ if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
+ print_err("Invalid CC ID - %d", cc_id);
+ return (-1);
+ }
+
+ if(ant_id >= XRAN_MAX_ANTENNA_NR) {
+ print_err("Invalid antenna ID - %d", ant_id);
+ return (-1);
+ }
+
+ /* O-RU needs to check the sequence ID of U-Plane DL from O-DU */
+ xran_updl_seq_id_num[cc_id][ant_id]++;
+ if(xran_updl_seq_id_num[cc_id][ant_id] == seq_id) {
+ /* expected sequence */
+ return (0);
+ } else {
+ xran_updl_seq_id_num[cc_id][ant_id] = seq_id;
+ return (-1);
+ }
+}
+
+
+static struct xran_section_gen_info cpSections[XRAN_MAX_NUM_SECTIONS];
static struct xran_cp_gen_params cpInfo;
int process_cplane(struct rte_mbuf *pkt)
{
- int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result);
+ struct xran_recv_packet_info recv;
cpInfo.sections = cpSections;
- xran_parse_cp_pkt(pkt, &cpInfo);
+ xran_parse_cp_pkt(pkt, &cpInfo, &recv);
- return (0);
+ return (MBUF_FREE);
}
//////////////////////////////////////////
void sym_ota_cb(struct rte_timer *tim, void *arg)
{
- uint8_t offset = 0;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
long t1 = MLogTick();
+ static int32_t ctx = 0;
if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 0){
tti_ota_cb(NULL, arg);
}
- if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 1){
- if(p_xran_lib_ctx->phy_tti_cb_done == 0){
- uint64_t t3 = MLogTick();
+ if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 3){
+ if(p_xran_dev_ctx->phy_tti_cb_done == 0){
/* rearm timer to deliver TTI event to PHY */
- p_xran_lib_ctx->phy_tti_cb_done = 0;
- xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core);
- MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
+ p_xran_dev_ctx->phy_tti_cb_done = 0;
+ xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core);
}
}
xran_process_tx_sym(timer_ctx);
/* check if there is call back to do something else on this symbol */
- if(p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym])
- p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym](&tx_cp_dl_timer, p_xran_lib_ctx->pSymCallbackTag[0][xran_lib_ota_sym]);
+ if(p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym]){
+ p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym](&dpdk_timer[ctx], p_xran_dev_ctx->pSymCallbackTag[0][xran_lib_ota_sym]);
+ ctx = DpdkTiemerIncrementCtx(ctx);
+ }
xran_lib_ota_sym++;
if(xran_lib_ota_sym >= N_SYM_PER_SLOT){
xran_lib_ota_sym=0;
}
+
MLogTask(PID_SYM_OTA_CB, t1, MLogTick());
}
uint64_t t3 = 0;
uint32_t reg_tti = 0;
struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
MLogTask(PID_TTI_TIMER, t1, MLogTick());
/* To match TTbox */
if(xran_lib_ota_tti == 0)
- reg_tti = 8000-1;
+ reg_tti = xran_fs_get_max_slot() - 1;
else
reg_tti = xran_lib_ota_tti -1;
MLogIncrementCounter();
mlogVar[mlogVarCnt++] = 0;
MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
- if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU)
+ if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU)
next_tti = xran_lib_ota_tti + 1;
else
next_tti = xran_lib_ota_tti;
- if(next_tti>= SLOTNUM_PER_SUBFRAME*1000){
+ if(next_tti>= xran_fs_get_max_slot()){
print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
next_tti=0;
}
- /* [0 - 7] */
+
slot_id = XranGetSlotNum(next_tti, SLOTNUM_PER_SUBFRAME);
- /* sf [0 - 9] */
subframe_id = XranGetSubFrameNum(next_tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
- /* frame [0 - 99] for now */
frame_id = XranGetFrameNum(next_tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
- if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU){
+ if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU){
pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = next_tti;
} else {
pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = pTCtx[(xran_lib_ota_tti & 1)^1].tti_to_process;
}
- t3 = MLogTick();
- p_xran_lib_ctx->phy_tti_cb_done = 0;
- xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core);
- MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
+ p_xran_dev_ctx->phy_tti_cb_done = 0;
+ xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core);
xran_lib_ota_tti++;
- /* within 1 sec we have 8000 TTIs as 1000ms/0.125ms where TTI is 125us*/
- if(xran_lib_ota_tti >= SLOTNUM_PER_SUBFRAME*1000){
+ if(xran_lib_ota_tti >= xran_fs_get_max_slot()){
print_dbg("[%d]SFN %d sf %d slot %d\n",xran_lib_ota_tti, frame_id, subframe_id, slot_id);
xran_lib_ota_tti=0;
}
void xran_timer_arm(struct rte_timer *tim, void* arg)
{
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ uint64_t t3 = MLogTick();
+
if (xran_if_current_state == XRAN_RUNNING){
rte_timer_cb_t fct = (rte_timer_cb_t)arg;
- rte_timer_reset_sync(tim, 0, SINGLE, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core, fct, timer_ctx);
+ rte_timer_init(tim);
+ rte_timer_reset_sync(tim, 0, SINGLE, p_xran_dev_ctx->fh_init.io_cfg.timing_core, fct, &timer_ctx[0]);
}
+ MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
}
void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore)
{
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ uint64_t t3 = MLogTick();
+
if (xran_if_current_state == XRAN_RUNNING){
rte_timer_cb_t fct = (rte_timer_cb_t)CbFct;
rte_timer_init(tim);
rte_timer_reset_sync(tim, 0, SINGLE, tim_lcore, fct, CbArg);
}
+ MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
}
+int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id,
+ struct xran_prb_map *prbMapElem)
+{
+ struct xran_cp_gen_params params;
+ struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
+ struct rte_mbuf *mbuf;
+ int ret = 0;
+ uint32_t i;
+ uint32_t nsection = prbMapElem->nPrbElm;
+ struct xran_prb_elm *pPrbMapElem = &prbMapElem->prbMap[0];
+ struct xran_prb_elm *pPrbMapElemPrev;
+ uint32_t slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
+ uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
+ uint32_t frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+ uint8_t seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id);
+
+ params.dir = dir;
+ params.sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels
+ params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD;
+ params.hdr.frameId = frame_id;
+ params.hdr.subframeId = subframe_id;
+ params.hdr.slotId = slot_id;
+ params.hdr.startSymId = pPrbMapElem->nStartSymb;
+ params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
+ params.hdr.compMeth = pPrbMapElem->compMethod;
+
+ for (i=0; i<nsection; i++)
+ {
+ pPrbMapElem = &prbMapElem->prbMap[i];
+ sect_geninfo[i].info.type = params.sectionType; // for database
+ sect_geninfo[i].info.startSymId = params.hdr.startSymId; // for database
+ sect_geninfo[i].info.iqWidth = params.hdr.iqWidth; // for database
+ sect_geninfo[i].info.compMeth = params.hdr.compMeth; // for database
+ sect_geninfo[i].info.id = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
+ sect_geninfo[i].info.rb = XRAN_RBIND_EVERY;
+ sect_geninfo[i].info.startPrbc = pPrbMapElem->nRBStart;
+ sect_geninfo[i].info.numPrbc = pPrbMapElem->nRBSize;
+ sect_geninfo[i].info.numSymbol = pPrbMapElem->numSymb;
+ sect_geninfo[i].info.reMask = 0xfff;
+ sect_geninfo[i].info.beamId = pPrbMapElem->nBeamIndex;
+ if (i==0)
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
+ else
+ {
+ pPrbMapElemPrev = &prbMapElem->prbMap[i-1];
+ if (pPrbMapElemPrev->nStartSymb == pPrbMapElem->nStartSymb)
+ {
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
+ if (pPrbMapElemPrev->numSymb != pPrbMapElem->numSymb)
+ print_err("section info error: previous numSymb %d not equal to current numSymb %d\n", pPrbMapElemPrev->numSymb, pPrbMapElem->numSymb);
+ }
+ else
+ {
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_INC;
+ if (pPrbMapElem->nStartSymb != (pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb))
+ print_err("section info error: current startSym %d not equal to previous endSymb %d\n", pPrbMapElem->nStartSymb, pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb);
+ }
+ }
+
+ /* extension is not supported */
+ sect_geninfo[nsection].info.ef = 0;
+ sect_geninfo[nsection].exDataSize = 0;
+ //sect_geninfo[nsection].exData = NULL;
+ }
+ params.numSections = nsection;
+ params.sections = sect_geninfo;
+
+ mbuf = xran_ethdi_mbuf_alloc();
+ if(unlikely(mbuf == NULL)) {
+ print_err("Alloc fail!\n");
+ return (-1);
+ }
+
+ ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id);
+ if(ret < 0) {
+ print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
+ frame_id, subframe_id, slot_id, dir);
+ } else {
+ /* add in the ethernet header */
+ struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+ xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
+ tx_counter++;
+ for(i=0; i<nsection; i++)
+ xran_cp_add_section_info(pHandle,
+ dir, cc_id, ru_port_id,
+ (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
+ §_geninfo[i].info);
+ }
+
+ return ret;
+}
+#if 0
+int xran_cp_create_rbmap(int dir, int tti, int cc_id,
+ struct xran_flat_buffer *prbMapElem,
+ struct xran_cp_rbmap_list *rbMapList)
+{
+ struct xran_prb_map *prb_map;
+ int list_index = 0;
+ int sym_id;
+ int i, j;
+
+ prb_map = (struct xran_prb_map *)prbMapElm[0].pData;
+ cc_id = prb_map->cc_id;
+ tti = prb_map->tti_id;
+ dir = prb_map->dir;
+
+
+ list_index = -1;
+ for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) {
+ /* skip symbol, if not matched with given direction */
+ int type_sym = xran_fs_get_symbol_type(cc_id, tti, sym_id);
+ if(type_sym != XRAN_SYMBOL_TYPE_FDD && type_sym != dir)
+ continue;
+
+ /* retrieve the information of RB allocation */
+ prb_map = (struct xran_prb_map *)prbMapElem[sym_id].pData;
+ if(unlikely(prb_map == NULL)) {
+ print_err("RB allocation table is NULL! (tti:%d, cc:%d, sym_id:%d)", tti, cc_id, sym_id);
+ continue;
+ }
+
+ /* creating 2D mapping */
+ for(i=0; i < prb_map->nPrbElm; i++) {
+ if(list_index < 0) { /* create first entry */
+ list_index = 0;
+ rbMapList[list_index].grp_id = 0;
+ rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id
+ rbMapList[list_index].sym_num = 1;
+ rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart;
+ rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize;
+ rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex;
+ rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+ }
+ else {
+ /* find consecutive allocation from list */
+ for(j=0; j<list_index+1; j++) {
+ if(prb_map->prbMap[i].nRBStart != rbMapList[j].rb_start
+ || prb_map->prbMap[i].nRBSize != rbMapList[j].rb_num
+ || prb_map->prbMap[i].nBeamIndex != rbMapList[j].beam_id
+ || prb_map->prbMap[i].compMethod != rbMapList[j].comp_meth
+ || sym_id != (rbMapList[j].sym_start+rbMapList[j].sym_num)) {
+ /* move to next */
+ continue;
+ }
+ else {
+ /* consecutive allocation has been found */
+ rbMapList[j].sym_num++;
+ break;
+ }
+ }
+
+ if(j == list_index+1) { /* different allocation, create new entry */
+ list_index++;
+ rbMapList[list_index].grp_id = 0;
+ rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id
+ rbMapList[list_index].sym_num = 1;
+ rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart;
+ rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize;
+ rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex;
+ rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+ }
+ }
+ } /* for(i=0; i < prb_map->nPrbElm; i++) */
+ } /* for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) */
+
+ list_index++;
+
+#if 0
+ for(i=0; i<list_index; i++) {
+ printf("[%c:%d-%d] %d - symstart=%d, symnum=%d, rbstart=%d, rbnum=%d, beamid=%d, comp=%d\n",
+ dir?'U':'D', tti, cc_id, i,
+ rbMapList[i].sym_start, rbMapList[i].sym_num,
+ rbMapList[i].rb_start, rbMapList[i].rb_num,
+ rbMapList[i].beam_id, rbMapList[i].comp_meth);
+ }
+#endif
+ return (list_index);
+}
+#endif
+
void tx_cp_dl_cb(struct rte_timer *tim, void *arg)
{
long t1 = MLogTick();
- int tti, sym;
+ int tti, buf_id;
+ int i, ret;
uint32_t slot_id, subframe_id, frame_id;
- int ant_id;
- int32_t cc_id = 0;
- uint16_t beam_id;
- uint8_t num_eAxc, num_CCPorts;
+ int cc_id;
+ uint8_t ctx_id;
+ uint8_t ant_id, num_eAxc, num_CCPorts;
void *pHandle;
+ int num_list;
+ struct xran_cp_rbmap_list rb_map_list[XRAN_MAX_PRBS*N_SYM_PER_SLOT]; /* array size can be reduced */
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
-
pHandle = NULL; // TODO: temp implemantation
num_eAxc = xran_get_num_eAxc(pHandle);
num_CCPorts = xran_get_num_cc(pHandle);
- if(p_xran_lib_ctx->enableCP) {
+ if(p_xran_dev_ctx->enableCP) {
tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
+ buf_id = tti % XRAN_N_FE_BUF_LEN;
slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+ ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
- // start new section information list
- xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id);
- beam_id = xran_get_beamid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id);
+ /* start new section information list */
+ xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id, ctx_id);
+
+ if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) { // 1 when FDD, DL slot or DL symbol is present in SP slot
+ if (p_xran_dev_ctx->DynamicSectionEna){
+ num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_DL, tti, cc_id,
+ (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData);
+ }
+ else{
+ struct xran_cp_gen_params params;
+ struct xran_section_gen_info sect_geninfo[8];
+ struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
+
+ /* use symb 0 only with constant RBs for full slot */
+ struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData;
+ num_list = 1;
+ rb_map_list[0].sym_start = 0;
+ rb_map_list[0].sym_num = 14;
+ rb_map_list[0].rb_start = prb_map->prbMap[0].nRBStart;
+ rb_map_list[0].rb_num = prb_map->prbMap[0].nRBSize;
+ rb_map_list[0].beam_id = prb_map->prbMap[0].nBeamIndex;
+ rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod;
+
+ for(i=0; i<num_list; i++) {
+ ret = generate_cpmsg_dlul(pHandle, ¶ms, sect_geninfo, mbuf, XRAN_DIR_DL,
+ frame_id, subframe_id, slot_id,
+ rb_map_list[i].sym_start, rb_map_list[i].sym_num,
+ rb_map_list[i].rb_start, rb_map_list[i].rb_num,
+ rb_map_list[i].beam_id, cc_id, ant_id, rb_map_list[i].comp_meth,
+ xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id), XRAN_SYMBOLNUMBER_NOTINC);
+
+ if (ret == XRAN_STATUS_SUCCESS)
+ send_cpmsg(pHandle, mbuf, ¶ms, sect_geninfo,
+ cc_id, ant_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id));
+ }
+ }
+ } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) */
+ } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+ } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
+ } /* if(p_xran_dev_ctx->enableCP) */
- send_cpmsg_dlul(pHandle, XRAN_DIR_DL,
- frame_id, subframe_id, slot_id,
- 0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
- beam_id, cc_id, ant_id,
- xran_get_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id));
- }
- }
- }
MLogTask(PID_CP_DL_CB, t1, MLogTick());
}
void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
{
long t1 = MLogTick();
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
- XranStatusInt32 status;
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ xran_status_t status;
/* half of RX for current TTI as measured against current OTA time */
int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+ int32_t cc_id;
- if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+ if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
return;
- if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
- status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */
- if(p_xran_lib_ctx->pCallback[0])
- p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
- } else {
- p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
+ for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
+ if(p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] == 0){
+ status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */
+ if(p_xran_dev_ctx->pCallback[cc_id])
+ p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
+ } else {
+ p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] = 0;
+ }
}
MLogTask(PID_UP_UL_HALF_DEAD_LINE_CB, t1, MLogTick());
}
void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
{
long t1 = MLogTick();
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
- XranStatusInt32 status;
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ xran_status_t status = 0;
int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+ int32_t cc_id = 0;
- if(rx_tti >= 8000-1)
- rx_tti = 0;
+ if(rx_tti == 0)
+ rx_tti = (xran_fs_get_max_slot()-1);
else
rx_tti -= 1; /* end of RX for prev TTI as measured against current OTA time */
- if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+ if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
return;
- if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
+ /* U-Plane */
+ for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
status = (rx_tti << 16) | 7; /* last 7 sym means full slot of Symb */
- if(p_xran_lib_ctx->pCallback[0])
- p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
- } else {
- p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
+ if(p_xran_dev_ctx->pCallback[cc_id])
+ p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
+
+ if(p_xran_dev_ctx->pPrachCallback[cc_id])
+ p_xran_dev_ctx->pPrachCallback[cc_id](p_xran_dev_ctx->pPrachCallbackTag[cc_id], status);
+
}
MLogTask(PID_UP_UL_FULL_DEAD_LINE_CB, t1, MLogTick());
void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
{
long t1 = MLogTick();
- int sym, tti;
- uint32_t frame_id = 0;
- uint32_t subframe_id = 0;
- uint32_t slot_id = 0;
-
+ int tti, buf_id;
+ int i, ret;
+ uint32_t slot_id, subframe_id, frame_id;
int32_t cc_id;
int ant_id, prach_port_id;
uint16_t beam_id;
uint8_t num_eAxc, num_CCPorts;
+ uint8_t ctx_id;
void *pHandle;
+ int num_list;
+ struct xran_cp_rbmap_list rb_map_list[XRAN_MAX_PRBS*N_SYM_PER_SLOT]; /* array size can be reduced */
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
- xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_lib_ctx->PrachCPConfig);
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
pHandle = NULL; // TODO: temp implemantation
num_eAxc = xran_get_num_eAxc(pHandle);
num_CCPorts = xran_get_num_cc(pHandle);
+ tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
+ buf_id = tti % XRAN_N_FE_BUF_LEN;
+ slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
+ subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
+ frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+ ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
- if (p_xran_lib_ctx->enableCP){
- tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
- slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
- subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
- frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
- print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
+ if(p_xran_dev_ctx->enableCP) {
+ print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
- for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
- // start new section information list
- xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id);
+ for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
+ if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 ||
+ xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1 ){
+ /* start new section information list */
+ xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id, ctx_id);
+ if (p_xran_dev_ctx->DynamicSectionEna){
+ /* create a map of RB allocation to generate proper C-Plane */
+ num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_UL, tti, cc_id,
+ (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData);
+ }
+ else{
+ struct xran_cp_gen_params params;
+ struct xran_section_gen_info sect_geninfo[8];
+ struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
+ /* use symb 0 only with constant RBs for full slot */
+ struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData;
+ num_list = 1;
+ rb_map_list[0].sym_start = 0;
+ rb_map_list[0].sym_num = 14;
+ rb_map_list[0].rb_start = prb_map->prbMap[0].nRBStart;
+ rb_map_list[0].rb_num = prb_map->prbMap[0].nRBSize;
+ rb_map_list[0].beam_id = prb_map->prbMap[0].nBeamIndex;
+ rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod;
+
+ for(i=0; i<num_list; i++) {
+ ret = generate_cpmsg_dlul(pHandle, ¶ms, sect_geninfo, mbuf, XRAN_DIR_UL,
+ frame_id, subframe_id, slot_id,
+ rb_map_list[i].sym_start, rb_map_list[i].sym_num,
+ rb_map_list[i].rb_start, rb_map_list[i].rb_num,
+ rb_map_list[i].beam_id, cc_id, ant_id, rb_map_list[i].comp_meth,
+ xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id), XRAN_SYMBOLNUMBER_NOTINC);
+ if (ret == XRAN_STATUS_SUCCESS)
+ send_cpmsg(pHandle, mbuf, ¶ms, sect_geninfo,
+ cc_id, ant_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id));
+ }
+ }
+ } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 || */
- beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id);
- send_cpmsg_dlul(pHandle, XRAN_DIR_UL,
- frame_id, subframe_id, slot_id,
- 0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
- beam_id, cc_id, ant_id,
- xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id));
- }
- }
+ } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+ } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
+ } /* if(p_xran_dev_ctx->enableCP) */
- if ((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (pPrachCPConfig->isPRACHslot[slot_id]==1)) //is prach slot
- {
- for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
+ if(p_xran_dev_ctx->enablePrach) {
+ uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id);
+ if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (isPRACHslot==1)) { //is prach slot
+ for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
-#if !defined(PRACH_USES_SHARED_PORT)
+ struct xran_cp_gen_params params;
+ struct xran_section_gen_info sect_geninfo[8];
+ struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
prach_port_id = ant_id + num_eAxc;
- // start new section information list
- xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id);
-#else
- prach_port_id = ant_id;
-#endif
- beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
- send_cpmsg_prach(pHandle,
- frame_id, subframe_id, slot_id,
- beam_id, cc_id, prach_port_id,
- xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id));
+ /* start new section information list */
+ xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, ctx_id);
+
+ beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id); /* TODO: */
+ ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx,
+ frame_id, subframe_id, slot_id,
+ beam_id, cc_id, prach_port_id,
+ xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
+ if (ret == XRAN_STATUS_SUCCESS)
+ send_cpmsg(pHandle, mbuf, ¶ms, sect_geninfo,
+ cc_id, prach_port_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
}
}
}
-
}
+
MLogTask(PID_CP_UL_CB, t1, MLogTick());
}
void tti_to_phy_cb(struct rte_timer *tim, void *arg)
{
long t1 = MLogTick();
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
static int first_call = 0;
- p_xran_lib_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
+ p_xran_dev_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
if (first_call){
- if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
- if(p_xran_lib_ctx->SkipTti[XRAN_CB_TTI] <= 0){
- p_xran_lib_ctx->ttiCb[XRAN_CB_TTI](p_xran_lib_ctx->TtiCbParam[XRAN_CB_TTI]);
+ if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
+ if(p_xran_dev_ctx->SkipTti[XRAN_CB_TTI] <= 0){
+ p_xran_dev_ctx->ttiCb[XRAN_CB_TTI](p_xran_dev_ctx->TtiCbParam[XRAN_CB_TTI]);
}else{
- p_xran_lib_ctx->SkipTti[XRAN_CB_TTI]--;
+ p_xran_dev_ctx->SkipTti[XRAN_CB_TTI]--;
}
}
} else {
- if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
+ if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
int32_t tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
- if(tti == 8000-1)
+ if(tti == xran_fs_get_max_slot()-1)
first_call = 1;
}
}
uint32_t sym_up_ul;
int32_t sym_up;
struct sched_param sched_param;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
/* ToS = Top of Second start +- 1.5us */
struct timespec ts;
sched_param.sched_priority = 98;
CPU_ZERO(&cpuset);
- CPU_SET(p_xran_lib_ctx->xran_init_cfg.io_cfg.timing_core, &cpuset);
+ CPU_SET(p_xran_dev_ctx->fh_init.io_cfg.timing_core, &cpuset);
if (result1 = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset))
{
printf("pthread_setaffinity_np failed: coreId = 2, result1 = %d\n",result1);
printf("priority is not changed: coreId = 2, result1 = %d\n",result1);
}
- if (p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
+ if (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
do {
timespec_get(&ts, TIME_UTC);
}while (ts.tv_nsec >1500);
printf("lls-CU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
}
- delay_cp_dl = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_dl;
- delay_cp_ul = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_ul;
- delay_up = p_xran_lib_ctx->xran_init_cfg.T1a_max_up;
- delay_up_ul = p_xran_lib_ctx->xran_init_cfg.Ta4_max;
+ delay_cp_dl = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_dl;
+ delay_cp_ul = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_ul;
+ delay_up = p_xran_dev_ctx->fh_init.T1a_max_up;
+ delay_up_ul = p_xran_dev_ctx->fh_init.Ta4_max;
delay_cp2up = delay_up-delay_cp_dl;
sym_cp_dl = delay_cp_dl*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
sym_cp_ul = delay_cp_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
sym_up_ul = delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT);
- p_xran_lib_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
- p_xran_lib_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
+ p_xran_dev_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
+ p_xran_dev_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
printf("Start C-plane DL %d us after TTI [trigger on sym %d]\n", delay_cp_dl, sym_cp_dl);
printf("Start C-plane UL %d us after TTI [trigger on sym %d]\n", delay_cp_ul, sym_cp_ul);
printf("C-plane to U-plane delay %d us after TTI\n", delay_cp2up);
printf("Start Sym timer %ld ns\n", TX_TIMER_INTERVAL/N_SYM_PER_SLOT);
- p_xran_lib_ctx->pSymCallback[0][sym_cp_dl] = xran_timer_arm;
- p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb;
+ p_xran_dev_ctx->pSymCallback[0][sym_cp_dl] = xran_timer_arm;
+ p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb;
- p_xran_lib_ctx->pSymCallback[0][sym_cp_ul] = xran_timer_arm;
- p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb;
+ p_xran_dev_ctx->pSymCallback[0][sym_cp_ul] = xran_timer_arm;
+ p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb;
/* Full slot UL OTA + delay_up_ul */
- p_xran_lib_ctx->pSymCallback[0][sym_up_ul] = xran_timer_arm;
- p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb;
+ p_xran_dev_ctx->pSymCallback[0][sym_up_ul] = xran_timer_arm;
+ p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb;
/* Half slot UL OTA + delay_up_ul*/
- p_xran_lib_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2] = xran_timer_arm;
- p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb;
+ p_xran_dev_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2] = xran_timer_arm;
+ p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb;
- } else { // APP_RU
+ } else { // APP_O_RU
/* calcualte when to send UL U-plane */
- delay_up = p_xran_lib_ctx->xran_init_cfg.Ta3_min;
- p_xran_lib_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
+ delay_up = p_xran_dev_ctx->fh_init.Ta3_min;
+ p_xran_dev_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
printf("Start UL U-plane %d us after OTA [offset in sym %d]\n", delay_up, sym_up);
do {
timespec_get(&ts, TIME_UTC);
}
}
+ printf("interval_us %ld\n", interval_us);
do {
timespec_get(&ts, TIME_UTC);
}while (ts.tv_nsec == 0);
delta = poll_next_tick(interval_us*1000L/N_SYM_PER_SLOT);
if (XRAN_STOPPED == xran_if_current_state)
break;
- sym_ota_cb(&sym_timer, timer_ctx);
+
+ if (likely(XRAN_RUNNING == xran_if_current_state))
+ sym_ota_cb(&sym_timer, timer_ctx);
}
- printf("Closing timing source thread...\n");
+ printf("Closing timing source thread...tx counter %lu, rx counter %lu\n", tx_counter, rx_counter);
return 0;
}
{
const struct xran_ecpri_hdr *ecpri_hdr;
unsigned long t1;
+ int32_t ret = MBUF_FREE;
if (rte_pktmbuf_data_len(pkt) < sizeof(struct xran_ecpri_hdr)) {
- wlog("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
+ print_err("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
return 0;
}
/* check eCPRI header. */
ecpri_hdr = rte_pktmbuf_mtod(pkt, struct xran_ecpri_hdr *);
- if(ecpri_hdr == NULL)
+ if(ecpri_hdr == NULL){
+ print_err("ecpri_hdr error\n");
return MBUF_FREE;
+ }
- switch(ecpri_hdr->ecpri_mesg_type) {
+ switch(ecpri_hdr->cmnhdr.ecpri_mesg_type) {
case ECPRI_IQ_DATA:
- t1 = MLogTick();
- process_mbuf(pkt);
- MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
+ // t1 = MLogTick();
+ ret = process_mbuf(pkt);
+ // MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
break;
// For RU emulation
case ECPRI_RT_CONTROL_DATA:
t1 = MLogTick();
- if(xran_lib_get_ctx()->xran_init_cfg.io_cfg.id == APP_RU) {
- process_cplane(pkt);
+ if(xran_dev_get_ctx()->fh_init.io_cfg.id == O_RU) {
+ ret = process_cplane(pkt);
} else {
- print_err("LLS-CU recevied CP message!");
+ print_err("O-DU recevied C-Plane message!");
}
MLogTask(PID_PROCESS_CP_PKT, t1, MLogTick());
break;
default:
- wlog("Invalid eCPRI message type - %d", ecpri_hdr->ecpri_mesg_type);
+ print_err("Invalid eCPRI message type - %d", ecpri_hdr->cmnhdr.ecpri_mesg_type);
}
-#if 0
-//def DEBUG
- return MBUF_KEEP;
-#else
- return MBUF_FREE;
-#endif
+
+ return ret;
}
-int xran_process_rx_sym(void *arg,
+int xran_process_prach_sym(void *arg,
+ struct rte_mbuf *mbuf,
void *iq_data_start,
uint16_t size,
uint8_t CC_ID,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
- uint8_t symb_id)
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id)
{
char *pos = NULL;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
- uint32_t tti=0;
- XranStatusInt32 status;
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ uint8_t symb_id_offset;
+ uint32_t tti = 0;
+ xran_status_t status;
void *pHandle = NULL;
+ struct rte_mbuf *mb;
- if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+ uint16_t iq_sample_size_bits = 16;
+
+ if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
return 0;
tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
status = tti << 16 | symb_id;
- if(tti < 8000 && CC_ID < XRAN_MAX_SECTOR_NR && CC_ID == 0 && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
- pos = (char*) p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
+ if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
+ symb_id_offset = symb_id - p_xran_dev_ctx->prach_start_symbol[CC_ID]; //make the storing of prach packets to start from 0 for easy of processing within PHY
+ pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData;
if(pos && iq_data_start && size){
-#ifdef XRAN_BYTE_ORDER_SWAP
- int idx = 0;
- uint16_t *restrict psrc = (uint16_t *)iq_data_start;
- uint16_t *restrict pdst = (uint16_t *)pos;
- /* network byte (be) order of IQ to CPU byte order (le) */
- for (idx = 0; idx < size/sizeof(int16_t); idx++){
- pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+ if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
+ int idx = 0;
+ uint16_t *psrc = (uint16_t *)iq_data_start;
+ uint16_t *pdst = (uint16_t *)pos;
+ /* network byte (be) order of IQ to CPU byte order (le) */
+ for (idx = 0; idx < size/sizeof(int16_t); idx++){
+ pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+ }
+ }else {
+ mb = p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl;
+ rte_pktmbuf_free(mb);
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData = iq_data_start;
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl = mbuf;
}
-#else
-#error xran spec is network byte order
- /* for debug */
- rte_memcpy(pdst, psrc, size);
-#endif
#ifdef DEBUG_XRAN_BUFFERS
if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
pos[1] != CC_ID ||
} else {
print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id);
}
- if (symb_id == 7 || symb_id == 13){
- p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
- if(p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
- if(p_xran_lib_ctx->pCallback[0])
- p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
- p_xran_lib_ctx->rx_packet_callback_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID] = 1;
- p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
+/* if (symb_id == p_xran_dev_ctx->prach_last_symbol[CC_ID] ){
+ p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
+ if(p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
+ if(p_xran_dev_ctx->pPrachCallback[0])
+ p_xran_dev_ctx->pPrachCallback[0](p_xran_dev_ctx->pPrachCallbackTag[0], status);
+ p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
}
}
+*/
return size;
}
+int32_t xran_pkt_validate(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ struct ecpri_seq_id *seq_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id)
+{
+ struct xran_device_ctx * pctx = xran_dev_get_ctx();
+ struct xran_common_counters *pCnt = &pctx->fh_counters;
+
+ if(pctx->fh_init.io_cfg.id == O_DU) {
+ if(xran_check_upul_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
+ pCnt->Rx_pkt_dupl++;
+ return (XRAN_STATUS_FAIL);
+ }
+ }else if(pctx->fh_init.io_cfg.id == O_RU) {
+ if(xran_check_updl_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
+ pCnt->Rx_pkt_dupl++;
+ return (XRAN_STATUS_FAIL);
+ }
+ }else {
+ print_err("incorrect dev type %d\n", pctx->fh_init.io_cfg.id);
+ }
+
+ rx_counter++;
+
+ pCnt->Rx_on_time++;
+ pCnt->Total_msgs_rcvd++;
+
+ return XRAN_STATUS_SUCCESS;
+}
+
+int xran_process_rx_sym(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id,
+ uint32_t *mb_free)
+{
+ char *pos = NULL;
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ uint32_t tti = 0;
+ xran_status_t status;
+ void *pHandle = NULL;
+ struct rte_mbuf *mb = NULL;
+
+ uint16_t iq_sample_size_bits = 16;
+
+ tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
+
+ status = tti << 16 | symb_id;
+
+ if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
+ pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
+ pos += start_prbu * N_SC_PER_PRB*(iq_sample_size_bits/8)*2;
+ if(pos && iq_data_start && size){
+ if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
+ int idx = 0;
+ uint16_t *psrc = (uint16_t *)iq_data_start;
+ uint16_t *pdst = (uint16_t *)pos;
+ rte_panic("XRAN_CPU_LE_BYTE_ORDER is not supported 0x16%lx\n", (long)mb);
+ /* network byte (be) order of IQ to CPU byte order (le) */
+ for (idx = 0; idx < size/sizeof(int16_t); idx++){
+ pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
+ }
+ } else if (likely(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_NE_BE_BYTE_ORDER)){
+ if (likely (p_xran_dev_ctx->fh_init.mtu >=
+ p_xran_dev_ctx->fh_cfg.nULRBs * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) {
+ /* no fragmentation */
+ mb = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl;
+ if(mb){
+ rte_pktmbuf_free(mb);
+ }else{
+ print_err("mb==NULL\n");
+ }
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData = iq_data_start;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl = mbuf;
+ *mb_free = MBUF_KEEP;
+ } else {
+ /* packet can be fragmented copy RBs */
+ rte_memcpy(pos, iq_data_start, size);
+ *mb_free = MBUF_FREE;
+ }
+ }
+#ifdef DEBUG_XRAN_BUFFERS
+ if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
+ pos[1] != CC_ID ||
+ pos[2] != Ant_ID ||
+ pos[3] != symb_id){
+ printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
+ }
+#endif
+ } else {
+ print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
+ }
+ } else {
+ print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id);
+ }
+
+ return size;
+}
+
+/* Send burst of packets on an output interface */
+static inline int
+xran_send_burst(struct xran_device_ctx *dev, uint16_t n, uint16_t port)
+{
+ struct rte_mbuf **m_table;
+ struct rte_mbuf *m;
+ int32_t i = 0;
+ int j;
+ int32_t ret = 0;
+
+ m_table = (struct rte_mbuf **)dev->tx_mbufs[port].m_table;
+
+ for(i = 0; i < n; i++){
+ rte_mbuf_sanity_check(m_table[i], 0);
+ /*rte_pktmbuf_dump(stdout, m_table[i], 256);*/
+ tx_counter++;
+ ret += xran_ethdi_mbuf_send(m_table[i], ETHER_TYPE_ECPRI);
+ }
+
+
+ if (unlikely(ret < n)) {
+ print_err("ret < n\n");
+ }
+
+ return 0;
+}
+
int xran_process_tx_sym(void *arg)
{
uint32_t tti=0;
+#if XRAN_MLOG_VAR
uint32_t mlogVar[10];
uint32_t mlogVarCnt = 0;
+#endif
unsigned long t1 = MLogTick();
void *pHandle = NULL;
uint32_t sym_idx = 0;
char *pos = NULL;
+ void *mb = NULL;
int prb_num = 0;
+ uint16_t iq_sample_size_bits = 16; // TODO: make dynamic per
struct xran_section_info *sectinfo;
uint32_t next;
+ uint32_t num_sections;
+ uint8_t ctx_id;
enum xran_pkt_dir direction;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
-
- if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
+ if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
return 0;
- if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
+ if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
direction = XRAN_DIR_DL; /* lls-CU */
- prb_num = NUM_OF_PRB_IN_FULL_BAND;
- }
- else {
+ prb_num = p_xran_dev_ctx->fh_cfg.nDLRBs;
+ } else {
direction = XRAN_DIR_UL; /* RU */
- prb_num = NUM_OF_PRB_IN_FULL_BAND; /*TODO: simulation on D-1541 @ 2.10GHz has issue with performace. reduce copy size */
- }
+ prb_num = p_xran_dev_ctx->fh_cfg.nULRBs;
+ }
/* RU: send symb after OTA time with delay (UL) */
/* lls-CU:send symb in advance of OTA time (DL) */
- sym_idx = XranOffsetSym(p_xran_lib_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
+ sym_idx = XranOffsetSym(p_xran_dev_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
tti = XranGetTtiNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
sym_id = XranGetSymNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
+ ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
+#if XRAN_MLOG_VAR
mlogVar[mlogVarCnt++] = 0xAAAAAAAA;
mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
mlogVar[mlogVarCnt++] = sym_idx;
- mlogVar[mlogVarCnt++] = abs(p_xran_lib_ctx->sym_up);
+ mlogVar[mlogVarCnt++] = abs(p_xran_dev_ctx->sym_up);
mlogVar[mlogVarCnt++] = tti;
mlogVar[mlogVarCnt++] = frame_id;
mlogVar[mlogVarCnt++] = subframe_id;
mlogVar[mlogVarCnt++] = slot_id;
mlogVar[mlogVarCnt++] = sym_id;
MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
+#endif
if(frame_id > 99) {
print_err("OTA %d: TX:[sym_idx %d: TTI %d] fr %d sf %d slot %d sym %d\n",xran_lib_ota_sym_idx, sym_idx, tti, frame_id, subframe_id, slot_id, sym_id);
- xran_if_current_state =XRAN_STOPPED;
- }
+ xran_if_current_state = XRAN_STOPPED;
+ }
num_eAxc = xran_get_num_eAxc(pHandle);
num_CCPorts = xran_get_num_cc(pHandle);
/* U-Plane */
for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
- if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) {
+ if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU
+ && p_xran_dev_ctx->enableCP) {
+ /*==== lls-CU and C-Plane has been enabled ===*/
next = 0;
- while(next < xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id)) {
- sectinfo = xran_cp_iterate_section_info(pHandle, direction,
- cc_id, ant_id, subframe_id, slot_id, &next);
+ num_sections = xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id, ctx_id);
+ /* iterate C-Plane configuration to generate corresponding U-Plane */
+ while(next < num_sections) {
+ sectinfo = xran_cp_iterate_section_info(pHandle, direction, cc_id, ant_id, ctx_id, &next);
+
if(sectinfo == NULL)
break;
- /* pointer to IQs input */
- /* TODO: need to implement the case of partial RB assignment */
- pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
- print_dbg(">>> [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", next,
- sectinfo->type, sectinfo->id, sectinfo->startPrbc,
- sectinfo->numPrbc, sectinfo->numSymbol);
-
- if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) {
+ if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) { /* only supports type 1 */
print_err("Invalid section type in section DB - %d", sectinfo->type);
continue;
+ }
+
+ /* skip, if not scheduled */
+ if(sym_id < sectinfo->startSymId || sym_id >= sectinfo->startSymId + sectinfo->numSymbol)
+ continue;
+
+ /* if(sectinfo->compMeth)
+ iq_sample_size_bits = sectinfo->iqWidth;*/
+
+ if(iq_sample_size_bits != 16) {/* TODO: support for compression */
+ print_err("Incorrect iqWidth %d", iq_sample_size_bits);
+ iq_sample_size_bits = 16;
+ }
+
+ print_dbg(">>> sym %2d [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", sym_id, next,
+ sectinfo->type, sectinfo->id, sectinfo->startPrbc,
+ sectinfo->numPrbc, sectinfo->numSymbol);
+
+ p_xran_dev_ctx->tx_mbufs[0].len = 0;
+ uint16_t len = p_xran_dev_ctx->tx_mbufs[0].len;
+ int16_t len2 = 0;
+ uint16_t i = 0;
+
+ //Added for Klocworks
+ if (len >= MBUF_TABLE_SIZE)
+ len = MBUF_TABLE_SIZE - 1;
+
+ pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+ mb = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
+
+ /* first all PRBs */
+ prepare_symbol_ex(direction, sectinfo->id,
+ mb,
+ (struct rb_map *)pos,
+ p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+ frame_id, subframe_id, slot_id, sym_id,
+ sectinfo->startPrbc, sectinfo->numPrbc,
+ cc_id, ant_id,
+ xran_get_updl_seqid(pHandle, cc_id, ant_id),
+ 0);
+
+ /* if we don't need to do any fragmentation */
+ if (likely (p_xran_dev_ctx->fh_init.mtu >=
+ sectinfo->numPrbc * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) {
+ /* no fragmentation */
+ p_xran_dev_ctx->tx_mbufs[0].m_table[len] = mb;
+ len2 = 1;
+ } else {
+ /* fragmentation */
+ len2 = xran_app_fragment_packet(mb,
+ &p_xran_dev_ctx->tx_mbufs[0].m_table[len],
+ (uint16_t)(MBUF_TABLE_SIZE - len),
+ p_xran_dev_ctx->fh_init.mtu,
+ p_xran_dev_ctx->direct_pool,
+ p_xran_dev_ctx->indirect_pool,
+ sectinfo,
+ xran_get_updl_seqid_addr(pHandle, cc_id, ant_id));
+
+ /* Free input packet */
+ rte_pktmbuf_free(mb);
+
+ /* If we fail to fragment the packet */
+ if (unlikely (len2 < 0)){
+ print_err("len2= %d\n", len2);
+ return 0;
}
+ }
- send_symbol_ex(direction, sectinfo->id,
- (struct rb_map *)pos,
- frame_id, subframe_id, slot_id, sym_id,
- sectinfo->startPrbc, sectinfo->numPrbc,
- cc_id, ant_id,
- xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
+ if(len2 > 1){
+ for (i = len; i < len + len2; i ++) {
+ struct rte_mbuf *m;
+ m = p_xran_dev_ctx->tx_mbufs[0].m_table[i];
+ struct ether_hdr *eth_hdr = (struct ether_hdr *)
+ rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct ether_hdr));
+ if (eth_hdr == NULL) {
+ rte_panic("No headroom in mbuf.\n");
+ }
+ }
}
- }
- else { /* if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) */
- /* pointer to IQs input */
- pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+ len += len2;
+
+ if (unlikely(len > XRAN_MAX_PKT_BURST_PER_SYM)) {
+ rte_panic("XRAN_MAX_PKT_BURST_PER_SYM\n");
+ }
+
+ /* Transmit packets */
+ xran_send_burst(p_xran_dev_ctx, (uint16_t)len, 0);
+ p_xran_dev_ctx->tx_mbufs[0].len = 0;
+ } /* while(section) */
+
+ }
+ else {
+ /*==== RU or C-Plane is disabled ===*/
+ xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
+
+ if(xran_fs_get_slot_type(cc_id, tti, ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SLOT_TYPE_DL : XRAN_SLOT_TYPE_UL)) == 1
+ || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1
+ || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_FDD) == 1){
+
+ if(xran_fs_get_symbol_type(cc_id, tti, sym_id) == ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SYMBOL_TYPE_DL : XRAN_SYMBOL_TYPE_UL)
+ || xran_fs_get_symbol_type(cc_id, tti, sym_id) == XRAN_SYMBOL_TYPE_FDD){
+
+ if(iq_sample_size_bits != 16)
+ print_err("Incorrect iqWidth %d\n", iq_sample_size_bits );
+
+ pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
+ mb = (void*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
+
+ if( prb_num > 136 || prb_num == 0) {
+ uint16_t sec_id = xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id);
+ /* first 136 PRBs */
+ send_symbol_ex(direction,
+ sec_id,
+ NULL,
+ (struct rb_map *)pos,
+ p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+ frame_id, subframe_id, slot_id, sym_id,
+ 0, 136,
+ cc_id, ant_id,
+ (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+ xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+ xran_get_upul_seqid(pHandle, cc_id, ant_id));
+
+ pos += 136 * N_SC_PER_PRB * (iq_sample_size_bits/8)*2;
+ /* last 137 PRBs */
+ send_symbol_ex(direction, sec_id,
+ NULL,
+ (struct rb_map *)pos,
+ p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+ frame_id, subframe_id, slot_id, sym_id,
+ 136, 137,
+ cc_id, ant_id,
+ (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+ xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+ xran_get_upul_seqid(pHandle, cc_id, ant_id));
+ } else {
#ifdef DEBUG_XRAN_BUFFERS
- if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
- pos[1] != cc_id ||
- pos[2] != ant_id ||
- pos[3] != sym_id)
- printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
+ if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
+ pos[1] != cc_id ||
+ pos[2] != ant_id ||
+ pos[3] != sym_id)
+ printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
#endif
- send_symbol_ex(direction,
- xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id),
- (struct rb_map *)pos,
- frame_id, subframe_id, slot_id, sym_id,
- 0, prb_num,
- cc_id, ant_id,
- xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
+ send_symbol_ex(direction,
+ xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id),
+ (struct rte_mbuf *)mb,
+ (struct rb_map *)pos,
+ p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+ frame_id, subframe_id, slot_id, sym_id,
+ 0, prb_num,
+ cc_id, ant_id,
+ (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
+ xran_get_updl_seqid(pHandle, cc_id, ant_id) :
+ xran_get_upul_seqid(pHandle, cc_id, ant_id));
+ }
+
+ if(p_xran_dev_ctx->enablePrach
+ && (p_xran_dev_ctx->fh_init.io_cfg.id == O_RU)) { /* Only RU needs to send PRACH I/Q */
+ uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id);
+ if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0])
+ && (isPRACHslot == 1)
+ && (sym_id >= p_xran_dev_ctx->prach_start_symbol[cc_id])
+ && (sym_id <= p_xran_dev_ctx->prach_last_symbol[cc_id])) { //is prach slot
+ for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
+ int prach_port_id = ant_id + num_eAxc;
+ pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pData;
+ pos += (sym_id - p_xran_dev_ctx->prach_start_symbol[cc_id]) * pPrachCPConfig->numPrbc * N_SC_PER_PRB * 4;
+ mb = NULL;//(void*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pCtrl;
+ send_symbol_ex(direction,
+ xran_alloc_sectionid(pHandle, direction, cc_id, prach_port_id, slot_id),
+ (struct rte_mbuf *)mb,
+ (struct rb_map *)pos,
+ p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
+ frame_id, subframe_id, slot_id, sym_id,
+ pPrachCPConfig->startPrbc, pPrachCPConfig->numPrbc,
+ cc_id, prach_port_id,
+ xran_get_upul_seqid(pHandle, cc_id, prach_port_id));
+ }
+ } /* if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) .... */
+ } /* if(p_xran_dev_ctx->enablePrach ..... */
+
+ } /* RU mode or C-Plane is not used */
}
}
- }
+ } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
+ } /* for(ant_id = 0; ant_id < num_eAxc; ant_id++) */
MLogTask(PID_PROCESS_TX_SYM, t1, MLogTick());
return 0;
}
-int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle)
+int32_t
+xran_init(int argc, char *argv[],
+ struct xran_fh_init *p_xran_fh_init, char *appName, void ** pXranLayerHandle)
{
- int i;
- int j;
+ int32_t i;
+ int32_t j;
struct xran_io_loop_cfg *p_io_cfg = (struct xran_io_loop_cfg *)&p_xran_fh_init->io_cfg;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
- int lcore_id = 0;
+ int32_t lcore_id = 0;
char filename[64];
- memset(p_xran_lib_ctx, 0, sizeof(struct xran_lib_ctx));
+ memset(p_xran_dev_ctx, 0, sizeof(struct xran_device_ctx));
+
/* copy init */
- p_xran_lib_ctx->xran_init_cfg = *p_xran_fh_init;
+ p_xran_dev_ctx->fh_init = *p_xran_fh_init;
- xran_if_current_state = XRAN_RUNNING;
- interval_us = p_xran_fh_init->ttiPeriod;
+ printf(" %s: MTU %d\n", __FUNCTION__, p_xran_dev_ctx->fh_init.mtu);
- p_xran_lib_ctx->llscu_id = p_xran_fh_init->llscuId;
- memcpy(&(p_xran_lib_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(XRANEAXCIDCONFIG));
+ xran_if_current_state = XRAN_INIT;
- p_xran_lib_ctx->enableCP = p_xran_fh_init->enableCP;
+ memcpy(&(p_xran_dev_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(struct xran_eaxcid_config));
+
+ p_xran_dev_ctx->enableCP = p_xran_fh_init->enableCP;
+ p_xran_dev_ctx->enablePrach = p_xran_fh_init->prachEnable;
+ p_xran_dev_ctx->DynamicSectionEna = p_xran_fh_init->DynamicSectionEna;
xran_register_ethertype_handler(ETHER_TYPE_ECPRI, handle_ecpri_ethertype);
if (p_io_cfg->id == 0)
- xran_ethdi_init_dpdk_io(basename(appName),
+ xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
p_io_cfg,
&lcore_id,
- (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
- (struct ether_addr *)p_xran_fh_init->p_ru_addr,
+ (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
+ (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
p_xran_fh_init->cp_vlan_tag,
p_xran_fh_init->up_vlan_tag);
else
- xran_ethdi_init_dpdk_io(basename(appName),
+ xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
p_io_cfg,
&lcore_id,
- (struct ether_addr *)p_xran_fh_init->p_ru_addr,
- (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
+ (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
+ (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
p_xran_fh_init->cp_vlan_tag,
p_xran_fh_init->up_vlan_tag);
for(i = 0; i < 10; i++ )
rte_timer_init(&tti_to_phy_timer[i]);
- rte_timer_init(&tti_timer);
rte_timer_init(&sym_timer);
- rte_timer_init(&tx_cp_dl_timer);
- rte_timer_init(&tx_cp_ul_timer);
- rte_timer_init(&tx_up_timer);
+ for (i = 0; i< MAX_NUM_OF_DPDK_TIMERS; i++)
+ rte_timer_init(&dpdk_timer[i]);
+
+ p_xran_dev_ctx->direct_pool = socket_direct_pool;
+ p_xran_dev_ctx->indirect_pool = socket_indirect_pool;
- for(i = 0; i < XRAN_MAX_SECTOR_NR; i++ ){
- unsigned n = snprintf(&p_xran_lib_ctx->ring_name[0][i][0], RTE_RING_NAMESIZE, "dl_sym_ring_%u", i);
- p_xran_lib_ctx->dl_sym_idx_ring[i] = rte_ring_create(&p_xran_lib_ctx->ring_name[0][i][0], XRAN_RING_SIZE,
- rte_lcore_to_socket_id(lcore_id), RING_F_SP_ENQ | RING_F_SC_DEQ);
+ printf("Set debug stop %d, debug stop count %d\n", p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
+ timing_set_debug_stop(p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
+
+ for (uint32_t nCellIdx = 0; nCellIdx < XRAN_MAX_SECTOR_NR; nCellIdx++){
+ xran_fs_clear_slot_type(nCellIdx);
}
+ *pXranLayerHandle = p_xran_dev_ctx;
- lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
- PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
+ return 0;
+}
- /* Start packet processing thread */
- if (rte_eal_remote_launch(ring_processing_thread, NULL, lcore_id))
- rte_panic("ring_processing_thread() failed to start\n");
+int32_t xran_sector_get_instances (void * pDevHandle, uint16_t nNumInstances,
+ xran_cc_handle_t * pSectorInstanceHandles)
+{
+ xran_status_t nStatus = XRAN_STATUS_FAIL;
+ struct xran_device_ctx *pDev = (struct xran_device_ctx *)pDevHandle;
+ XranSectorHandleInfo *pCcHandle = NULL;
+ int32_t i = 0;
- if(p_io_cfg->pkt_aux_core > 0){
- lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
- PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
+ /* Check for the Valid Parameters */
+ CHECK_NOT_NULL (pSectorInstanceHandles, XRAN_STATUS_INVALID_PARAM);
- /* Start packet processing thread */
- if (rte_eal_remote_launch(xran_packet_and_dpdk_timer_thread, NULL, lcore_id))
- rte_panic("ring_processing_thread() failed to start\n");
+ if (!nNumInstances) {
+ print_dbg("Instance is not assigned for this function !!! \n");
+ return XRAN_STATUS_INVALID_PARAM;
}
- lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
- PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
-
- /* Start packet processing thread */
- if (rte_eal_remote_launch(xran_timing_source_thread, xran_lib_get_ctx(), lcore_id))
- rte_panic("thread_run() failed to start\n");
+ for (i = 0; i < nNumInstances; i++) {
- printf("Set debug stop %d\n", p_xran_fh_init->debugStop);
- timing_set_debug_stop(p_xran_fh_init->debugStop);
+ /* Allocate Memory for CC handles */
+ pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64);
- memset(&DevHandle, 0, sizeof(XranLibHandleInfoStruct));
+ if(pCcHandle == NULL)
+ return XRAN_STATUS_RESOURCE;
- *pHandle = &DevHandle;
+ memset (pCcHandle, 0, (sizeof (XranSectorHandleInfo)));
- return 0;
-}
+ pCcHandle->nIndex = i;
+ pCcHandle->nXranPort = pDev->xran_port_id;
-int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
- XranCcInstanceHandleVoidP * pSectorInstanceHandles)
-{
- int i;
+ printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, pDev->xran_port_id, i, pCcHandle);
+ pLibInstanceHandles[pDev->xran_port_id][i] = pSectorInstanceHandles[i] = pCcHandle;
- /* only one handle as only one CC is currently supported */
- for(i = 0; i < nNumInstances; i++ )
- pSectorInstanceHandles[i] = pHandle;
+ printf("Handle: %p Instance: %p\n",
+ &pSectorInstanceHandles[i], pSectorInstanceHandles[i]);
+ }
- return 0;
+ return XRAN_STATUS_SUCCESS;
}
int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
{
- XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
+ XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+ uint32_t nAllocBufferSize;
char pool_name[RTE_MEMPOOL_NAMESIZE];
- snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "bm_mempool_%ld", pPoolIndex);
+ snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
+ pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
+
+ nAllocBufferSize = nBufferSize + sizeof(struct ether_hdr) +
+ sizeof (struct xran_ecpri_hdr) +
+ sizeof (struct radio_app_common_hdr) +
+ sizeof(struct data_section_hdr) + 256;
+
+
+ printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name,
+ pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize);
- pXran->p_bufferPool[pXran->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
- MBUF_CACHE, 0, XRAN_MAX_MBUF_LEN, rte_socket_id());
+ pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
+ MBUF_CACHE, 0, nAllocBufferSize, rte_socket_id());
+
+ if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){
+ rte_panic("rte_pktmbuf_pool_create failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n",
+ pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno));
+ return -1;
+ }
- pXran->bufferPoolElmSz[pXran->nBufferPoolIndex] = nBufferSize;
- pXran->bufferPoolNumElm[pXran->nBufferPoolIndex] = nNumberOfBuffers;
+ pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex] = nBufferSize;
+ pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
- print_dbg("[nPoolIndex %d] mb pool %p \n", pXran->nBufferPoolIndex, pXran->p_bufferPool[pXran->nBufferPoolIndex]);
+ printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n",
+ pXranCc, pXranCc->nXranPort, pXranCc->nIndex,
+ pXranCc->nBufferPoolIndex, pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]);
- *pPoolIndex = pXran->nBufferPoolIndex++;
+ *pPoolIndex = pXranCc->nBufferPoolIndex++;
return 0;
}
-int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr)
+int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl)
{
- XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
- *ppVirtAddr = NULL;
+ XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+ *ppData = NULL;
+ *ppCtrl = NULL;
- struct rte_mbuf * mb = rte_pktmbuf_alloc(pXran->p_bufferPool[nPoolIndex]);
+ struct rte_mbuf * mb = rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
if(mb){
- *ppVirtAddr = rte_pktmbuf_append(mb, pXran->bufferPoolElmSz[nPoolIndex]);
-
+ char * start = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
+ char * ethhdr = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
+
+ if(start && ethhdr){
+ char * iq_offset = rte_pktmbuf_mtod(mb, char * );
+ /* skip headers */
+ iq_offset = iq_offset + sizeof(struct ether_hdr) +
+ sizeof (struct xran_ecpri_hdr) +
+ sizeof (struct radio_app_common_hdr) +
+ sizeof(struct data_section_hdr);
+
+ if (0) /* if compression */
+ iq_offset += sizeof (struct data_section_compression_hdr);
+
+ *ppData = (void *)iq_offset;
+ *ppCtrl = (void *)mb;
+ }
+ else {
+ print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex );
+ return -1;
+ }
}else {
print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
return -1;
}
- if (*ppVirtAddr == NULL){
- print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXran->bufferPoolElmSz[nPoolIndex]);
+ if (*ppData == NULL){
+ print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]);
return -1;
}
return 0;
}
-int32_t xran_bm_free_buffer(void * pHandle, void *pVirtAddr)
+int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
{
- XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
- rte_pktmbuf_free(pVirtAddr);
+ XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+
+ if(pCtrl)
+ rte_pktmbuf_free(pCtrl);
return 0;
}
int32_t xran_5g_fronthault_config (void * pHandle,
- XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XranTransportBlockCallbackFn pCallback,
+ struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ xran_transport_callback_fn pCallback,
void *pCallbackTag)
{
- XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
- XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
+ XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+ xran_status_t nStatus = XRAN_STATUS_SUCCESS;
int j, i = 0, z, k;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
print_dbg("%s\n", __FUNCTION__);
printf("Handle is NULL!\n");
return XRAN_STATUS_FAIL;
}
+
if (pCallback == NULL)
{
printf ("no callback\n");
return XRAN_STATUS_FAIL;
}
+ i = pXranCc->nIndex;
+
for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
{
for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulTxBuffers[j][i][z][0];
-
- p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j];
-
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulRxBuffers[j][i][z][0];
- p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
+ /* U-plane TX */
+
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxBuffers[j][i][z][0];
+
+ p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j];
+
+ /* C-plane TX */
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxPrbMapBuffers[j][i][z][0];
+
+ p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pSrcCpBuffer[z][j];
+
+ /* U-plane RX */
+
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxBuffers[j][i][z][0];
+
+ p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
+
+ /* C-plane RX */
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxPrbMapBuffers[j][i][z][0];
+
+ p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pDstCpBuffer[z][j];
}
}
for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
printf("TTI:TX 0x%02x Sec %d Ant%d\n",j,i,z);
for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
- uint8_t *ptr = p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
+ uint8_t *ptr = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
printf(" sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]);
}
}
for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
printf("TTI:RX 0x%02x Sec %d Ant%d\n",j,i,z);
for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
- uint8_t *ptr = p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
+ uint8_t *ptr = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
printf(" sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]);
}
}
#endif
- p_xran_lib_ctx->pCallback[i] = pCallback;
- p_xran_lib_ctx->pCallbackTag[i] = pCallbackTag;
+ p_xran_dev_ctx->pCallback[i] = pCallback;
+ p_xran_dev_ctx->pCallbackTag[i] = pCallbackTag;
- p_xran_lib_ctx->xran2phy_mem_ready = 1;
+ p_xran_dev_ctx->xran2phy_mem_ready = 1;
return nStatus;
}
int32_t xran_5g_prach_req (void * pHandle,
- XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
- XranTransportBlockCallbackFn pCallback,
+ struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
+ xran_transport_callback_fn pCallback,
void *pCallbackTag)
{
- XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
- XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
+ XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
+ xran_status_t nStatus = XRAN_STATUS_SUCCESS;
int j, i = 0, z;
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
if(NULL == pHandle)
{
return XRAN_STATUS_FAIL;
}
+ i = pXranCc->nIndex;
+
for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
{
for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFHPrachRxBuffers[j][i][z][0];
- p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHPrachRxBuffers[j][i][z][0];
+ p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
}
}
- p_xran_lib_ctx->pPrachCallback[i] = pCallback;
- p_xran_lib_ctx->pPrachCallbackTag[i] = pCallbackTag;
+ p_xran_dev_ctx->pPrachCallback[i] = pCallback;
+ p_xran_dev_ctx->pPrachCallbackTag[i] = pCallbackTag;
return 0;
}
-int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
- uint32_t nTxPhaseCps,
- uint32_t nRxPhaseCps,
- uint8_t nSectorId)
+int32_t xran_open(void *pHandle, struct xran_fh_config* pConf)
{
- /* functionality is not yet implemented */
- return 0;
-}
+ int32_t i;
+ uint8_t nNumerology = 0;
+ int32_t lcore_id = 0;
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
+ struct xran_fh_config *pFhCfg;
+ pFhCfg = &(p_xran_dev_ctx->fh_cfg);
-int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf)
-{
- int i;
- uint8_t slotNr;
- XRANFHCONFIG *pFhCfg;
- xRANPrachCPConfigStruct *pPrachCPConfig = &(xran_lib_get_ctx()->PrachCPConfig);
- pFhCfg = &(xran_lib_get_ctx()->xran_fh_cfg);
- memcpy(pFhCfg, pConf, sizeof(XRANFHCONFIG));
- PXRANPRACHCONFIG pPRACHConfig = &pFhCfg->prach_conf;
- uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
- const xRANPrachConfigTableStruct *pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
- uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
- const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt - FORMAT_A1];
- memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct));
+ memcpy(pFhCfg, pConf, sizeof(struct xran_fh_config));
- //setup PRACH configuration for C-Plane
- pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC; // 3, PRACH preamble format A1~3, B1~4, C0, C2
- pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
- pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
- pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
- pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
- pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
- pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
- pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
- pPrachCPConfig->x = pxRANPrachConfigTable->x;
- pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
- pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
+ nNumerology = xran_get_conf_numerology(pHandle);
- pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
- for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
+ if (pConf->nCC > XRAN_MAX_SECTOR_NR)
{
- slotNr = pxRANPrachConfigTable->slotNr[i];
- if (slotNr > 0)
- pPrachCPConfig->isPRACHslot[slotNr] = 1;
+ if(pConf->log_level)
+ printf("Number of cells %d exceeds max number supported %d!\n", pConf->nCC, XRAN_MAX_SECTOR_NR);
+ pConf->nCC = XRAN_MAX_SECTOR_NR;
+
+ }
+ if(pConf->ru_conf.iqOrder != XRAN_I_Q_ORDER
+ || pConf->ru_conf.byteOrder != XRAN_NE_BE_BYTE_ORDER ){
+
+ print_err("Byte order and/or IQ order is not suppirted [IQ %d byte %d]\n", pConf->ru_conf.iqOrder, pConf->ru_conf.byteOrder);
+ return XRAN_STATUS_FAIL;
}
+ //setup PRACH configuration for C-Plane
+ xran_init_prach(pConf, p_xran_dev_ctx);
+
xran_cp_init_sectiondb(pHandle);
xran_init_sectionid(pHandle);
xran_init_seqid(pHandle);
+ interval_us = xran_fs_get_tti_interval(nNumerology);
+
+ if(pConf->log_level){
+ printf("%s: interval_us=%ld\n", __FUNCTION__, interval_us);
+ }
+ timing_set_numerology(nNumerology);
+
+ for(i = 0 ; i <pConf->nCC; i++){
+ xran_fs_set_slot_type(i, pConf->frame_conf.nFrameDuplexType, pConf->frame_conf.nTddPeriod,
+ pConf->frame_conf.sSlotConfig);
+ }
+
+ xran_fs_slot_limit_init(xran_fs_get_tti_interval(nNumerology));
+
+ if(xran_ethdi_get_ctx()->io_cfg.bbdev_mode != XRAN_BBDEV_NOT_USED){
+ p_xran_dev_ctx->bbdev_dec = pConf->bbdev_dec;
+ p_xran_dev_ctx->bbdev_enc = pConf->bbdev_enc;
+ }
+
+ /* Start packet processing thread */
+ if((uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF] != 0xFFFF &&
+ (uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF] != 0xFFFF ){
+ if(pConf->log_level){
+ print_dbg("XRAN_UP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF]);
+ print_dbg("XRAN_CP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF]);
+ }
+ if (rte_eal_remote_launch(xran_timing_source_thread, xran_dev_get_ctx(), xran_ethdi_get_ctx()->io_cfg.timing_core))
+ rte_panic("thread_run() failed to start\n");
+ } else
+ if(pConf->log_level){
+ printf("Eth port was not open. Processing thread was not started\n");
+ }
+
+
+
return 0;
}
int32_t xran_close(void *pHandle)
{
xran_if_current_state = XRAN_STOPPED;
- xran_cp_free_sectiondb(pHandle);
- rte_eal_mp_wait_lcore();
+ //TODO: fix memory leak xran_cp_free_sectiondb(pHandle);
+ //rte_eal_mp_wait_lcore();
+ //xran_ethdi_ports_stats();
+
return 0;
}
return -1;
}
-int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb, uint8_t ant)
+int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant)
{
/* functionality is not yet implemented */
return -1;
}
-int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
+int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
{
- struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
+ struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
- p_xran_lib_ctx->ttiCb[id] = Cb;
- p_xran_lib_ctx->TtiCbParam[id] = cbParam;
- p_xran_lib_ctx->SkipTti[id] = skipTtiNum;
+ p_xran_dev_ctx->ttiCb[id] = Cb;
+ p_xran_dev_ctx->TtiCbParam[id] = cbParam;
+ p_xran_dev_ctx->SkipTti[id] = skipTtiNum;
return 0;
}
return tti;
}
-/**
- * @brief Get supported maximum number of sections
- *
- * @return maximum number of sections
- */
-inline uint8_t xran_get_max_sections(void *pHandle)
-{
- return (XRAN_MAX_NUM_SECTIONS);
-}
/**
* @brief Get the configuration of eAxC ID
*
* @return the pointer of configuration
*/
-inline XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle)
+inline struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle)
{
- return (&(xran_lib_get_ctx()->eAxc_id_cfg));
+ return (&(xran_dev_get_ctx()->eAxc_id_cfg));
}
/**
/**
* @brief Get the configuration of nummerology
*
- * @return subcarrier spacing value for PRACH
+ * @return Configured numerology
*/
inline uint8_t xran_get_conf_numerology(void *pHandle)
{
*/
inline uint8_t xran_get_conf_iqwidth(void *pHandle)
{
- XRANFHCONFIG *pFhCfg;
+ struct xran_fh_config *pFhCfg;
pFhCfg = xran_lib_get_ctx_fhcfg();
return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth);
return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth);
}
-/**
- * @brief Get the configuration of lls-cu ID
- *
- * @return Configured lls-cu ID
- */
-inline uint8_t xran_get_llscuid(void *pHandle)
-{
- return (xran_lib_get_ctx()->llscu_id);
-}
-
-/**
- * @brief Get the configuration of lls-cu ID
- *
- * @return Configured lls-cu ID
- */
-inline uint8_t xran_get_sectorid(void *pHandle)
-{
- return (xran_lib_get_ctx()->sector_id);
-}
/**
* @brief Get the configuration of the number of component carriers
*
- * @return Configured the number of componen carriers
+ * @return Configured the number of component carriers
*/
inline uint8_t xran_get_num_cc(void *pHandle)
{
return (xran_lib_get_ctx_fhcfg()->neAxc);
}
+int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats)
+{
+ struct xran_device_ctx* pDev = (struct xran_device_ctx*)pXranLayerHandle;
+
+ if(pStats && pDev) {
+ *pStats = pDev->fh_counters;
+ return XRAN_STATUS_SUCCESS;
+ } else {
+ return XRAN_STATUS_INVALID_PARAM;
+ }
+}
*
*******************************************************************************/
-
/**
* @brief Modules provide debug prints and utility functions
* @file xran_printf.h
#endif /* _IASSERT_*/
-
+#ifdef CHECK_PARAMS
+#define CHECK_NOT_NULL(param, returnValue) \
+if (param == NULL) \
+{ \
+ print_err("%s is NULL!\n", #param); \
+ return returnValue; \
+}
+#else
+#define CHECK_NOT_NULL(param, returnValue)
+#endif
#ifdef __cplusplus
}
* limitations under the License.
*
*******************************************************************************/
-
/**
* @brief This file provides implementation of synchronization related APIs (PTP/1588)
* for XRAN.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <math.h>
#include "xran_sync_api.h"
#include "xran_printf.h"
char full_path[BUF_LEN] = {0};
char read_proc_name[BUF_LEN] = {0};
int res = 1;
- int null = 0;
- int dir_fd = dirfd((DIR*)PROC_DIR);
- DIR *dir = fdopendir(dir_fd);
+ DIR *dir = opendir(PROC_DIR);
if (NULL == dir) {
return 1;
}
struct dirent *entry = NULL;
- while ((entry = readdir(dir))) {
+ while (entry = readdir(dir)) {
long pid = atol(entry->d_name);
if (0 == pid)
continue;
-
- snprintf(full_path, BUF_LEN,"%s/%ld/%s", PROC_DIR, pid, COMM_FILE);
- int proc_name_file = open(full_path, O_RDONLY);
- if (null == proc_name_file)
+ sprintf(full_path, "%s/%ld/%s", PROC_DIR, pid, COMM_FILE);
+ FILE *proc_name_file = fopen(full_path, "r");
+ if (NULL == proc_name_file)
continue;
- fgets( read_proc_name, BUF_LEN, (FILE*)proc_name_file);
+ fgets( read_proc_name, BUF_LEN, proc_name_file);
if (0 == strncmp(read_proc_name, pname, strlen(pname))) {
res = 0;
- close(proc_name_file);
+ fclose(proc_name_file);
break;
}
- close(proc_name_file);
+ fclose(proc_name_file);
}
closedir(dir);
return res;
*
*******************************************************************************/
-
/**
* @brief This file provides implementation to Timing for XRAN.
*
#include "xran_timer.h"
#include "xran_printf.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_mlog_lnx.h"
#include "xran_lib_mlog_tasks_id.h"
#include "ethdi.h"
+#include "xran_fh_o_du.h"
+#include "xran_common.h"
#define NSEC_PER_SEC 1000000000L
#define NSEC_PER_USEC 1000L
#define THRESHOLD 35 /**< the avg cost of clock_gettime() in ns */
#define TIMECOMPENSATION 2 /**< time compensation in us, avg latency of clock_nanosleep */
-#define SEC_MOD_STOP (30)
+#define SEC_MOD_STOP (60)
static struct timespec started_time;
static struct timespec last_time;
static unsigned long current_second = 0;
static unsigned long started_second = 0;
+static uint8_t numerlogy = 0;
extern uint32_t xran_lib_ota_sym;
extern uint32_t xran_lib_ota_tti;
extern uint32_t xran_lib_ota_sym_idx;
static int debugStop = 0;
+static int debugStopCount = 0;
+
+static long fine_tuning[5][2] =
+{
+ {71428L, 71429L}, /* mu = 0 */
+ {35714L, 35715L}, /* mu = 1 */
+ {0, 0}, /* mu = 2 not supported */
+ {8928L, 8929L}, /* mu = 3 */
+ {0,0 } /* mu = 4 not supported */
+};
+
+static uint8_t slots_per_subframe[4] =
+{
+ 1, /* mu = 0 */
+ 2, /* mu = 1 */
+ 4, /* mu = 2 */
+ 8, /* mu = 3 */
+};
uint64_t timing_get_current_second(void)
{
return current_second;
}
-int timing_set_debug_stop(int value)
+int timing_set_numerology(uint8_t value)
+{
+ numerlogy = value;
+ return numerlogy;
+}
+
+int timing_set_debug_stop(int value, int count)
{
debugStop = value;
+ debugStopCount = count;
if(debugStop){
clock_gettime(CLOCK_REALTIME, &started_time);
clock_gettime(CLOCK_REALTIME, p_cur_time);
delta = (p_cur_time->tv_sec * NSEC_PER_SEC + p_cur_time->tv_nsec) - target_time;
if(delta > 0 || (delta < 0 && abs(delta) < THRESHOLD)) {
+ if (debugStop &&(debugStopCount > 0) && (tx_counter >= debugStopCount)){
+ uint64_t t1;
+ printf("STOP:[%ld.%09ld], debugStopCount %d, tx_counter %ld\n", p_cur_time->tv_sec, p_cur_time->tv_nsec, debugStopCount, tx_counter);
+ t1 = MLogTick();
+ rte_pause();
+ MLogTask(PID_TIME_SYSTIME_STOP, t1, MLogTick());
+ xran_if_current_state = XRAN_STOPPED;
+ }
if(current_second != p_cur_time->tv_sec){
current_second = p_cur_time->tv_sec;
xran_lib_ota_sym_idx = 0;
}
p_cur_time->tv_nsec = 0; // adjust to 1pps
} else {
- xran_lib_ota_sym_idx = XranIncrementSymIdx(xran_lib_ota_sym_idx, 14*8);
+ xran_lib_ota_sym_idx = XranIncrementSymIdx(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*slots_per_subframe[numerlogy]);
/* adjust to sym boundary */
if(sym_cnt & 1)
- sym_acc += 8928L;
+ sym_acc += fine_tuning[numerlogy][0];
else
- sym_acc += 8929L;
+ sym_acc += fine_tuning[numerlogy][1];
/* fine tune to second boundary */
if(sym_cnt % 13 == 0)
sym_acc += 1;
p_last_time = p_cur_time;
p_cur_time = p_temp_time;
break;
+ } else {
+ if( likely(xran_if_current_state == XRAN_RUNNING)){
+ ring_processing_func();
+ process_dpdk_io();
+ }
}
}
*
*******************************************************************************/
-
/**
* @brief This file provides the implementation for Transport lyaer (eCPRI) API.
*
#include <rte_common.h>
#include <rte_config.h>
-#include "xran_fh_lls_cu.h"
+#include "xran_fh_o_du.h"
#include "xran_common.h"
#include "xran_transport.h"
+#include "xran_pkt_cp.h"
+#include "xran_cp_api.h"
#include "xran_up_api.h"
+#include "xran_printf.h"
+/**
+ * @brief return eCPRI header size without eCPRI common header
+ *
+ * @ingroup xran
+ *
+ * @return the size of eCPRI header without common header
+ */
+int xran_get_ecpri_hdr_size(void)
+{
+ return(sizeof(struct xran_ecpri_hdr) - sizeof(struct xran_ecpri_cmn_hdr));
+}
+
/**
* @brief Compose ecpriRtcid/ecpriPcid
*
+ * @ingroup xran
+ *
* @param CU_Port_ID CU Port ID
* @param BanbSector_ID Band Sector ID
* @param CC_ID Component Carrier ID
* @param Ant_ID RU Port ID (antenna ID)
* @return uint16_t composed ecpriRtcid/ecpriPcid (network byte order)
*/
-inline uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)
+uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)
{
uint16_t cid;
- XRANEAXCIDCONFIG *conf;
+ struct xran_eaxcid_config *conf;
conf = xran_get_conf_eAxC(NULL);
/**
* @brief Decompose ecpriRtcid/ecpriPcid
*
+ * @ingroup xran
+ *
* @param cid composed ecpriRtcid/ecpriPcid (network byte order)
* @param result the pointer of the structure to store decomposed values
* @return none
*/
-inline void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
+void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
{
- XRANEAXCIDCONFIG *conf;
+ struct xran_eaxcid_config *conf;
conf = xran_get_conf_eAxC(NULL);
cid = rte_be_to_cpu_16(cid);
/**
* @brief modify the payload size of eCPRI header in xRAN packet
*
+ * @ingroup xran
+ *
* @param mbuf Initialized rte_mbuf packet which has eCPRI header already
* @param size payload size to be updated
* @return none
ecpri_hdr = rte_pktmbuf_mtod(mbuf, struct xran_ecpri_hdr *);
- ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(size);
+ ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(size);
+}
+
+
+/**
+ * @brief Build ECPRI header and returns added length
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ * The pointer of the packet buffer to be parsed
+ * @param CC_ID
+ * Component Carrier ID for this C-Plane message
+ * @param Ant_ID
+ * Antenna ID(RU Port ID) for this C-Plane message
+ * @param seq_id
+ * Sequence ID for this C-Plane message
+ * @param ecpri_hdr
+ * The pointer to ECPRI header
+ * @return
+ * added payload size on success
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
+ uint8_t CC_ID, uint8_t Ant_ID,
+ uint8_t seq_id,
+ struct xran_ecpri_hdr **ecpri_hdr)
+{
+ uint32_t payloadlen;
+ struct xran_ecpri_hdr *tmp;
+
+
+ tmp = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
+ if(unlikely(tmp == NULL)) {
+ print_err("Fail to allocate the space for eCPRI hedaer!");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ /* Fill common header */
+ tmp->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
+ tmp->cmnhdr.ecpri_resv = 0; // should be zero
+ tmp->cmnhdr.ecpri_concat = 0;
+ tmp->cmnhdr.ecpri_mesg_type = ECPRI_RT_CONTROL_DATA;
+ tmp->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
+
+ /* TODO: Transport layer fragmentation is not supported */
+ tmp->ecpri_seq_id.seq_id = seq_id;
+ tmp->ecpri_seq_id.sub_seq_id = 0;
+ tmp->ecpri_seq_id.e_bit = 1;
+
+ /* Starts with eCPRI header size */
+ payloadlen = xran_get_ecpri_hdr_size();
+
+ *ecpri_hdr = tmp;
+
+ return (payloadlen);
+}
+
+/**
+ * @brief Parse ECPRI header
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ * The pointer of the packet buffer to be parsed
+ * @param ecpri_hdr
+ * The pointer to ECPRI header
+ * @param pkt_info
+ * The pointer of sturcture to store the information from header
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
+ */
+int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
+ struct xran_ecpri_hdr **ecpri_hdr,
+ struct xran_recv_packet_info *pkt_info)
+{
+ int ret;
+
+
+ *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
+ if(*ecpri_hdr == NULL) {
+ print_err("Invalid packet - eCPRI hedaer!");
+ return (XRAN_STATUS_INVALID_PACKET);
+ }
+
+ /* Process eCPRI header */
+ ret = XRAN_STATUS_SUCCESS;
+ if((*ecpri_hdr)->cmnhdr.ecpri_ver != XRAN_ECPRI_VER) {
+ print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.ecpri_ver);
+ ret = XRAN_STATUS_INVALID_PACKET;
+ }
+ if((*ecpri_hdr)->cmnhdr.ecpri_resv != 0) {
+ print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.ecpri_resv);
+ ret = XRAN_STATUS_INVALID_PACKET;
+ }
+
+ if(pkt_info != NULL) {
+ /* store the information from header */
+ pkt_info->ecpri_version = (*ecpri_hdr)->cmnhdr.ecpri_ver;
+ pkt_info->msg_type = (enum ecpri_msg_type)(*ecpri_hdr)->cmnhdr.ecpri_mesg_type;
+ pkt_info->payload_len = rte_be_to_cpu_16((*ecpri_hdr)->cmnhdr.ecpri_payl_size);
+
+ pkt_info->seq_id = (*ecpri_hdr)->ecpri_seq_id.seq_id;
+ pkt_info->subseq_id = (*ecpri_hdr)->ecpri_seq_id.sub_seq_id;
+ pkt_info->ebit = (*ecpri_hdr)->ecpri_seq_id.e_bit;
+ xran_decompose_cid((*ecpri_hdr)->ecpri_xtc_id, &(pkt_info->eaxc));
+ }
+
+ return (ret);
}
*
*******************************************************************************/
-
/**
* @brief This file defines those table used in 5G NR spec.
* @file xran_ul_tables.c
{ 255, { FORMAT_A3, FORMAT_B3 }, 1, { 0 }, { 7, 15, 23, 31, 39 }, 5, 2, 1, 2, 6 },
};
-const xRANPrachPreambleLRAStruct gxranPreambleforLRA[XRAN_PRACH_PREAMBLE_FORMAT_OF_ABC] =
+const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13] =
{
+ {FORMAT_0, 839, 125, 1 , 3168 },
+ {FORMAT_1, 839, 125, 2 ,21024 },
+ {FORMAT_2, 839, 125, 4 , 4688 },
+ {FORMAT_3, 839, 5, 1 , 3168 },
{FORMAT_A1, 139, 15, 2 , 288 },
{FORMAT_A2, 139, 15, 4 , 576 },
{FORMAT_A3, 139, 15, 6 , 864 },
* @author Intel Corporation
*
**/
+#include <inttypes.h>
#include <rte_memcpy.h>
-#include <inttypes.h>
-#include "xran_fh_lls_cu.h"
+#include <rte_mbuf.h>
+
+#include "xran_fh_o_du.h"
#include "xran_transport.h"
#include "xran_up_api.h"
-#ifndef MLOG_ENABLED
-#include "mlog_lnx_xRAN.h"
-#else
-#include "mlog_lnx.h"
-#endif
+#include "xran_printf.h"
+#include "xran_mlog_lnx.h"
extern uint32_t xran_lib_ota_tti;
-
/**
* @brief Builds eCPRI header in xRAN packet
*
if (NULL == ecpri_hdr)
return 1;
- ecpri_hdr->ecpri_ver = XRAN_ECPRI_VER;
- ecpri_hdr->ecpri_resv = 0;
- ecpri_hdr->ecpri_concat = 0;
- ecpri_hdr->ecpri_mesg_type = ECPRI_IQ_DATA;
+ ecpri_hdr->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
+ ecpri_hdr->cmnhdr.ecpri_resv = 0;
+ ecpri_hdr->cmnhdr.ecpri_concat = 0;
+ ecpri_hdr->cmnhdr.ecpri_mesg_type = ECPRI_IQ_DATA;
if (iq_data_offset + iq_samples_bytes_in_mbuf > iq_data_num_bytes) {
- ecpri_hdr->ecpri_payl_size =
+ ecpri_hdr->cmnhdr.ecpri_payl_size =
rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
sizeof(struct data_section_hdr) +
- (iq_data_num_bytes - iq_data_offset));
+ (iq_data_num_bytes - iq_data_offset) +
+ xran_get_ecpri_hdr_size());
ecpri_hdr->ecpri_seq_id.e_bit = 1; /* last segment */
} else {
- ecpri_hdr->ecpri_payl_size =
+ ecpri_hdr->cmnhdr.ecpri_payl_size =
rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
sizeof(struct data_section_hdr) +
- iq_samples_bytes_in_mbuf);
+ iq_samples_bytes_in_mbuf +
+ xran_get_ecpri_hdr_size());
ecpri_hdr->ecpri_seq_id.e_bit = 0;
}
uint8_t Ant_ID,
uint8_t seq_id)
{
- struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)
- rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
+ char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+ struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)(pChar + sizeof(struct ether_hdr));
if (NULL == ecpri_hdr)
return 1;
- ecpri_hdr->ecpri_ver = XRAN_ECPRI_VER;
- ecpri_hdr->ecpri_resv = 0; // should be zero
- ecpri_hdr->ecpri_concat = 0;
- ecpri_hdr->ecpri_mesg_type = ecpri_mesg_type;
- ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(payl_size
- + sizeof(struct data_section_hdr)+sizeof(struct radio_app_common_hdr));
+ ecpri_hdr->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
+ ecpri_hdr->cmnhdr.ecpri_resv = 0; // should be zero
+ ecpri_hdr->cmnhdr.ecpri_concat = 0;
+ ecpri_hdr->cmnhdr.ecpri_mesg_type = ecpri_mesg_type;
+ ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payl_size
+ + sizeof(struct data_section_hdr)
+ + sizeof(struct radio_app_common_hdr)
+ + xran_get_ecpri_hdr_size());
/* one to one lls-CU to RU only and band sector is the same */
ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
struct rte_mbuf *mbuf,
const struct radio_app_common_hdr *app_hdr_input)
{
- struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)
- rte_pktmbuf_append(mbuf, sizeof(struct radio_app_common_hdr));
+ char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+ struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)(pChar + sizeof(struct ether_hdr)
+ + sizeof (struct xran_ecpri_hdr));
if (NULL == app_hdr)
return 1;
struct rte_mbuf *mbuf,
const struct data_section_hdr *sec_hdr)
{
+ char *pChar = rte_pktmbuf_mtod(mbuf, char*);
struct data_section_hdr *section_hdr = (struct data_section_hdr *)
- rte_pktmbuf_append(mbuf, sizeof(struct data_section_hdr));
+ (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr));
if (NULL == section_hdr)
return 1;
static uint16_t append_iq_samples_ex(
struct rte_mbuf *mbuf,
const void *iq_data_start,
- const uint32_t iq_data_num_bytes)
+ const uint32_t iq_data_num_bytes,
+ enum xran_input_byte_order iq_buf_byte_order,
+ uint32_t do_copy)
{
- uint16_t free_space_in_pkt = rte_pktmbuf_tailroom(mbuf);
+ char *pChar = rte_pktmbuf_mtod(mbuf, char*);
+ void *iq_sam_buf = (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr)
+ + sizeof(struct radio_app_common_hdr)
+ + sizeof(struct data_section_hdr));
- if(free_space_in_pkt >= iq_data_num_bytes){
-
- void *iq_sam_buf = (void *)rte_pktmbuf_append(mbuf, iq_data_num_bytes);
- if (iq_sam_buf == NULL)
- return 0;
-#ifdef XRAN_BYTE_ORDER_SWAP
+ if (iq_sam_buf == NULL){
+ print_err("iq_sam_buf == NULL\n");
+ return 0;
+ }
+ if(iq_buf_byte_order == XRAN_CPU_LE_BYTE_ORDER){
int idx = 0;
- uint16_t *restrict psrc = (uint16_t *)iq_data_start;
- uint16_t *restrict pdst = (uint16_t *)iq_sam_buf;
+ uint16_t *psrc = (uint16_t *)iq_data_start;
+ uint16_t *pdst = (uint16_t *)iq_sam_buf;
/* CPU byte order (le) of IQ to network byte order (be) */
for (idx = 0; idx < iq_data_num_bytes/sizeof(int16_t); idx++){
pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_cpu_to_be_16(psrc[idx]);
}
-#else
-#error xran spec is network byte order
- /* for debug */
- rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start, iq_data_num_bytes);
-
-#endif
-
- return iq_data_num_bytes;
+ }else if(iq_buf_byte_order == XRAN_NE_BE_BYTE_ORDER){
+ if(do_copy)
+ rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start, iq_data_num_bytes);
}
- return 0;
+ return iq_data_num_bytes;
}
-
/**
* @brief Function for appending IQ samples data to the mbuf.
*
uint8_t *subframe_id,
uint8_t *slot_id,
uint8_t *symb_id,
- struct ecpri_seq_id *seq_id)
+ struct ecpri_seq_id *seq_id,
+ uint16_t *num_prbu,
+ uint16_t *start_prbu,
+ uint16_t *sym_inc,
+ uint16_t *rb,
+ uint16_t *sect_id)
{
+#if XRAN_MLOG_VAR
uint32_t mlogVar[10];
uint32_t mlogVarCnt = 0;
+#endif
struct xran_eaxc_info result;
if (NULL == mbuf)
*symb_id = radio_hdr->sf_slot_sym.symb_id;
/* Process data section hdr */
- const struct data_section_hdr *data_hdr =
+ struct data_section_hdr *data_hdr =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));
if (data_hdr == NULL)
return 0; /* packet too short */
+ /* cpu byte order */
+ data_hdr->fields.all_bits = rte_be_to_cpu_32(data_hdr->fields.all_bits);
+
+ *num_prbu = data_hdr->fields.num_prbu;
+ *start_prbu = data_hdr->fields.start_prbu;
+ *sym_inc = data_hdr->fields.sym_inc;
+ *rb = data_hdr->fields.rb;
+ *sect_id = data_hdr->fields.sect_id;
+
#ifdef COMPRESSION
const struct data_section_compression_hdr *data_compr_hdr =
(void *) rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
if (*iq_data_start == NULL)
return 0;
- mlogVar[mlogVarCnt++] = 0xBBBBBBB;
+#if XRAN_MLOG_VAR
+ mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
mlogVar[mlogVarCnt++] = radio_hdr->frame_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.subframe_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.slot_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.symb_id;
+ mlogVar[mlogVarCnt++] = data_hdr->fields.sect_id;
+ mlogVar[mlogVarCnt++] = data_hdr->fields.start_prbu;
+ mlogVar[mlogVarCnt++] = data_hdr->fields.num_prbu;
mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(mbuf);
MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
+#endif
return rte_pktmbuf_pkt_len(mbuf);
}
int xran_prepare_iq_symbol_portion_no_comp(
struct rte_mbuf *mbuf,
const void *iq_data_start,
+ const enum xran_input_byte_order iq_buf_byte_order,
const uint32_t iq_data_num_bytes,
struct xran_up_pkt_gen_no_compression_params *params,
uint8_t CC_ID,
uint8_t Ant_ID,
- uint8_t seq_id)
+ uint8_t seq_id,
+ uint32_t do_copy)
{
if(xran_build_ecpri_hdr_ex(mbuf,
ECPRI_IQ_DATA,
iq_data_num_bytes,
CC_ID,
Ant_ID,
- seq_id))
+ seq_id)){
+ print_err("xran_build_ecpri_hdr_ex return 0\n");
return 0;
+ }
- if (build_application_layer(mbuf, &(params->app_params)) != 0)
+ if (build_application_layer(mbuf, &(params->app_params)) != 0){
+ print_err("build_application_layer return != 0\n");
return 0;
+ }
- if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0)
+ if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0){
+ print_err("build_section_hdr return != 0\n");
return 0;
+ }
- return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes);
+ return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes, iq_buf_byte_order, do_copy);
}
#* distributed under the License is distributed on an "AS IS" BASIS,
#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#* See the License for the specific language governing permissions and
-#* limitations under the License.
+#* limitations under the License.
#*
#*******************************************************************************/
1. Introduction
xRAN Lib performs communication between the low-layer split central unit (lls-CU) and RU, it is highly-optimized software implementation based on Intel Architecture to provide the standard interface implementation based on O-RAN front haul interface specification.
2. Supported features
-please refer PRD in the table <<xRAN release track table.xlsx>>, only ICC compiler was supported for this version.
+Please refer to the Document ORAN Front Haul Interface Library based on Intel's xRAN Front Haul SW Architecture Specifications Section 4.2 Supported Feature Set, both GCC/ICC compiler are supported for this version.
3. Fixed Issues
It's first version of seed code for feature development, future fixed issues will be tracked here.
4. Known Issues
-From current unit testing coverage, no Know issues was founded yet.
+From current unit testing coverage, no issues have been found yet.
5. Prerequisites for install
-5.1 Intel Compiler version
+5.1. Prerequisites
+
+5.1.0 System configuration
+
+VFIO requires:
+linux:
+ IOMMU=ON
+BIOS:
+ Intel(R) Virtualization Technology Enabled
+ Intel(R) VT for Directed I/O - Enabled
+ ACS Control - Enabled
+ Coherency Support - Disabled
+5.1.1 Compiler
+
icc -v
-icc version 18.0.1 (gcc version 4.8.5 compatibility)
+icc version 19.0.3.206 (gcc version 4.8.5 compatibility)
Link to ICC (community free version):
https://software.intel.com/en-us/system-studio/choose-download#technical
+5.1.2 DPDK 18.08
-5.2 DPDK version
-dpdk_18.08
-
-5.3 compile DPDK with command
-[dpdk]# ./usertools/dpdk-setup.sh
+5.1.3 Compile DPDK with
+[root@5gnr-sc12-xran dpdk]# ./usertools/dpdk-setup.sh // Where the root@5gnr-sc12-xran dpdk corresponds to the location in the server for the dpdk installation folder
select [16] x86_64-native-linuxapp-icc
-select [18] Insert IGB UIO module
+select [19] Insert VFIO module
exit [35] Exit Script
-5.4 Find PCIe device of Fortville port
+5.1.4 Find PCIe device of Fortville port
lspci |grep Eth
19:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
d8:00.0 << Ethernet controller: Intel Corporation Ethernet Controller XL710 for 40GbE QSFP+ (rev 02) <<<< this one
d8:00.1 Ethernet controller: Intel Corporation Ethernet Controller XL710 for 40GbE QSFP+ (rev 02)
-5.5 Corresponding Eth device via
+5.1.5 Corresponding Eth device via
ifconfig -a
find port Eth with correct PCIe Bus address as per list above
-ethtool -i enp216s0f0
+ethtool -i enp218s0f0
driver: i40e
-version: 2.4.10 << i40e driver
-firmware-version: 6.01 0x800034a4 1.1747.0
+version: 2.4.10 << driver
+firmware-version: 6.80 0x80003cfd 1.2007.0
expansion-rom-version:
-bus-info: 0000:d8:00.0 <<< this one
+bus-info: 0000:da:00.0 << this one
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes
-5.6 install correct 2.4.10 i40e version if different (https://downloadcenter.intel.com/download/28306/Intel-Network-Adapter-Driver-for-PCIe-40-Gigabit-Ethernet-Network-Connections-Under-Linux-)
+5.1.6 install correct 2.4.10 i40e version if different (https://downloadcenter.intel.com/download/28306/Intel-Network-Adapter-Driver-for-PCIe-40-Gigabit-Ethernet-Network-Connections-Under-Linux-)
-make sure firmare version is
+make sure firmare version is at least this version or higher
-firmware-version: 6.01
+firmware-version: 6.01
-5.7 make sure that linux boot arguments are correct
+5.1.7 make sure that linux boot arguments are correct
cat /proc/cmdline
-BOOT_IMAGE=/vmlinuz-3.10.0-rt56 root=/dev/mapper/centos_5gnr--skx--sp-root ro crashkernel=auto rd.lvm.lv=centos_5gnr-skx-sp/root rd.lvm.lv=centos_5gnr-skx-sp/swap intel_iommu=off usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 intel_pstate=disable cgroup_disable=memory mce=off idle=poll hugepagesz=1G hugepages=20 hugepagesz=2M hugepages=0 default_hugepagesz=1G isolcpus=1-35 rcu_nocbs=1-35 kthread_cpus=0 irqaffinity=0 nohz_full=1-35
-
-5.8 enable SRIOV VF port for XRAN
+BOOT_IMAGE=/vmlinuz-3.10.0-rt56 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap intel_iommu=on iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 intel_pstate=disable cgroup_disable=memory mce=off idle=poll hugepagesz=1G hugepages=20 hugepagesz=2M hugepages=0 default_hugepagesz=1G isolcpus=1-39 rcu_nocbs=1-39 kthread_cpus=0 irqaffinity=0 nohz_full=1-39
+1.10 enable SRIOV VF port for XRAN
echo 2 > /sys/class/net/enp216s0f0/device/sriov_numvfs
see https://doc.dpdk.org/guides/nics/intel_vf.html
-5.9 Check Virtual Function was created
+5.1.8 Check Virtual Function was created
lspci |grep Eth
19:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
d8:02.0 Ethernet controller: Intel Corporation XL710/X710 Virtual Function (rev 02) <<<< this is XRAN port (u-plane)
d8:02.1 Ethernet controller: Intel Corporation XL710/X710 Virtual Function (rev 02) <<<< this is XRAN port (c-plane)
-5.10 Configure VFs
+5.1.9 Configure VFs
- set mac to 00:11:22:33:44:66
- set Vlan tag to 2 (U-plane) for VF0
- set Vlan tag to 1 (C-plane) for VF1
link/ether 96:fa:4d:04:4d:87 brd ff:ff:ff:ff:ff:ff
13: enp216s2f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000
link/ether a6:67:49:bb:bd:5e brd ff:ff:ff:ff:ff:ff
-
-6. Install xRAN Lib
-
-6.1 start matlab and run gen_test.m
-copy ant_*.bin to /xran/app
-
-6.2 build xran sample application
-export XRAN_DIR=xRAN folder
-export RTE_SDK=dpdk folder
-[xRAN root folder]$ ./build.sh
-6.3 update Eth port used for XRAN
-in ./app/run_lls-cu.sh
-ports have to match VF function from step 1.11 (0000:d8:02.0 - U-plane 0000:d8:02.1 C-plane)
-
-6.4 Run dpdk.sh to assign port to PMD
-
-[xran root folder]# ./app/dpdk.sh
+6. Install
+
+6.1.1 start matlab and run gen_test.m with correct Numerology, Bandwidth and number of slots
+copy ant_*.bin to /xran/app/usecase/mu{X}_{Y}MHz
+ where X is numerology: 0,1,3
+ Y is 5,10,20,100 MHz bandwidth
+
+6.1.2 compile xran sample application (Please make sure that the export match your install directories for SDK, ORAN_FH_lib (i.e. XRAN_DIR), google test
+export RTE_SDK=/opt/dpdk-18.08
+export RTE_TARGET=x86_64-native-linuxapp-icc
+export XRAN_DIR= /home/npg_wireless-flexran_xran/
+export export GTEST_ROOT=/opt/gtest/gtest-1.7.0
+
+ ./build.sh
+Number of commandline arguments: 0
+Building xRAN Library
+LIBXRANSO=0
+ CC ../lib/ethernet/ethdi.o
+ CC ../lib/ethernet/ethernet.o
+ CC ../lib/src/xran_up_api.o
+ CC ../lib/src/xran_sync_api.o
+ CC ../lib/src/xran_timer.o
+ CC ../lib/src/xran_cp_api.o
+ CC ../lib/src/xran_transport.o
+ CC ../lib/src/xran_common.o
+ CC ../lib/src/xran_ul_tables.o
+ CC ../lib/src/xran_frame_struct.o
+ CC ../lib/src/xran_compression.o
+ CC ../lib/src/xran_app_frag.o
+ CC ../lib/src/xran_main.o
+ AR libxran.a
+ INSTALL-LIB libxran.a
+Building xRAN Test Application
+ CC ../app/src/common.o
+ CC ../app/src/sample-app.o
+remark #11074: Inlining inhibited by limit max-size
+remark #11076: To get full report use -qopt-report=4 -qopt-report-phase ipo
+ CC ../app/src/config.o
+ LD sample-app
+ INSTALL-APP sample-app
+ INSTALL-MAP sample-app.map
+
+
+6.1.3 update Eth port used for XRAN
+
+
+cat ./run_o_du.sh
+#! /bin/bash
+
+ulimit -c unlimited
+echo 1 > /proc/sys/kernel/core_uses_pid
+
+grep Huge /proc/meminfo
+huge_folder="/mnt/huge_bbu"
+[ -d "$huge_folder" ] || mkdir -p $huge_folder
+if ! mount | grep $huge_folder; then
+ mount none $huge_folder -t hugetlbfs -o rw,mode=0777
+fi
+
+#40G
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat 0000:da:02.0 0000:da:02.1
+ ^^^^^ ports have to match VF function from step 1.11 (0000:da:02.0 - U-plane 0000:da:02.1 C-plane)
+
+umount $huge_folder
+rmdir $huge_folder
+
+
+cat ./dpdk.sh
+...
+$RTE_SDK/usertools/dpdk-devbind.py --status
+if [ ${VM_DETECT} == 'HOST' ]; then
+ #HOST
+
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.0 <<< port has to match VF function from step 1.11
+ $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:da:02.1 <<< port has to match VF function from step 1.11
+
+ 1.
+Run
+
+6.2.1 Run dpdk.sh to assign port to PMD
+
+[root@5gnr-sc12-xran app]# ./dpdk.sh
Network devices using DPDK-compatible driver
============================================
-0000:d8:02.0 'XL710/X710 Virtual Function 154c' drv=igb_uio unused=i40evf
-0000:d8:02.1 'XL710/X710 Virtual Function 154c' drv=igb_uio unused=i40evf
-
-
-6.5 Run XRAN lls-CU sample app
-setup RU mac address in config_file_lls_cu.dat
-[xran root folder]# ./app/run_lls-cu.sh
-
+0000:da:02.0 'XL710/X710 Virtual Function 154c' drv=vfio-pci unused=i40evf,igb_uio
+0000:da:02.1 'XL710/X710 Virtual Function 154c' drv=vfio-pci unused=i40evf,igb_uio
+
+
+6.2.2 Run XRAN sample app
+setup RU mac address in config_file_o_du.dat for corespondig usecase
+
+e.g.
+./build/sample-app ./usecase/mu3_100mhz/config_file_o_du.dat 0000:da:02.0 0000:da:02.1
+
+ruMac=00:11:22:33:44:55 #RU VF for RU
+
+execute O-DU sample app
+
+[root@sc12-xran-ru-1 app]# ./run_o_du.sh
+HugePages_Total: 20
+HugePages_Free: 11
+HugePages_Rsvd: 0
+HugePages_Surp: 0
+Hugepagesize: 1048576 kB
+Machine is synchronized using PTP!
+mu_number: 3
+nDLAbsFrePointA: 27968160
+nULAbsFrePointA: 27968160
+nDLBandwidth: 100
+nULBandwidth: 100
+nULFftSize: 1024
+nULFftSize: 1024
+nFrameDuplexType: 1
+nTddPeriod: 4
+sSlotConfig0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+sSlotConfig3: 0 2 2 1 1 1 1 1 1 1 1 1 1 1
+mtu 9600
+lls-CU MAC address: 00:11:22:33:44:66
+RU MAC address: 00:11:22:33:44:55
+numSlots: 40
+antC0: ./usecase/mu3_100mhz/ant_0.bin
+antC1: ./usecase/mu3_100mhz/ant_1.bin
+antC2: ./usecase/mu3_100mhz/ant_2.bin
+antC3: ./usecase/mu3_100mhz/ant_3.bin
+antC4: ./usecase/mu3_100mhz/ant_4.bin
+antC5: ./usecase/mu3_100mhz/ant_5.bin
+antC6: ./usecase/mu3_100mhz/ant_6.bin
+antC7: ./usecase/mu3_100mhz/ant_7.bin
+antC8: ./usecase/mu3_100mhz/ant_8.bin
+antC9: ./usecase/mu3_100mhz/ant_9.bin
+antC10: ./usecase/mu3_100mhz/ant_10.bin
+antC11: ./usecase/mu3_100mhz/ant_11.bin
+antC12: ./usecase/mu3_100mhz/ant_12.bin
+antC13: ./usecase/mu3_100mhz/ant_13.bin
+antC14: ./usecase/mu3_100mhz/ant_14.bin
+antC15: ./usecase/mu3_100mhz/ant_15.bin
+Prach enable: 0
+Prach config index: 81
+debugStop: 1
+CPenable: 1
+cp_vlan_tag: 1
+up_vlan_tag: 2
+Tadv_cp_dl: 25
+T2a_min_cp_dl: 50
+T2a_max_cp_dl: 140
+T2a_min_cp_ul: 50
+T2a_max_cp_ul: 140
+T2a_min_up: 25
+T2a_max_up: 140
+Ta3_min: 20
+Ta3_max: 32
+T1a_min_cp_dl: 70
+T1a_max_cp_dl: 100
+T1a_min_cp_ul: 60
+T1a_max_cp_ul: 70
+T1a_min_up: 35
+T1a_max_up: 50
+Ta4_min: 0
+Ta4_max: 45
+115 lines of config file has been read.
+numCCPorts 1 num_eAxc4
+set O-DU
+IQ files size is 40 slots
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+Loading file ./usecase/mu3_100mhz/ant_0.bin to DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62ad088010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_1.bin to DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62aced6010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_2.bin to DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62acd24010) size (1774080) bytes num (1774080)
+Loading file ./usecase/mu3_100mhz/ant_3.bin to DL IFFT IN IQ Samples in binary format: Reading IQ samples from file: File Size: 1774080 [Buffer Size: 1774080]
+from addr (0x7f62acb72010) size (1774080) bytes num (1774080)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant0.txt: from addr (0x7f62ad088010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant0.bin: from addr (0x7f62ad088010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant1.txt: from addr (0x7f62aced6010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant1.bin: from addr (0x7f62aced6010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant2.txt: from addr (0x7f62acd24010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant2.bin: from addr (0x7f62acd24010) size (887040) bytes num (887040)
+Storing DL IFFT IN IQ Samples in human readable format to file ./logs/o-du-play_ant3.txt: from addr (0x7f62acb72010) size (1774080) IQ num (443520)
+Storing DL IFFT IN IQ Samples in binary format to file ./logs/o-du-play_ant3.bin: from addr (0x7f62acb72010) size (887040) bytes num (887040)
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [0]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [1]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [2]
+TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [3]
+System clock (rdtsc) resolution 1596250371 [Hz]
+Ticks per us 1596
+ xran_init: MTU 9600
+xran_ethdi_init_dpdk_io: Calling rte_eal_init:wls -c ffffffff -m5120 --proc-type=auto --file-prefix wls -w 0000:00:00.0
+EAL: Detected 40 lcore(s)
+EAL: Detected 2 NUMA nodes
+EAL: Auto-detected process type: PRIMARY
+EAL: Multi-process socket /var/run/dpdk/wls/mp_socket
+EAL: No free hugepages reported in hugepages-2048kB
+EAL: Probing VFIO support...
+EAL: VFIO support initialized
+EAL: PCI device 0000:da:02.0 on NUMA socket 1
+EAL: probe driver: 8086:154c net_i40e_vf
+EAL: using IOMMU type 1 (Type 1)
+initializing port 0 for TX, drv=net_i40e_vf
+Port 0 MAC: 00 11 22 33 44 66
+
+Checking link status ... done
+Port 0 Link Up - speed 40000 Mbps - full-duplex
+EAL: PCI device 0000:da:02.1 on NUMA socket 1
+EAL: probe driver: 8086:154c net_i40e_vf
+initializing port 1 for TX, drv=net_i40e_vf
+Port 1 MAC: 00 11 22 33 44 66
+
+Checking link status ... done
+Port 1 Link Up - speed 40000 Mbps - full-duplex
+Set debug stop 1
+FFT Order 10
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_get_num_rbs: nNumerology[3] nBandwidth[100] nAbsFrePointA[27968160] numRBs[66]
+app_xran_cal_nrarfcn: nCenterFreq[28015680] nDeltaFglobal[60] nFoffs[24250080] nNoffs[2016667] nNRARFCN[2079427]
+DL center freq 28015680 DL NR-ARFCN 2079427
+app_xran_cal_nrarfcn: nCenterFreq[28015680] nDeltaFglobal[60] nFoffs[24250080] nNoffs[2016667] nNRARFCN[2079427]
+UL center freq 28015680 UL NR-ARFCN 2079427
+XRAN front haul xran_mm_init
+xran_sector_get_instances [0]: CC 0 handle 0xd013380
+Handle: 0x5a07cb8 Instance: 0xd013380
+init_xran [0]: CC 0 handle 0xd013380
+Sucess xran_mm_init
+nSectorNum 1
+nSectorIndex[0] = 0
+[ handle 0xd013380 0 0 ] [nPoolIndex 0] nNumberOfBuffers 4480 nBufferSize 3328
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 0] mb pool 0x24a7ad440
+nSectorIndex[0] = 0
+[ handle 0xd013380 0 0 ] [nPoolIndex 1] nNumberOfBuffers 4480 nBufferSize 2216
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 1] mb pool 0x24956d100
+[ handle 0xd013380 0 0 ] [nPoolIndex 2] nNumberOfBuffers 4480 nBufferSize 3328
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 2] mb pool 0x248818dc0
+[ handle 0xd013380 0 0 ] [nPoolIndex 3] nNumberOfBuffers 4480 nBufferSize 2216
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 3] mb pool 0x2475d8a80
+[ handle 0xd013380 0 0 ] [nPoolIndex 4] nNumberOfBuffers 4480 nBufferSize 8192
+CC:[ handle 0xd013380 ru 0 cc_idx 0 ] [nPoolIndex 4] mb pool 0x246884740
+@@@ NB cell 0 DL NR-ARFCN 0,DL phase comp flag 0 UL NR-ARFCN 0,UL phase comp flag 0
+init_xran_iq_content
+xRAN open PRACH config: Numerology 3 ConfIdx 81, preambleFmrt 6 startsymb 7, numSymbol 6, occassionsInPrachSlot 1
+PRACH: x 1 y[0] 0, y[1] 0 prach slot: 3.. 5 .... 7 .... 9 .... 11 .... 13 ..
+
+PRACH start symbol 7 lastsymbol 12
+xran_cp_init_sectiondb:Allocation Size for Section DB : 128 (1x8x16)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for Section DB : 128 (1x8x16)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_cp_init_sectiondb:Allocation Size for list : 1848 (28x66)
+xran_open: interval_us=125
+nSlotNum[0] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+ numDlSlots[1] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[1] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+ numDlSlots[2] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[2] : numDlSym[14] numGuardSym[0] numUlSym[0] XRAN_SLOT_TYPE_DL
+ numDlSlots[3] numUlSlots[0] numSpSlots[0] numSpDlSlots[0] numSpUlSlots[0]
+nSlotNum[3] : numDlSym[1] numGuardSym[2] numUlSym[11] XRAN_SLOT_TYPE_SP
+ numDlSlots[3] numUlSlots[0] numSpSlots[1] numSpDlSlots[1] numSpUlSlots[1]
+xran_fs_set_slot_type: nPhyInstanceId[0] nFrameDuplexType[1], nTddPeriod[4]
+DLRate[1.000000] ULRate[0.250000]
+SlotPattern:
+Slot: 0 1 2 3
+ 0 DL DL DL SP
+
+xran_timing_source_thread [CPU 7] [PID: 292331]
+MLogOpen: filename(mlog-o-du.bin) mlogSubframes (0), mlogCores(32), mlogSize(0) mlog_mask (-1)
+ mlogSubframes (256), mlogCores(32), mlogSize(7168)
+ localMLogTimerInit
+lls-CU: thread_run start time: 06/10/19 21:09:37.000000028 UTC [125]
+Start C-plane DL 25 us after TTI [trigger on sym 3]
+Start C-plane UL 55 us after TTI [trigger on sym 7]
+Start U-plane DL 50 us before OTA [offset in sym -6]
+Start U-plane UL 45 us OTA [offset in sym 6]
+C-plane to U-plane delay 25 us after TTI
+Start Sym timer 8928 ns
+interval_us 125
+ System clock (CLOCK_REALTIME) resolution 1000037471 [Hz]
+ Ticks per us 1000
+ MLog Storage: 0x7f6298487100 -> 0x7f629bc88d20 [ 58727456 bytes ]
+ localMLogFreqReg: 1000. Storing: 1000
+ Mlog Open successful
+
+----------------------------------------
+MLog Info: virt=0x00007f6298487100 size=58727456
+----------------------------------------
+Start XRAN traffic
++---------------------------------------+
+| Press 1 to start 5G NR XRAN traffic |
+| Press 2 reserved for future use |
+| Press 3 to quit |
++---------------------------------------+
+rx_counter 0 tx_counter 1376072
+rx_counter 0 tx_counter 1720112
+rx_counter 0 tx_counter 2064161
+rx_counter 0 tx_counter 2408212
+rx_counter 0 tx_counter 2752232
+
+type 3 to stop
+3
+rx_counter 0 tx_counter 3096264
+Stop XRAN traffic
+get_xran_iq_content
+Closing timing source thread...
+Closing l1 app... Ending all threads...
+MLogPrint: ext_filename((null).bin)
+ Opening MLog File: mlog-o-du-c0.bin
+ MLog file mlog-o-du-c0.bin closed
+ Mlog Print successful
+
+Failed at xran_mm_destroy, status -2
+Dump IQs...
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [0]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [1]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [2]
+RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [3]
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant0.txt: from addr (0x7f62ac9c0010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant0.bin: from addr (0x7f62ac9c0010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant1.txt: from addr (0x7f62ac80e010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant1.bin: from addr (0x7f62ac80e010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant2.txt: from addr (0x7f62ac65c010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant2.bin: from addr (0x7f62ac65c010) size (887040) bytes num (887040)
+Storing UL FFT OUT IQ Samples in human readable format to file ./logs/o-du-rx_log_ant3.txt: from addr (0x7f62ac4aa010) size (1774080) IQ num (443520)
+Storing UL FFT OUT IQ Samples in binary format to file ./logs/o-du-rx_log_ant3.bin: from addr (0x7f62ac4aa010) size (887040) bytes num (887040)