Compare commits

...

4 Commits

Author SHA1 Message Date
Bartosz Podrygajlo
7a8fc8f78a Work-in-progress memif conf
This is an attmept to allow configuring oainr_ru and nr-softmodem on the same system
using dpdk memif PMD.

In theory this should allow to run both executables on the same system without a
physical ethernet connection.

This was not tested yet beyond running both executables on my laptop.
2025-01-13 11:32:22 +01:00
Bartosz Podrygajlo
306ee75f58 Use nb_nr_L1_inst instead of nb_L1_inst to differentiate gNB & nrRU 2025-01-13 09:21:32 +01:00
Raymond Knopp
8f8b5e6767 gNB modifications for RU changes 2025-01-08 10:23:11 +01:00
Raymond Knopp
19c6f9bf4c initial implementation of O-RU for 7.2 emulator 2024-12-26 16:15:52 +01:00
16 changed files with 852 additions and 58 deletions

View File

@@ -596,6 +596,11 @@ include_directories("${OPENAIR_DIR}")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common/utils/T
${CMAKE_CURRENT_BINARY_DIR}/common/utils/T)
include_directories(${OPENAIR_DIR}/common/utils/barrier)
include_directories(${OPENAIR_DIR}/common/utils/actor)
include_directories(${OPENAIR_DIR}/common/utils/threadPool)
# set the T_LIB name to T if the target exists, otherwise leave empty
set(T_LIB $<TARGET_NAME_IF_EXISTS:T>)
@@ -1876,9 +1881,6 @@ target_link_libraries(oairu PRIVATE
SCHED_RU_LIB PHY_COMMON PHY_RU UTIL shlib_loader
-Wl,--end-group z dl)
target_link_libraries(oairu PRIVATE pthread m CONFIG_LIB rt ${T_LIB})
target_link_libraries(oairu PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
# force the generation of ASN.1 so that we don't need to wait during the build
target_link_libraries(lte-softmodem PRIVATE
asn1_lte_rrc asn1_s1ap asn1_m2ap asn1_m3ap asn1_x2ap)
@@ -1917,6 +1919,29 @@ target_link_libraries(lte-uesoftmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIE
target_link_libraries(lte-uesoftmodem PRIVATE
asn1_lte_rrc asn1_s1ap asn1_m2ap asn1_m3ap asn1_x2ap)
# nr RRU
add_executable(oainr_ru
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR_DIR}/openair1/PHY/INIT/nr_parms.c
${OPENAIR_DIR}/openair1/SCHED_NR/phy_frame_config_nr.c
${OPENAIR_DIR}/openair1/PHY/INIT/nr_parms.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_prach_procedures.c
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR_DIR}/executables/main_nr_ru.c
)
target_link_libraries(oainr_ru PRIVATE
-Wl,--start-group
UTIL SCHED_RU_LIB PHY_COMMON PHY_RU shlib_loader
-Wl,--end-group z dl)
target_link_libraries(oainr_ru PRIVATE pthread m CONFIG_LIB rt ${T_LIB} utils
barrier actor)
target_link_libraries(oainr_ru PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
# nr-softmodem
###################################################

View File

@@ -87,6 +87,8 @@ Options:
Makes the NR softmodem
--RU
Makes the OAI RRU
--nrRU
Makes the OAI nrRRU
--UE
Makes the UE specific parts (usim, nvram) from the given configuration file
--nrUE
@@ -242,6 +244,11 @@ function main() {
TARGET_LIST="$TARGET_LIST oairu"
echo_info "Will compile RRU"
shift;;
--nrRU)
nrRU=1
TARGET_LIST="$TARGET_LIST oainr_ru"
echo_info "Will compile nrRRU"
shift;;
--UE)
UE=1
TARGET_LIST="$TARGET_LIST lte-uesoftmodem"
@@ -484,7 +491,8 @@ function main() {
if [[ $TARGET_LIST != "" ]] && [[ -f $OPENAIR_DIR/CMakeLists.txt ]]; then
# add some default libraries that should always be built
# for eNB, gNB, UEs, simulators
if [[ $gNB == 1 || $eNB == 1 || $UE == 1 || $nrUE == 1 || $SIMUS_PHY == 1 || $RU == 1 ]]; then
if [[ $gNB == 1 || $eNB == 1 || $UE == 1 || $nrUE == 1 || $SIMUS_PHY == 1
|| $RU == 1 || $nrRU == 1 ]]; then
TARGET_LIST="$TARGET_LIST params_libconfig coding rfsimulator dfts params_yaml"
fi

219
executables/main_nr_ru.c Normal file
View File

@@ -0,0 +1,219 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file oairu.c
* \brief Top-level threads for radio-unit
* \author R. Knopp
* \date 2020
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include "assertions.h"
#include "PHY/types.h"
#include "PHY/defs_RU.h"
#include "common/oai_version.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
#include "common/ran_context.h"
#include "radio/COMMON/common_lib.h"
#include "radio/ETHERNET/if_defs.h"
#include "PHY/phy_vars.h"
#include "PHY/phy_extern.h"
#include "PHY/TOOLS/phy_scope_interface.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
//#include "PHY/INIT/phy_init.h"
#include "openair2/ENB_APP/enb_paramdef.h"
#include "system.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include <executables/softmodem-common.h>
#include <executables/thread-common.h>
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
int oai_exit = 0;
uint16_t sf_ahead = 4;
RAN_CONTEXT_t RC;
extern void kill_NR_RU_proc(int inst);
extern void set_function_spec_param(RU_t *ru);
extern void start_NR_RU(RU_t *ru);
extern void init_NR_RU(configmodule_interface_t *cfg, char *);
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
void nfapi_setmode(nfapi_mode_t nfapi_mode) { return; }
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) {
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
}
close_log_mem();
oai_exit = 1;
RU_t *ru = RC.ru[0];
if (ru->rfdevice.trx_end_func) {
ru->rfdevice.trx_end_func(&ru->rfdevice);
ru->rfdevice.trx_end_func = NULL;
}
if (ru->ifdevice.trx_end_func) {
ru->ifdevice.trx_end_func(&ru->ifdevice);
ru->ifdevice.trx_end_func = NULL;
}
pthread_mutex_destroy(ru->ru_mutex);
pthread_cond_destroy(ru->ru_cond);
if (assert) {
abort();
} else {
sleep(1); // allow lte-softmodem threads to exit first
exit(EXIT_SUCCESS);
}
}
static void get_options(configmodule_interface_t *cfg)
{
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options(cfg, SOFTMODEM_ENB_BIT);
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
// NRCConfig();
}
nfapi_mode_t nfapi_getmode(void) {
return(NFAPI_MODE_PNF);
}
void oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
AssertFatal(1==0,"This is bad ... please check why we get here\n");
}
void wait_eNBs(void){ return; }
void wait_gNBs(void){ return; }
struct timespec timespec_add(struct timespec,struct timespec) {struct timespec t={0}; return t;};
struct timespec timespec_sub(struct timespec,struct timespec) {struct timespec t={0}; return t;};
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation) {return;}
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) {return;};
int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols) {int i=0; return i;};
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map) {return;}
uint16_t nr_du[838];
uint64_t downlink_frequency[MAX_NUM_CCs][4];
configmodule_interface_t *uniqCfg = NULL;
THREAD_STRUCT thread_struct;
int main ( int argc, char **argv )
{
memset(&RC,0,sizeof(RC));
if ((uniqCfg = load_configmodule(argc, argv, 0)) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
logInit();
printf("Reading in command-line options\n");
get_options(uniqCfg);
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n");
exit(-1);
}
#if T_TRACER
T_Config_Init();
#endif
printf("configuring for RRU\n");
// strdup to put the sring in the core file for post mortem identification
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
/* Read configuration */
printf("About to Init RU threads\n");
lock_memory_to_ram();
RC.nb_RU=1;
RC.ru = malloc(sizeof(RC.ru));
init_NR_RU(config_get_if(),NULL);
RU_t *ru = RC.ru[0];
LOG_I(PHY, "Starting ru_thread , is_slave %d, send_dmrs %d\n", ru->is_slave, ru->generate_dmrs_sync);
start_NR_RU(ru);
LOG_I(PHY,"RU configured, unlocking threads\n");
config_sync_var=0;
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
while (oai_exit==0) sleep(1);
// stop threads
kill_NR_RU_proc(0);
end_configmodule(uniqCfg);
if (ru->rfdevice.trx_end_func) {
ru->rfdevice.trx_end_func(&ru->rfdevice);
ru->rfdevice.trx_end_func = NULL;
}
if (ru->ifdevice.trx_end_func) {
ru->ifdevice.trx_end_func(&ru->ifdevice);
ru->ifdevice.trx_end_func = NULL;
}
logClean();
printf("Bye.\n");
return 0;
}

View File

@@ -58,6 +58,8 @@ static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
static int DEFBFW[] = {0x00007fff};
static int DEFRUTPCORES[] = {-1,-1,-1,-1};
static int DEFBW[] = {273};
static int DEFCARRIER[] = {3430560};
#include "ENB_APP/enb_paramdef.h"
#include "GNB_APP/gnb_paramdef.h"
@@ -190,7 +192,7 @@ int connect_rau(RU_t *ru) {
break;
default:
AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function);
AssertFatal(1==0,"RU_function is unknown %d\n",ru->function);
break;
}
@@ -241,7 +243,7 @@ int connect_rau(RU_t *ru) {
// southbound IF5 fronthaul for 16-bit OAI format
void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
int offset = ru->nr_frame_parms->get_samples_slot_timestamp(slot,ru->nr_frame_parms,0);
void *buffs[ru->nb_tx];
for (int aid=0;aid<ru->nb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset];
@@ -263,7 +265,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
nfapi_nr_config_request_scf_t *cfg = &ru->config;
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
@@ -380,7 +382,7 @@ void fh_if4p5_south_in(RU_t *ru,
*slot = proc->tti_rx;
}
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, f );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, sl);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
@@ -456,7 +458,7 @@ void fh_if4p5_north_in(RU_t *ru,int *frame,int *slot) {
} while (symbol_mask != symbol_mask_full);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, *frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, *slot );
}
@@ -532,7 +534,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,slot_tx);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx );
}
@@ -575,7 +577,7 @@ void *emulatedRF_thread(void *param) {
int microsec = 500; // length of time to sleep, in miliseconds
struct timespec req = {0};
req.tv_sec = 0;
req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
req.tv_nsec = (proc->ru->numerology>0)? ((microsec * 1000L)/proc->ru->numerology):(microsec * 1000L)*2;
wait_sync("emulatedRF_thread");
while(!oai_exit) {
@@ -610,7 +612,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
old_ts = proc->timestamp_rx;
LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",samples_per_slot,*slot,rxp[0]);
if(emulate_rf) {
if(ru->emulate_rf) {
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
rxs = samples_per_slot;
@@ -663,7 +665,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx );
}
@@ -691,7 +693,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
*slot = proc->tti_rx;
}
if (!emulate_rf) {
if (!ru->emulate_rf) {
metadata mt = {.slot = *slot, .frame = *frame};
gNBscopeCopyWithMetadata(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0, &mt);
}
@@ -1057,7 +1059,7 @@ void ru_tx_func(void *param)
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm))
ru->feptx_ofdm(ru, frame_tx, slot_tx);
if(!emulate_rf) {
if(!ru->emulate_rf) {
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out))
ru->fh_south_out(ru, frame_tx, slot_tx, info->timestamp_tx);
@@ -1108,7 +1110,7 @@ void *ru_thread(void *param)
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
PHY_VARS_gNB *gNB = RC.gNB[0];
PHY_VARS_gNB *gNB = (RC.nb_nr_L1_inst > 0) ? RC.gNB[0] : NULL;
int ret;
int slot = fp->slots_per_frame-1;
int frame = 1023;
@@ -1123,15 +1125,16 @@ void *ru_thread(void *param)
// set default return value
sprintf(threadname,"ru_thread %u",ru->idx);
LOG_I(PHY,"Starting RU %d (%s,%s) on cpu %d\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing],sched_getcpu());
memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config));
nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
if (gNB) {
memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config));
nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
}
nr_phy_init_RU(ru);
fill_rf_config(ru, ru->rf_config_file);
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame, fp->ofdm_symbol_size);
if(!emulate_rf) {
if(!ru->emulate_rf) {
// Start IF device if any
if (ru->nr_start_if) {
LOG_I(PHY, "starting transport\n");
@@ -1193,7 +1196,7 @@ void *ru_thread(void *param)
pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread");
if(!emulate_rf) {
if(!ru->emulate_rf) {
// Start RF device if any
if (ru->start_rf) {
if (ru->start_rf(ru) != 0)
@@ -1426,7 +1429,7 @@ void init_RU_proc(RU_t *ru) {
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
pthread_cond_init( &proc->cond_emulateRF, NULL);
if(emulate_rf)
if(ru->emulate_rf)
threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
if (cpu_meas_enabled)
threadCreate(&ru->ru_stats_thread, ru_stats_thread, (void *)ru, "ru_stats", -1, OAI_PRIORITY_RT);
@@ -1648,6 +1651,7 @@ void set_function_spec_param(RU_t *ru)
reset_meas(&ru->tx_fhaul);
reset_meas(&ru->compression);
reset_meas(&ru->transport);
LOG_I(NR_PHY,"Setting IF4p5 (7.2 split)\n");
} else if (ru->function == gNodeB_3GPP) {
ru->do_prach = 0; // no prach processing in RU
ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs
@@ -1755,9 +1759,10 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
ru->num_gNB=1;
}
}
gNB_RC = RC.gNB[0];
gNB0 = ru->gNB_list[0];
if (RC.nb_nr_L1_inst > 0) {
gNB_RC = RC.gNB[0];
gNB0 = ru->gNB_list[0];
}
fp = ru->nr_frame_parms;
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
@@ -1778,6 +1783,9 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
}
}
}
else {
nr_ru_init_frame_parms(ru);
}
set_function_spec_param(ru);
init_RU_proc(ru);
if (ru->if_south != REMOTE_IF4p5) {
@@ -1805,9 +1813,8 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
LOG_D(HW,"[nr-softmodem.c] RU threads created\n");
}
void start_NR_RU()
void start_NR_RU(RU_t *ru)
{
RU_t *ru = RC.ru[0];
start_RU_proc(ru);
}
@@ -1917,7 +1924,7 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
if (!(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX))) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = gNodeB_3GPP;
LOG_D(PHY, "Setting function for RU %d to gNodeB_3GPP\n", j);
LOG_I(NR_PHY, "Setting function for RU %d to gNodeB_3GPP\n", j);
} else {
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
@@ -1931,22 +1938,22 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF5 (udp)\n", j);
LOG_I(NR_PHY, "Setting function for RU %d to NGFI_RRU_IF5 (udp)\n", j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF5 (raw)\n", j);
LOG_I(NR_PHY, "Setting function for RU %d to NGFI_RRU_IF5 (raw)\n", j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n", j);
LOG_I(NR_PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n", j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n", j);
LOG_I(NR_PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n", j);
}
}
@@ -1995,8 +2002,23 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
RC.ru[j]->sl_ahead = *(RUParamList.paramarray[j][RU_SL_AHEAD].iptr);
RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
for (int i = 0; i < RC.ru[j]->num_bands; i++)
for (int i = 0; i < RC.ru[j]->num_bands; i++) {
RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
RC.ru[j]->bw_tx[i] = RUParamList.paramarray[j][RU_TX_BW_LIST_IDX].iptr[i];
RC.ru[j]->bw_rx[i] = RUParamList.paramarray[j][RU_RX_BW_LIST_IDX].iptr[i];
RC.ru[j]->carrier_freq_tx[i] = RUParamList.paramarray[j][RU_TX_CARRIER_LIST_IDX].iptr[i];
RC.ru[j]->carrier_freq_rx[i] = RUParamList.paramarray[j][RU_RX_CARRIER_LIST_IDX].iptr[i];
}
RC.ru[j]->frame_type = *(RUParamList.paramarray[j][RU_FRAME_TYPE_IDX].iptr);
RC.ru[j]->prach_config_index = *(RUParamList.paramarray[j][RU_PRACH_CONFIGID_IDX].iptr);
RC.ru[j]->prach_msg1_freq = *(RUParamList.paramarray[j][RU_PRACH_MSG1FREQ_IDX].iptr);
RC.ru[j]->numerology = *(RUParamList.paramarray[j][RU_NUMEROLOGY_IDX].iptr);
RC.ru[j]->tdd_period = *(RUParamList.paramarray[j][RU_TDD_PERIOD_IDX].iptr);
RC.ru[j]->num_DL_slots = *(RUParamList.paramarray[j][RU_NUM_DL_SLOTS_IDX].iptr);
RC.ru[j]->num_UL_slots = *(RUParamList.paramarray[j][RU_NUM_UL_SLOTS_IDX].iptr);
RC.ru[j]->num_DL_symbols = *(RUParamList.paramarray[j][RU_NUM_DL_SYMBOLS_IDX].iptr);
RC.ru[j]->num_UL_symbols = *(RUParamList.paramarray[j][RU_NUM_UL_SYMBOLS_IDX].iptr);
RC.ru[j]->openair0_cfg.nr_flag = *(RUParamList.paramarray[j][RU_NR_FLAG].iptr);
RC.ru[j]->openair0_cfg.nr_band = RC.ru[j]->band[0];
RC.ru[j]->openair0_cfg.nr_scs_for_raster = *(RUParamList.paramarray[j][RU_NR_SCS_FOR_RASTER].iptr);

View File

@@ -489,7 +489,7 @@ int start_L1L2(module_id_t gnb_id)
init_NR_RU(config_get_if(), NULL);
start_NR_RU();
start_NR_RU(RC.ru[0]);
wait_RUs();
init_eNB_afterRU();
LOG_I(GNB_APP, "Sending sync to all threads\n");
@@ -688,7 +688,7 @@ int main( int argc, char **argv ) {
wait_f1_setup_response();
if (RC.nb_RU > 0)
start_NR_RU();
start_NR_RU(RC.ru[0]);
#ifdef ENABLE_AERIAL
gNB_MAC_INST *nrmac = RC.nrmac[0];
nvIPC_Init(nrmac->nvipc_params_s);

View File

@@ -47,7 +47,7 @@ extern void stop_gNB(int);
// In nr-ru.c
extern void init_NR_RU(configmodule_interface_t *cfg, char *);
extern void init_RU_proc(RU_t *ru);
extern void start_NR_RU(void);
extern void start_NR_RU(RU_t *ru);
extern void stop_RU(int nb_ru);
extern void kill_NR_RU_proc(int inst);
extern void set_function_spec_param(RU_t *ru);

View File

@@ -35,12 +35,15 @@ int nr_phy_init_RU(RU_t *ru)
LOG_D(PHY, "Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n", ru_if_types[ru->if_south], ru->nb_tx, ru->nb_rx);
nfapi_nr_config_request_scf_t *cfg = &ru->config;
ru->nb_log_antennas = 0;
for (int n = 0; n < ru->num_gNB; n++) {
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas)
ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
if (ru->num_gNB > 0) {
nfapi_nr_config_request_scf_t *cfg = &ru->config;
ru->nb_log_antennas = 0;
for (int n = 0; n < ru->num_gNB; n++) {
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas)
ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
}
}
else ru->nb_log_antennas = ru->nb_tx;
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration
// (at least the parts that are needed by the RU, numerology and PRACH)

View File

@@ -281,6 +281,74 @@ uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsig
return samp_count;
}
void nr_ru_init_frame_parms(RU_t *ru) {
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
fp->frame_type = ru->frame_type;
ru->config.cell_config.frame_duplex_type.value = ru->frame_type;
ru->config.cell_config.frame_duplex_type.tl.tag = 0x100D;
fp->N_RB_DL = ru->bw_tx[0];
ru->config.ssb_config.scs_common.value=ru->numerology;
ru->config.carrier_config.dl_grid_size[ru->config.ssb_config.scs_common.value].value = ru->bw_tx[0];
fp->N_RB_UL = ru->bw_rx[0];
ru->config.carrier_config.ul_grid_size[ru->config.ssb_config.scs_common.value].value = ru->bw_rx[0];
fp->numerology_index=ru->numerology;
fp->nr_band = ru->band[0];
LOG_I(NR_PHY,"Set RU frame type to %s, N_RB_DL %d, N_RB_UL %d, mu %d\n",ru->frame_type == TDD ? "TDD" : "FDD", ru->bw_tx[0],ru->bw_rx[0],ru->numerology);
set_scs_parameters(fp,fp->numerology_index,ru->bw_tx[0]);
fp->slots_per_frame = 10 * fp->slots_per_subframe;
fp->nb_antennas_rx = ru->nb_rx;
fp->nb_antennas_tx = ru->nb_tx;
fp->symbols_per_slot=14;
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size;
fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot;
fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 +
(fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
fp->get_samples_per_slot = &get_samples_per_slot;
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->get_slot_from_timestamp = &get_slot_from_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = (ru->carrier_freq_tx[0] < 6e6)? FR1 : FR2;
fp->dl_CarrierFreq = (double)ru->carrier_freq_tx[0] * 1000;
fp->ul_CarrierFreq = (double)ru->carrier_freq_rx[0] * 1000;
fp->Ncp = NORMAL;
// Split 7.2 parameters
ru->config.prach_config.num_prach_fd_occasions.value = 1;
ru->config.prach_config.prach_ConfigurationIndex.value = ru->prach_config_index;
ru->config.prach_config.prach_ConfigurationIndex.tl.tag = 0x1029;
ru->config.prach_config.num_prach_fd_occasions_list = malloc(sizeof(*ru->config.prach_config.num_prach_fd_occasions_list));
ru->config.prach_config.num_prach_fd_occasions_list[0].k1.value = ru->prach_msg1_freq;
if (ru->config.cell_config.frame_duplex_type.value == 1 /* TDD */) {
ru->config.tdd_table.tdd_period.value = ru->tdd_period;
ru->config.tdd_table.tdd_period.tl.tag = 0x1026;
int n=0,s=0;
ru->config.tdd_table.max_tdd_periodicity_list = malloc(sizeof(*ru->config.tdd_table.max_tdd_periodicity_list)*(ru->num_DL_slots+ru->num_UL_slots+1));
for (;n<ru->num_DL_slots;n++) {
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list = malloc(sizeof(*ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list)*14);
for (int s=0;s<14;s++)
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list[s].slot_config.value = 0;
}
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list = malloc(sizeof(*ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list)*14);
for (s=0;s<ru->num_DL_symbols;s++)
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list[s].slot_config.value = 0;
for (;s<14-ru->num_UL_symbols;s++)
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list[s].slot_config.value = 2;
for (;s<14;s++)
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list[s].slot_config.value = 1;
n++;
for (;n<ru->num_DL_slots+ru->num_UL_slots+1;n++){
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list = malloc(sizeof(*ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list)*14);
for (;s<14;s++)
ru->config.tdd_table.max_tdd_periodicity_list[n].max_num_of_symbol_per_slot_list[s].slot_config.value = 1;
}
}
}
void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp)
{

View File

@@ -27,6 +27,7 @@
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
void nr_ru_init_frame_parms(RU_t *ru);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,

View File

@@ -485,6 +485,30 @@ typedef struct RU_t_s {
int num_bands;
/// band list
int band[MAX_BANDS_PER_RRU];
/// tx carrier
uint64_t carrier_freq_tx[MAX_BANDS_PER_RRU];
/// rx carrier
uint64_t carrier_freq_rx[MAX_BANDS_PER_RRU];
/// tx BW in PRBs
int bw_tx[MAX_BANDS_PER_RRU];
/// rx BW in PRBs
int bw_rx[MAX_BANDS_PER_RRU];
/// 3GPP FRAME Type FDD/TDD
int frame_type;
/// 3GPP PRACH configuration index
int prach_config_index;
/// 3GPP MSG1 Start frequency
int prach_msg1_freq;
/// 3GPP TDD periodicity (0.5 ms, 1 0.625ms, 2 1ms, 3 1.25ms, 4 2ms,5 2.5ms, 6 5ms, 7 10ms, 8 3ms, 9 4ms
int tdd_period;
/// number of DL slots
int num_DL_slots;
/// number of UL slots
int num_UL_slots;
/// number of DL symbols
int num_DL_symbols;
/// number of UL symbols
int num_UL_symbols;
/// number of RX paths on device
int nb_rx;
/// number of TX paths on device

View File

@@ -113,6 +113,21 @@ typedef enum {
#define CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION "half_slot_parallelization"
#define CONFIG_STRING_RU_RU_THREAD_CORE "ru_thread_core"
#define CONFIG_STRING_RU_GPIO_CONTROL "gpio_controller"
#define CONFIG_STRING_RU_TX_BW_LIST "tx_bw"
#define CONFIG_STRING_RU_RX_BW_LIST "rx_bw"
#define CONFIG_STRING_RU_CARRIER_TX_LIST "carrier_tx"
#define CONFIG_STRING_RU_CARRIER_RX_LIST "carrier_rx"
#define CONFIG_STRING_RU_FRAME_TYPE "frame_type"
#define CONFIG_STRING_RU_PRACH_CONFIGID "prach_config_index"
#define CONFIG_STRING_RU_PRACH_MSG1FREQ "prach_msg1_start"
#define CONFIG_STRING_RU_NUMEROLOGY "mu"
#define CONFIG_STRING_RU_TDD_PERIOD "tdd_period"
#define CONFIG_STRING_RU_NUM_DL_SLOTS "num_dl_slots"
#define CONFIG_STRING_RU_NUM_UL_SLOTS "num_ul_slots"
#define CONFIG_STRING_RU_NUM_DL_SYMBOLS "num_dl_symbols"
#define CONFIG_STRING_RU_NUM_UL_SYMBOLS "num_ul_symbols"
#define HLP_RU_SF_AHEAD "LTE TX processing advance"
#define HLP_RU_SL_AHEAD "NR TX processing advance"
@@ -126,6 +141,20 @@ typedef enum {
#define HLP_RU_HALF_SLOT_PARALLELIZATION "run half slots in parallel in RU FEP"
#define HLP_RU_RU_THREAD_CORE "id of core to pin ru_thread, -1 is default"
#define HLP_RU_GPIO_CONTROL "set the GPIO control type for the RU"
#define HLP_RU_TX_BW "set the TX bandwidth list per component carrier"
#define HLP_RU_RX_BW "set the RX bandwidth list per component carrier"
#define HLP_RU_CARRIER_TX "set the TX carrier frequencies per component carrier"
#define HLP_RU_CARRIER_RX "set the RX carrier frequencies per component carrier"
#define HLP_RU_FRAMETYPE "set the Frame type TDD/FDD of all component carriers"
#define HLP_RU_PRACH_CONFIGID "set the PRACH configuration id of all component carriers"
#define HLP_RU_PRACH_MSG1FREQ "set the PRACH MSG1 frequency of all component carriers"
#define HLP_RU_NUMEROLOGY "set the numerology of the RU"
#define HLP_RU_TDD_PERIOD "set the 3GPP TDD periodificty 0-9"
#define HLP_RU_NUM_DL_SLOTS "set the number of DL Slots in TDD"
#define HLP_RU_NUM_UL_SLOTS "set the number of UL Slots in TDD"
#define HLP_RU_NUM_DL_SYMBOLS "set the number of DL symbols in the mixed slot"
#define HLP_RU_NUM_UL_SYMBOLS "set the number of UL symbols in the mixed slot"
#define RU_LOCAL_IF_NAME_IDX 0
#define RU_LOCAL_ADDRESS_IDX 1
@@ -170,6 +199,19 @@ typedef enum {
#define RU_HALF_SLOT_PARALLELIZATION 40
#define RU_RU_THREAD_CORE 41
#define RU_GPIO_CONTROL 42
#define RU_TX_BW_LIST_IDX 43
#define RU_RX_BW_LIST_IDX 44
#define RU_TX_CARRIER_LIST_IDX 45
#define RU_RX_CARRIER_LIST_IDX 46
#define RU_FRAME_TYPE_IDX 47
#define RU_PRACH_CONFIGID_IDX 48
#define RU_PRACH_MSG1FREQ_IDX 49
#define RU_NUMEROLOGY_IDX 50
#define RU_TDD_PERIOD_IDX 51
#define RU_NUM_DL_SLOTS_IDX 52
#define RU_NUM_UL_SLOTS_IDX 53
#define RU_NUM_DL_SYMBOLS_IDX 54
#define RU_NUM_UL_SYMBOLS_IDX 55
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* RU configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -219,6 +261,19 @@ typedef enum {
{CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION, HLP_RU_HALF_SLOT_PARALLELIZATION, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_RU_THREAD_CORE, HLP_RU_RU_THREAD_CORE, 0, .uptr=NULL, .defintval=-1, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_GPIO_CONTROL, HLP_RU_GPIO_CONTROL, 0, .strptr=NULL, .defstrval="generic", TYPE_STRING, 0}, \
{CONFIG_STRING_RU_TX_BW_LIST, HLP_RU_TX_BW, 0, .iptr=NULL, .defintarrayval=DEFBW, TYPE_INTARRAY, 0}, \
{CONFIG_STRING_RU_RX_BW_LIST, HLP_RU_RX_BW, 0, .iptr=NULL, .defintarrayval=DEFBW, TYPE_INTARRAY, 0}, \
{CONFIG_STRING_RU_CARRIER_TX_LIST, HLP_RU_CARRIER_TX, 0, .iptr=NULL, .defintarrayval=DEFCARRIER, TYPE_INTARRAY, 0}, \
{CONFIG_STRING_RU_CARRIER_RX_LIST, HLP_RU_CARRIER_RX, 0, .iptr=NULL, .defintarrayval=DEFCARRIER, TYPE_INTARRAY, 0}, \
{CONFIG_STRING_RU_FRAME_TYPE, HLP_RU_FRAMETYPE, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_PRACH_CONFIGID, HLP_RU_PRACH_CONFIGID, 0, .uptr=NULL, .defintval=152, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_PRACH_MSG1FREQ, HLP_RU_PRACH_MSG1FREQ, 0, .uptr=NULL, .defintval=0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NUMEROLOGY, HLP_RU_NUMEROLOGY, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_TDD_PERIOD, HLP_RU_TDD_PERIOD, 0, .uptr=NULL, .defintval=5, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NUM_DL_SLOTS, HLP_RU_NUM_DL_SLOTS, 0, .uptr=NULL, .defintval=3, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NUM_UL_SLOTS, HLP_RU_NUM_UL_SLOTS, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NUM_DL_SYMBOLS, HLP_RU_NUM_DL_SYMBOLS, 0, .uptr=NULL, .defintval=7, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NUM_UL_SYMBOLS, HLP_RU_NUM_UL_SYMBOLS, 0, .uptr=NULL, .defintval=3, TYPE_UINT, 0}, \
}
// clang-format on

View File

@@ -90,7 +90,8 @@ static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
static int DEFBFW[] = {0x00007fff};
static int DEFRUTPCORES[] = {-1,-1,-1,-1};
static int DEFBW[] = {273};
static int DEFCARRIER[] = {3430560};
/**
* @brief Helper define to allocate and initialize SetupRelease structures
*/

View File

@@ -180,7 +180,8 @@ void print_fh_init(const struct xran_fh_init *fh_init)
fh_init->filePrefix,
fh_init->mtu,
fh_init->p_o_du_addr);
print_ether_addr(" p_o_ru_addr", fh_init->xran_ports * fh_init->io_cfg.num_vfs, (struct rte_ether_addr *)fh_init->p_o_ru_addr);
if (fh_init->p_o_ru_addr) print_ether_addr(" p_o_ru_addr", fh_init->xran_ports * fh_init->io_cfg.num_vfs, (struct rte_ether_addr *)fh_init->p_o_ru_addr);
else if (fh_init->p_o_du_addr) print_ether_addr(" p_o_du_addr", fh_init->xran_ports * fh_init->io_cfg.num_vfs, (struct rte_ether_addr *)fh_init->p_o_du_addr);
printf("\
totalBfWeights %d\n",
fh_init->totalBfWeights);
@@ -457,14 +458,14 @@ static uint64_t get_u64_mask(const paramdef_t *pd)
return mask;
}
static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, int nump, const int num_rus)
static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, int nump, const int num_rus,const int is_du)
{
DevAssert(fhip != NULL);
int num_dev = gpd(fhip, nump, ORAN_CONFIG_DPDK_DEVICES)->numelt;
AssertFatal(num_dev > 0, "need to provide DPDK devices for O-RAN 7.2 Fronthaul\n");
AssertFatal(num_dev < 17, "too many DPDK devices for O-RAN 7.2 Fronthaul\n");
io_cfg->id = 0; // 0 -> xran as O-DU; 1 -> xran as O-RU
io_cfg->id = 1-is_du; // 0 -> xran as O-DU; 1 -> xran as O-RU
io_cfg->num_vfs = num_dev; // number of VFs for C-plane and U-plane (should be even); max = XRAN_VF_MAX
io_cfg->num_rxq = 1; // number of RX queues per VF
for (int i = 0; i < num_dev; ++i) {
@@ -601,8 +602,15 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
config_getlist(config_get_if(), &FH_ConfigList, FHconfigs, nfh, aprefix);
int num_rus = FH_ConfigList.numelt; // based on the number of fh_config sections -> number of RUs
int is_du=0;
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus))
int num_ru_addr = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->numelt;
int num_du_addr = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->numelt;
if (num_ru_addr > 0 && num_du_addr == 0) is_du = 1;
else if (num_du_addr > 0 && num_ru_addr == 0) is_du =0;
else AssertFatal(1==0,"Illegal node configuration, num_du_addr %d, num_ru_addr %d\n",num_du_addr,num_ru_addr);
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus,is_du))
return false;
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, xran_cat))
return false;
@@ -620,16 +628,31 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
fh_init->p_o_du_addr = NULL; // DPDK retreives DU MAC address within the xran library with rte_eth_macaddr_get() function
int num_ru_addr = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->numelt;
fh_init->p_o_ru_addr = calloc(num_ru_addr, sizeof(struct rte_ether_addr));
char **ru_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->strlistptr;
AssertFatal(fh_init->p_o_ru_addr != NULL, "out of memory\n");
for (int i = 0; i < num_ru_addr; ++i) {
struct rte_ether_addr *ea = (struct rte_ether_addr *)fh_init->p_o_ru_addr;
if (get_ether_addr(ru_addrs[i], &ea[i]) == NULL) {
printf("could not read ethernet address '%s' for RU!\n", ru_addrs[i]);
return false;
}
char **ru_addrs,**du_addrs;
if (is_du > 0) {
fh_init->p_o_ru_addr = calloc(num_ru_addr, sizeof(struct rte_ether_addr));
ru_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->strlistptr;
AssertFatal(fh_init->p_o_ru_addr != NULL, "out of memory\n");
for (int i = 0; i < num_ru_addr; ++i) {
struct rte_ether_addr *ea = (struct rte_ether_addr *)fh_init->p_o_ru_addr;
if (get_ether_addr(ru_addrs[i], &ea[i]) == NULL) {
printf("could not read ethernet address '%s' for RU!\n", ru_addrs[i]);
return false;
}
}
}
else {
fh_init->p_o_du_addr = calloc(num_du_addr, sizeof(struct rte_ether_addr));
du_addrs = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->strlistptr;
AssertFatal(fh_init->p_o_du_addr != NULL, "out of memory\n");
for (int i = 0; i < num_du_addr; ++i) {
struct rte_ether_addr *ea = (struct rte_ether_addr *)fh_init->p_o_du_addr;
if (get_ether_addr(du_addrs[i], &ea[i]) == NULL) {
printf("could not read ethernet address '%s' for DU!\n", du_addrs[i]);
return false;
}
}
}
fh_init->totalBfWeights = 0; // only used if id = O_RU (for emulation); C-plane extension types; section 5.4.6 of CUS spec

View File

@@ -31,6 +31,7 @@
#define ORAN_CONFIG_SYSTEM_CORE "system_core"
#define ORAN_CONFIG_IO_CORE "io_core"
#define ORAN_CONFIG_WORKER_CORES "worker_cores"
#define ORAN_CONFIG_DU_ADDR "du_addr"
#define ORAN_CONFIG_RU_ADDR "ru_addr"
#define ORAN_CONFIG_MTU "mtu"
#define ORAN_CONFIG_FILE_PREFIX "file_prefix"
@@ -47,7 +48,8 @@
{ORAN_CONFIG_SYSTEM_CORE, "DPDK control threads core\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{ORAN_CONFIG_IO_CORE, "DPDK Core used for IO\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintval=4, TYPE_INT, 0}, \
{ORAN_CONFIG_WORKER_CORES, "CPU Cores to use for workers\n", PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=NULL,TYPE_UINTARRAY, 0}, \
{ORAN_CONFIG_RU_ADDR, "Ether addr of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \
{ORAN_CONFIG_DU_ADDR, "Ether addr of DU\n", 0, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \
{ORAN_CONFIG_RU_ADDR, "Ether addr of RU\n", 0, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \
{ORAN_CONFIG_MTU, "MTU of Eth interface\n", 0, .uptr=NULL, .defuintval=1500, TYPE_UINT, 0}, \
{ORAN_CONFIG_FILE_PREFIX, "DPDK file-prefix\n", 0, .strptr=NULL, .defstrval="wls_0", TYPE_STRING, 0}, \
{ORAN_CONFIG_NETHPERPORT, "number of links per port\n", 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0}, \

View File

@@ -0,0 +1,284 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); });
nr_cellid = 1;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pdsch_AntennaPorts_N1 = 2;
maxMIMO_layers = 2;
pusch_AntennaPorts = 4;
do_CSIRS = 1;
do_SRS = 0;
sib1_tda = 15;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 11;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# n_TimingAdvanceOffset = 0;
# downlinkConfigCommon
#frequencyInfoDL
# center frequency = 3450.72 MHz
# selected SSB frequency = 3450.72 MHz
absoluteFrequencySSB = 630048;
dl_frequencyBand = 78;
# frequency point A = 3401.58 MHz
dl_absoluteFrequencyPointA = 626772;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 273;
#initialDownlinkBWP
#genericParameters
initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 273;
pMax = 23;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 1099;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 159;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 22;
zeroCorrelationZoneConfig = 15;
preambleReceivedTargetPower = -104;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 7;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 2;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
msg3_DeltaPreamble = 2;
p0_NominalWithGrant = -96;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 0;
p0_nominal = -96;
ssb_PositionsInBurst_Bitmap = 0x1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 5;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 0;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "172.21.6.5"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.51";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.51";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
# dl_bler_target_upper = .35;
# dl_bler_target_lower = .15;
ul_bler_target_upper = .35;
ul_bler_target_lower = .15;
pusch_FailureThres = 100;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 130
pucch0_dtx_threshold = 80;
pusch_dtx_threshold = 10;
tx_amp_backoff_dB = 20; # needs to match O-RU configuration
L1_rx_thread_core = -1;
L1_tx_thread_core = -1;
phase_compensation = 1; # needs to match O-RU configuration
}
);
RUs = (
{
local_rf = "no";
nb_tx = 4;
nb_rx = 4;
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
sf_extension = 0;
eNB_instances = [0];
ru_thread_core = -1;
sl_ahead = 5;
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "info";
f1ap_log_level = "info";
};
fhi_72 = {
dpdk_devices = ("vdev=net_memif,bsize=1514,role=server,0000:00:00.1,mac=00:00:00:00:00:01,socket=/tmp/memif.sock");
system_core = 0;
io_core = 1;
worker_cores = (2);
ru_addr = ("00:00:00:00:00:01");
file_prefix = "gnb";
dpdk_mem_size = 0;
mtu = 1500;
fh_config = ({
T1a_cp_dl = (285, 429);
T1a_cp_ul = (285, 429);
T1a_up = (96, 196);
Ta4 = (110, 180);
ru_config = {
iq_width = 8;
iq_width_prach = 8;
};
prach_config = {
kbar = 0;
};
});
};

View File

@@ -0,0 +1,59 @@
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
RUs = (
{
local_rf = "no";
nb_tx = 4;
nb_rx = 4;
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
sf_extension = 0;
eNB_instances = [0];
ru_thread_core = -1;
sl_ahead = 5;
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "info";
f1ap_log_level = "info";
};
fhi_72 = {
dpdk_devices = ("vdev=net_memif,bsize=1514,role=client,0000:00:00.1,mac=00:00:00:00:00:01,socket=/tmp/memif.sock"); # one VF can be used as well
system_core = 3;
io_core = 4;
worker_cores = (5);
du_addr = ("00:00:00:00:00:02");
file_prefix = "ru";
dpdk_mem_size = 0;
mtu = 1500;
fh_config = ({
T1a_cp_dl = (285, 429);
T1a_cp_ul = (285, 429);
T1a_up = (96, 196);
Ta4 = (110, 180);
ru_config = {
iq_width = 8;
iq_width_prach = 8;
};
prach_config = {
kbar = 0;
};
});
};