Compare commits

...

1 Commits

Author SHA1 Message Date
Karim Boutiba
4a435fe341 O-RAN FR2 patch E release 2025-02-12 10:11:26 +01:00
20 changed files with 717 additions and 565 deletions

View File

@@ -93,10 +93,10 @@ static void tx_func(processingData_L1tx_t *info)
int slot_rx = info->slot_rx;
int64_t absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
int64_t absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
if (absslot_rx < 0) {
/*if (absslot_rx < 0) {
LOG_W(NR_PHY, "Slot ahead %d is larger than absslot_tx %ld. Cannot start TX yet.\n", info->gNB->RU_list[0]->sl_ahead, absslot_tx);
return;
}
}*/
LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx);
PHY_VARS_gNB *gNB = info->gNB;
module_id_t module_id = gNB->Mod_id;

View File

@@ -76,7 +76,11 @@ int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
int prach_id = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE);
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
//AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
if ((prach_id < 0))
{
LOG_E(PHY,"ILLEGAL PRACH (removed assert)\n");
return;}
gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id];
prach->frame = SFN;
prach->slot = Slot;
@@ -128,10 +132,13 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type)
void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
int prach_id = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE);
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
/*AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
"illegal or no prach_id found!!! prach_id %d\n",
prach_id);
prach_id);*/
if ((prach_id < 0))
{
printf("ILLEGAL PRACH\n");
return;}
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame = SFN;
ru->prach_list[prach_id].slot = Slot;

View File

@@ -1298,8 +1298,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
decoderState = 1;
corr_dB = dB_fixed64(corr);
LOG_D(PHY, "metric %d dB\n", corr_dB);
} else
LOG_E(PHY, "PUCCH not processed: nb_bit %d decoderState %d\n", nb_bit, decoderState);
} /*else
LOG_E(PHY, "PUCCH not processed: nb_bit %d decoderState %d slot %d\n", nb_bit, decoderState, slot);*/
LOG_D(PHY, "UCI decoderState %d, payload[0] %llu\n", decoderState, (unsigned long long)decodedPayload[0]);

View File

@@ -65,7 +65,7 @@ int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int s
if (idx != -1)
break;
}
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index);
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d in slot %d\n", fapi_beam_index,slot);
for (int j = 0; j < symbols_per_slot; j++) {
if (((bitmap_symbols >> j) & 0x01))
common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index;

View File

@@ -438,6 +438,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[n_ssb]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]);
LOG_D(NR_MAC,"beam_allocation_procedure [PRACH] slot %d.%d SSB %d beam %d\n", frameP, slotP, cc->ssb_index[n_ssb], beam_index);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1);
}
else {
@@ -447,6 +449,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[j]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]);
LOG_D(NR_MAC,"beam_allocation_procedure [PRACH multi ssb per RO] slot %d.%d SSB %d beam %d\n", frameP, slotP, cc->ssb_index[j], beam_index);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j);
}
}

View File

@@ -2810,7 +2810,7 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId);
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam (beam %d)\n", UE->UE_beam_index);
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
UE_info->sched_csirs |= (1 << dl_bwp->bwp_id);
@@ -3260,7 +3260,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE)
if (UE->UE_beam_index == new_bf_index)
return; // no beam change needed
LOG_I(NR_MAC, "[UE %x] Switching to beam with ID %d (SSB number %d)\n", UE->rnti, new_bf_index, rsrp_report->resource_id[0]);
LOG_E(NR_MAC, "[UE %x] Switching to beam with ID %d (SSB number %d)\n", UE->rnti, new_bf_index, rsrp_report->resource_id[0]);
UE->UE_beam_index = new_bf_index;
}

View File

@@ -476,6 +476,7 @@ static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu,
slot,
UE->UE_beam_index,
nr_slots_per_frame[current_BWP->scs]);
LOG_D(NR_MAC,"beam_allocation_procedure [SRS] slot %d.%d beam %d\n", frame, slot, UE->UE_beam_index);
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint64_t mask = SL_to_bitmap(srs_pdu->time_start_position, srs_pdu->num_symbols);

View File

@@ -267,6 +267,8 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
// going through the list of PUCCH resources to find the one indexed by resource_id
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n_slots_frame);
LOG_D(NR_MAC,"beam_allocation_procedure [CSI] slot %d.%d UE %d beam %d\n", sched_frame, sched_slot, UE->rnti, UE->UE_beam_index);
AssertFatal(beam.idx >= 0, "Cannot allocate CSI measurements on PUCCH in any available beam\n");
const int index = ul_buffer_index(sched_frame, sched_slot, ul_bwp->scs, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
@@ -467,7 +469,7 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac,
int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits);
rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]);
LOG_D(MAC,"SSB/CSI-RS index = %d\n", rsrp_report->resource_id[i]);
LOG_D(MAC,"SSB/CSI-RS i = %d index = %d\n", i, rsrp_report->resource_id[i]);
*cumul_bits += bitlen;
}
@@ -1078,6 +1080,8 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
// checking if in ul_slot the resources potentially to be assigned to this PUCCH are available
set_pucch_allocation(ul_bwp, r_pucch, bwp_size, curr_pucch);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, pucch_frame, pucch_slot, ue_beam, n_slots_frame);
LOG_D(NR_MAC,"beam_allocation_procedure [ACKNACK] slot %d.%d UE %d beam %d\n", pucch_frame, pucch_slot, UE->rnti, ue_beam);
if (beam.idx < 0) {
LOG_D(NR_MAC,
"DL %4d.%2d, UL_ACK %4d.%2d beam resources for this occasion are already occupied, move to the following occasion\n",
@@ -1187,6 +1191,8 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
}
else {
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, SFN, slot, UE->UE_beam_index, n_slots_frame);
LOG_D(NR_MAC,"beam_allocation_procedure [SR] slot %d.%d UE %d beam %d\n", SFN, slot, UE->rnti, UE->UE_beam_index);
AssertFatal(beam.idx >= 0, "Cannot allocate SR in any available beam\n");
const int index = ul_buffer_index(SFN, slot, ul_bwp->scs, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];

View File

@@ -1821,6 +1821,8 @@ static void pf_ul(module_id_t module_id,
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->frame = sched_frame;
sched_pusch->slot = sched_slot;
const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
/* Calculate throughput */
@@ -1836,6 +1838,8 @@ static void pf_ul(module_id_t module_id,
int n_dl = nr_slots_per_frame[UE->current_DL_BWP.scs];
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl);
LOG_D(NR_MAC,"beam_allocation_procedure [DCI UL] slot %d.%d UE %d beam %d\n", frame, slot, UE->rnti, UE->UE_beam_index);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot);
continue;
@@ -1843,6 +1847,8 @@ static void pf_ul(module_id_t module_id,
int n = nr_slots_per_frame[current_BWP->scs];
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n);
LOG_D(NR_MAC,"beam_allocation_procedure [PUSCH] slot %d.%d UE %d beam %d\n", sched_pusch->frame, sched_pusch->slot, UE->rnti, UE->UE_beam_index);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
@@ -2047,6 +2053,9 @@ static void pf_ul(module_id_t module_id,
sched_pusch->slot,
iterator->UE->UE_beam_index,
n);
LOG_D(NR_MAC,"beam_allocation_procedure [PUSCH2] slot %d.%d UE %d beam %d\n", sched_pusch->frame, sched_pusch->slot, iterator->UE->rnti, iterator->UE->UE_beam_index);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
iterator++;
@@ -2061,6 +2070,8 @@ static void pf_ul(module_id_t module_id,
int n_dl = nr_slots_per_frame[dl_BWP->scs];
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl);
LOG_D(NR_MAC,"beam_allocation_procedure [DCI UL2] slot %d.%d UE %d beam %d\n", frame, slot, iterator->UE->rnti, iterator->UE->UE_beam_index);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, iterator->UE->UE_beam_index, n, beam.new_beam);

View File

@@ -169,12 +169,13 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
output += snprintf(output,
end - output,
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS (%d) %d\n",
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS (%d) %d BEAM ID %d\n",
stats->dl.errors,
stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler,
UE->current_DL_BWP.mcsTableIdx,
sched_ctrl->dl_bler_stats.mcs);
sched_ctrl->dl_bler_stats.mcs,
UE->UE_beam_index);
if (reset_rsrp) {
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0;

View File

@@ -1,14 +1,13 @@
# we need at least gcc-11 to build xran, so let's enforce it here
# (because xran might not check it, and we have control here)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0
OR CMAKE_C_COMPILER_VERSION VERSION_LESS 11.0)
message(FATAL_ERROR "you need to have at least gcc/g++-11 to use 7.2 FHI through xran")
endif()
# use env var PKG_CONFIG_PATH to override paths to libdpdk.pc
pkg_check_modules(dpdk REQUIRED libdpdk)
pkg_check_modules(numa REQUIRED numa)
find_package(xran 5.1.0 EXACT REQUIRED) # E release -> 5
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
# alignment 1 of 'struct XYZ' is less than 2
add_compile_options(-Wno-packed-not-aligned)
add_library(oran_fhlib_5g MODULE
oran_isolate.c
oaioran.c
@@ -16,19 +15,6 @@ add_library(oran_fhlib_5g MODULE
oran-init.c
)
find_package(xran REQUIRED)
if(xran_VERSION VERSION_EQUAL 5.1.4)
target_compile_definitions(oran_fhlib_5g PRIVATE E_RELEASE)
elseif(xran_VERSION VERSION_EQUAL 6.1.1)
target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE)
else()
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.4 (E release) or 6.1.1 (F release)")
endif()
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
# alignment 1 of 'struct XYZ' is less than 2
add_compile_options(-Wno-packed-not-aligned)
set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native")
target_link_libraries(oran_fhlib_5g PRIVATE xran::xran)
target_link_libraries(oran_fhlib_5g PRIVATE ${dpdk_LINK_LIBRARIES})
@@ -43,6 +29,3 @@ set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_
add_custom_command(TARGET oran_fhlib_5g POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink liboran_fhlib_5g.so liboai_transpro.so
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
message(STATUS "Temporary added -DOAI_FHI72")
target_compile_definitions(nr-softmodem PUBLIC OAI_FHI72)

View File

@@ -34,13 +34,15 @@
#include "xran_common.h"
#include "oaioran.h"
#include <rte_ethdev.h>
#include "time_meas.h"
#include "oran-config.h" // for g_kbar
#define USE_POLLING 1
// Declare variable useful for the send buffer function
volatile uint8_t first_call_set = 0;
volatile uint8_t first_rx_set = 0;
volatile uint8_t first_rx_set_beam = 0;
volatile int first_read_set = 0;
// Variable declaration useful for fill IQ samples from file
@@ -89,38 +91,12 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
uint32_t rx_tti = callback_tag->slotiId;
tti = xran_get_slot_idx_from_tti(rx_tti, &frame, &subframe, &slot, &second);
rx_sym = callback_tag->symbol & 0xFF;
rx_sym = callback_tag->symbol;
uint32_t ru_id = callback_tag->oXuId;
LOG_D(NR_PHY,
"rx_callback frame %d, subframe %d, slot %d, second %lld, rx_sym %d ru_id %d\n",
frame,
subframe,
slot,
(unsigned long long)second,
rx_sym,
ru_id);
if (rx_sym == 7) { // in F release this value is defined as XRAN_FULL_CB_SYM (full slot (offset + 7))
#ifdef F_RELEASE
int32_t nCellIdx = callback_tag->cellId;
int32_t ntti = (rx_tti + XRAN_N_FE_BUF_LEN - 1) % XRAN_N_FE_BUF_LEN;
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
struct xran_prb_map *pRbMap = (struct xran_prb_map *)xran_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[ntti][nCellIdx][ant_id].sBufferList.pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", nCellIdx, ntti, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) {
struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm];
pRbElm->nSecDesc[sym_id] = 0; // number of section descriptors per symbol; M-plane info <supported-section-types>
}
}
}
#endif
if (rx_sym == 7) {
if (first_call_set) {
if (!first_rx_set) {
LOG_I(NR_PHY, "first_rx is set (num_ports %d), first_read_set %d\n", num_ports, first_read_set);
LOG_I(NR_PHY, "first_rx is set (num_ports %d)\n", num_ports);
}
first_rx_set = 1;
if (first_read_set == 1) {
@@ -194,7 +170,9 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
{
/* calculate tti and subframe_id from frame, slot num */
int sym_idx = 0;
//time_stats_t tmp_time;
//reset_meas(&tmp_time);
//start_meas(&tmp_time);
struct xran_device_ctx *xran_ctx = xran_dev_get_ctx();
struct xran_prach_cp_config *pPrachCPConfig = &(xran_ctx->PrachCPConfig);
struct xran_ru_config *ru_conf = &(xran_ctx->fh_cfg.ru_conf);
@@ -206,6 +184,7 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
uint32_t is_prach_slot = xran_is_prach_slot(0, subframe, (slot % slots_per_subframe));
int nb_rx_per_ru = ru->nb_rx / xran_ctx->fh_init.xran_ports;
/* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */
if (is_prach_slot) {
for (sym_idx = 0; sym_idx < pPrachCPConfig->numSymbol; sym_idx++) {
@@ -214,6 +193,7 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
int idx = 0;
xran_ctx = xran_dev_get_ctx_by_id(aa / nb_rx_per_ru);
dst = ru->prach_buf[aa]; // + (sym_idx*576));
src = (int16_t *)((uint8_t *)xran_ctx->sFHPrachRxBbuIoBufCtrlDecomp[tti % XRAN_N_FE_BUF_LEN][0][aa % nb_rx_per_ru]
.sBufferList.pBuffers[sym_idx]
.pData);
@@ -230,6 +210,7 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
}
}
} else if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_BLKFLOAT) {
struct xranlib_decompress_request bfp_decom_req;
struct xranlib_decompress_response bfp_decom_rsp;
@@ -248,21 +229,171 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
bfp_decom_rsp.data_out = (int16_t *)local_dst;
bfp_decom_rsp.len = 0;
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
// note: this is hardwired for 139 point PRACH sequence, kbar=2
if (sym_idx == 0) //
for (idx = 0; idx < (139 * 2); idx++)
dst[idx] = local_dst[idx + g_kbar];
dst[idx] = (local_dst[idx + g_kbar]) /*>> 3*/;
else
for (idx = 0; idx < (139 * 2); idx++)
dst[idx] += (local_dst[idx + g_kbar]);
dst[idx] += ((local_dst[idx + g_kbar]) /*>> 3*/);
/*if (dst != NULL )
{
int energy_level = dB_fixed(signal_energy((int32_t*)local_dst,139));
if (energy_level>25)
{
printf("PRACH tti %d slot %d symb %d energy level %d\n", tti, slot, sym_idx, energy_level);
}
}*/
} // COMPMETHOD_BLKFLOAT
} // aa
} // symb_indx
} // is_prach_slot
//stop_meas(&tmp_time);
//print_meas(&tmp_time, "PRACH_extraction", NULL, NULL);
return (0);
}
int check_buffer(int cc_id, int ant_id, int sym_idx, int frame, int slot )
{
struct xran_device_ctx *xran_ctx = xran_dev_get_ctx();
void *ptr = NULL;
int nb_rx_per_ru = 2;
xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_rx_per_ru);
const struct xran_fh_config *fh_config = &xran_ctx->fh_cfg;
int nPRBs = xran_ctx->fh_cfg.nULRBs;
const struct xran_fh_init *fh_init = &xran_ctx->fh_init;
// skip processing this slot if the last symbol in the slot is TX
// (no RX in this slot)
// This loop would better be more inner to avoid confusion and maybe also errors.
int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology;
int slots_per_subframe = 1 << xran_ctx->fh_cfg.frame_conf.nNumerology;
int tti = slots_per_frame * (frame) + (slot);
uint8_t *pData;
uint8_t *pPrbMapData = xran_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_rx_per_ru]
.sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
u_int8_t section_id_tmp = pPrbMap->nPrbElm < 10 ? sym_idx - 10: sym_idx; // Temporary hack for LiteON FR2 : receive UP section ID = 13
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[section_id_tmp];
struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[/*sym_idx*/0][0];
uint32_t one_rb_size =
(((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1));
if (fh_init->mtu < pRbElm->nRBSize * one_rb_size)
pData = xran_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_rx_per_ru]
.sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT]
.pData;
else
pData = p_sec_desc->pData;
ptr = pData;
if (ptr == NULL)
return -1;
struct xran_prb_map *pRbMap = pPrbMap;
uint32_t idxElm = 0;
uint8_t *src = (uint8_t *)ptr;
int16_t payload_len = 0;
LOG_D(PHY, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
//for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
LOG_D(PHY,
"prbMap[%d] : PRBstart %d nPRBs %d\n",
section_id_tmp,
pRbMap->prbMap[section_id_tmp].nRBStart,
pRbMap->prbMap[section_id_tmp].nRBSize);
pRbElm = &pRbMap->prbMap[section_id_tmp];
int pos_len = 0;
int neg_len = 0;
if (pRbElm->nRBStart < (nPRBs >> 1)) // there are PRBs left of DC
neg_len = min((nPRBs * 6) - (pRbElm->nRBStart * 12), pRbElm->nRBSize * N_SC_PER_PRB);
pos_len = (pRbElm->nRBSize * N_SC_PER_PRB) - neg_len;
src = pData;
// Calculation of the pointer for the section in the buffer.
// positive half
int32_t local_dst[pRbElm->nRBSize * N_SC_PER_PRB] __attribute__((aligned(64)));
if (pRbElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
struct xranlib_decompress_request bfp_decom_req;
struct xranlib_decompress_response bfp_decom_rsp;
payload_len = (3 * pRbElm->iqWidth + 1) * pRbElm->nRBSize;
memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
bfp_decom_req.data_in = (int8_t *)src;
bfp_decom_req.numRBs = pRbElm->nRBSize;
bfp_decom_req.len = payload_len;
bfp_decom_req.compMethod = pRbElm->compMethod;
bfp_decom_req.iqWidth = pRbElm->iqWidth;
bfp_decom_rsp.data_out = (int16_t *)local_dst;
bfp_decom_rsp.len = 0;
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
if (local_dst != NULL )
{
int energy_level = dB_fixed(signal_energy((int32_t*)local_dst,(neg_len + pos_len)));
if (1/*energy_level> 30*/ )
{
printf("check buffer PUSCH tti %d slot %d symb %d energy level %d ra %d beamid %d\n", tti, slot, sym_idx, energy_level,ant_id,pRbMap->prbMap[idxElm].nBeamIndex);
}else
return -2;
}
else return -1;
} else {
printf("pRbElm->compMethod == %d is not supported\n", pRbElm->compMethod);
exit(-1);
}
return 0;
}
int update_beams_ctx(int beamID[2][1120])
{
struct xran_device_ctx *xran_ctx = xran_dev_get_ctx();
if (beamID){
//printf("beamID is %d\n");
for (int i=0; i<80*14; i++) {
xran_ctx->beamID[0][i] = beamID[0][i];
//printf("[update_beams_ctx] slot %d symbol %d beamID is %d\n", i / 14, i%14, beamID[0][i]);
}
return 1;
}
return 0;
}
int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
{
void *ptr = NULL;
@@ -275,6 +406,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
static int64_t old_tx_counter[XRAN_PORTS_NUM] = {0};
struct xran_common_counters x_counters[XRAN_PORTS_NUM];
static int outcnt = 0;
#ifndef USE_POLLING
// pull next even from oran_sync_fifo
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&oran_sync_fifo);
@@ -305,15 +437,16 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
LOG_D(PHY, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot);
last_slot = *slot;
#endif
// return(0);
//return(0);
struct xran_device_ctx *xran_ctx = xran_dev_get_ctx();
int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology;
int tti = slots_per_frame * (*frame) + (*slot);
if (xran_ctx->fh_cfg.prachEnable)
read_prach_data(ru, *frame, *slot);
const struct xran_fh_init *fh_init = &xran_ctx->fh_init;
int nPRBs = xran_ctx->fh_cfg.nULRBs;
int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize;
@@ -322,6 +455,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
uint32_t slot_size = 4 * 14 * fftsize;
uint8_t *rx_data = (uint8_t *)ru->rxdataF[0];
uint8_t *start_ptr = NULL;
int print_next = 0;
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) {
@@ -332,11 +466,12 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
int tdd_period = fh_config->frame_conf.nTddPeriod;
int slot_in_period = *slot % tdd_period;
if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT - 1] == 0)
continue;
continue;
// skip processing this slot if the last symbol in the slot is TX
// (no RX in this slot)
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
for (int32_t sym_idx_l = 0; sym_idx_l < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx_l++) {
int32_t sym_idx = sym_idx_l;
/* the callback is for mixed and UL slots. In mixed, we have to
* skip DL and guard symbols. */
if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[sym_idx] != 1 /* UL */)
@@ -347,12 +482,10 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
.sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0];
#ifdef E_RELEASE
struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[sym_idx][0];
#elif defined F_RELEASE
struct xran_section_desc *p_sec_desc = &pRbElm->sec_desc[sym_idx][0];
#endif
u_int8_t section_id_tmp = pPrbMap->nPrbElm < 10 ? sym_idx - 10: sym_idx; // Temporary hack for LiteON FR2 : receive UP section ID = 13
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[section_id_tmp];
struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[/*sym_idx*/0][0];
uint32_t one_rb_size =
(((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1));
if (fh_init->mtu < pRbElm->nRBSize * one_rb_size)
@@ -362,7 +495,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
else
pData = p_sec_desc->pData;
ptr = pData;
pos = (int32_t *)(start_ptr + (4 * sym_idx * fftsize));
pos = (int32_t *)(start_ptr + (4 * sym_idx_l * fftsize));
if (ptr == NULL || pos == NULL)
continue;
@@ -374,13 +507,13 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
LOG_D(PHY, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
//for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
LOG_D(PHY,
"prbMap[%d] : PRBstart %d nPRBs %d\n",
idxElm,
pRbMap->prbMap[idxElm].nRBStart,
pRbMap->prbMap[idxElm].nRBSize);
pRbElm = &pRbMap->prbMap[idxElm];
section_id_tmp,
pRbMap->prbMap[section_id_tmp].nRBStart,
pRbMap->prbMap[section_id_tmp].nRBSize);
pRbElm = &pRbMap->prbMap[section_id_tmp];
int pos_len = 0;
int neg_len = 0;
@@ -423,11 +556,25 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
outcnt++;
/*if (local_dst != NULL )
{
int energy_level = dB_fixed(signal_energy((int32_t*)local_dst,(neg_len + pos_len)));
if (energy_level> -10 )
{
//if (!print_next) {print_next = 1;}
printf("PUSCH tti %d slot %d symb buffer %d symb OAI %d energy level %d ra %d beamid %d\n", tti, *slot, sym_idx, sym_idx_l, energy_level,ant_id,pRbMap->prbMap[idxElm].nBeamIndex);
}//else
//print_next = 0;
}*/
//int check_buffer(int cc_id, int ant_id, int sym_idx, int frame, int slot )
} else {
printf("pRbElm->compMethod == %d is not supported\n", pRbElm->compMethod);
exit(-1);
}
}
//}
} // sym_ind
} // ant_ind
} // vv_inf
@@ -464,7 +611,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
{
int tti = /*frame*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME+*/ 20 * frame
int tti = /*frame*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME+*/ 80 * frame
+ slot; // commented out temporarily to check that compilation of oran 5g is working.
void *ptr = NULL;
@@ -476,18 +623,29 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
int nPRBs = xran_ctx->fh_cfg.nDLRBs;
int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize;
int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports;
const struct xran_fh_config *fh_config = &xran_ctx->fh_cfg;
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < ru->nb_tx; ant_id++) {
xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_tx_per_ru);
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
uint8_t *pData = xran_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_tx_per_ru]
.sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT]
.pData;
int tdd_period = fh_config->frame_conf.nTddPeriod;
int slot_in_period = slot % tdd_period;
if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[sym_idx] != 0)
continue;
uint8_t *pPrbMapData = xran_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_tx_per_ru]
.sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
uint8_t *pData = xran_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id % nb_tx_per_ru]
.sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT]
.pData;
ptr = pData;
pos = &ru->txdataF_BF[ant_id][sym_idx * fftsize];
@@ -502,23 +660,16 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
uint8_t *dst = (uint8_t *)u8dptr;
struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm];
u_int8_t section_id_tmp = sym_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
struct xran_section_desc *p_sec_desc = NULL;
p_prbMapElm = &pRbMap->prbMap[idxElm];
// assumes one fragment per symbol
#ifdef E_RELEASE
p_sec_desc = p_prbMapElm->p_sec_desc[sym_id][0];
#elif F_RELEASE
p_sec_desc = &p_prbMapElm->sec_desc[sym_id][0];
#endif
p_prbMapElm = &pRbMap->prbMap[section_id_tmp];
p_sec_desc =
// assumes one fragment per symbol
p_prbMapElm->p_sec_desc[/*sym_id*/0][0];
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
uint16_t *dst16 = (uint16_t *)dst;
int pos_len = 0;
@@ -536,6 +687,14 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
uint32_t local_src[p_prbMapElm->nRBSize * N_SC_PER_PRB] __attribute__((aligned(64)));
memcpy((void *)local_src, (void *)src2, neg_len * 4);
memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4);
/*if (local_src != NULL )
{
int energy_level = dB_fixed(signal_energy((int32_t*)local_src,(neg_len + pos_len)));
if (energy_level>40 )
{
printf("PDSCH tti %d slot %d symb %d energy level %d ant %d beam %d\n", tti, slot, sym_idx, energy_level,ant_id, xran_ctx->beamID[0][slot*14+sym_idx]);
}
} */
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = p_prbMapElm->nRBSize * N_SC_PER_PRB * 4L;
/* convert to Network order */
@@ -564,13 +723,14 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
exit(-1);
}
if (p_sec_desc != NULL) {
p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr);
p_sec_desc->iq_buffer_len = payload_len;
}
dst += payload_len;
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
}
//}
// The tti should be updated as it increased.
pRbMap->tti_id = tti;

View File

@@ -27,7 +27,6 @@
#include "xran_fh_o_du.h"
#include "xran_cp_api.h"
#include "rte_ether.h"
#include <rte_ethdev.h>
#include "stdio.h"
#include "string.h"
@@ -35,7 +34,7 @@
static void print_fh_eowd_cmn(unsigned index, const struct xran_ecpri_del_meas_cmn *eowd_cmn)
{
printf("\
eowd_cmn[%u]:\n\
eowd_cmn[%d]:\n\
initiator_en %d\n\
numberOfSamples %d\n\
filterType %d\n\
@@ -59,6 +58,55 @@ static void print_fh_eowd_cmn(unsigned index, const struct xran_ecpri_del_meas_c
eowd_cmn->owdm_PlLength);
}
static void print_fh_eowd_port(unsigned index, unsigned vf, const struct xran_ecpri_del_meas_port *eowd_port)
{
printf("\
eowd_port[%d][%d]:\n\
t1 %ld\n\
t2 %ld\n\
tr %ld\n\
delta %ld\n\
portid %d\n\
runMeas %d\n\
currentMeasID %d\n\
msState %d\n\
numMeas %d\n\
txDone %d\n\
rspTimerIdx %ld\n\
delaySamples [%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld]\n\
delayAvg %ld\n",
index,
vf,
eowd_port->t1,
eowd_port->t2,
eowd_port->tr,
eowd_port->delta,
eowd_port->portid,
eowd_port->runMeas,
eowd_port->currentMeasID,
eowd_port->msState,
eowd_port->numMeas,
eowd_port->txDone,
eowd_port->rspTimerIdx,
eowd_port->delaySamples[0],
eowd_port->delaySamples[1],
eowd_port->delaySamples[2],
eowd_port->delaySamples[3],
eowd_port->delaySamples[4],
eowd_port->delaySamples[5],
eowd_port->delaySamples[6],
eowd_port->delaySamples[7],
eowd_port->delaySamples[8],
eowd_port->delaySamples[9],
eowd_port->delaySamples[10],
eowd_port->delaySamples[11],
eowd_port->delaySamples[12],
eowd_port->delaySamples[13],
eowd_port->delaySamples[14],
eowd_port->delaySamples[15],
eowd_port->delayAvg);
}
static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
{
printf("\
@@ -103,7 +151,7 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
pkt_proc_core_64_127 %016lx\n\
pkt_aux_core %d\n\
timing_core %d\n\
port (filled within xran library)\n\
port [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ]\n\
io_sleep %d\n\
nEthLinePerPort %d\n\
nEthLineSpeed %d\n\
@@ -114,17 +162,31 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
io_cfg->pkt_proc_core_64_127,
io_cfg->pkt_aux_core,
io_cfg->timing_core,
io_cfg->port[XRAN_UP_VF],
io_cfg->port[XRAN_CP_VF],
io_cfg->port[XRAN_UP_VF1],
io_cfg->port[XRAN_CP_VF1],
io_cfg->port[XRAN_UP_VF2],
io_cfg->port[XRAN_CP_VF2],
io_cfg->port[XRAN_UP_VF3],
io_cfg->port[XRAN_CP_VF3],
io_cfg->port[XRAN_UP_VF4],
io_cfg->port[XRAN_CP_VF4],
io_cfg->port[XRAN_UP_VF5],
io_cfg->port[XRAN_CP_VF5],
io_cfg->port[XRAN_UP_VF6],
io_cfg->port[XRAN_CP_VF6],
io_cfg->port[XRAN_UP_VF7],
io_cfg->port[XRAN_CP_VF7],
io_cfg->io_sleep,
io_cfg->nEthLinePerPort,
io_cfg->nEthLineSpeed,
io_cfg->one_vf_cu_plane);
print_fh_eowd_cmn(io_cfg->id, &io_cfg->eowd_cmn[io_cfg->id]);
printf("eowd_port (filled within xran library)\n");
#ifdef F_RELEASE
printf("\
bbu_offload %d\n",
io_cfg->bbu_offload);
#endif
print_fh_eowd_cmn(0, &io_cfg->eowd_cmn[0]);
print_fh_eowd_cmn(1, &io_cfg->eowd_cmn[1]);
for (int i = 0; i < 2; ++i)
for (int v = 0; v < io_cfg->num_vfs; ++v)
print_fh_eowd_port(i, v, &io_cfg->eowd_port[i][v]);
}
static void print_fh_init_eaxcid_conf(const struct xran_eaxcid_config *eaxcid_conf)
@@ -172,25 +234,17 @@ void print_fh_init(const struct xran_fh_init *fh_init)
dpdkBasebandFecMode %d\n\
dpdkBasebandDevice %s\n\
filePrefix %s\n\
mtu %d\n\
p_o_du_addr %s\n",
mtu %d\n",
fh_init->xran_ports,
fh_init->dpdkBasebandFecMode,
fh_init->dpdkBasebandDevice,
fh_init->filePrefix,
fh_init->mtu,
fh_init->p_o_du_addr);
fh_init->mtu);
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);
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);
printf("\
totalBfWeights %d\n",
fh_init->totalBfWeights);
#ifdef F_RELEASE
printf("\
mlogxranenable %d\n\
dlCpProcBurst %d\n",
fh_init->mlogxranenable,
fh_init->dlCpProcBurst);
#endif
}
static void print_prach_config(const struct xran_prach_config *prach_conf)
@@ -227,11 +281,6 @@ static void print_prach_config(const struct xran_prach_config *prach_conf)
prach_conf->timeOffset,
prach_conf->freqOffset,
prach_conf->eAxC_offset);
#ifdef F_RELEASE
printf("\
nPrachConfIdxLTE %d\n",
prach_conf->nPrachConfIdxLTE);
#endif
}
static void print_srs_config(const struct xran_srs_config *srs_conf)
@@ -391,14 +440,6 @@ void print_fh_config(const struct xran_fh_config *fh_config)
fh_config->GPS_Alpha,
fh_config->GPS_Beta);
#ifdef F_RELEASE
printf("\
srsEnableCp %d\n\
SrsDelaySym %d\n",
fh_config->srsEnableCp,
fh_config->SrsDelaySym);
#endif
print_prach_config(&fh_config->prach_conf);
print_srs_config(&fh_config->srs_conf);
print_frame_config(&fh_config->frame_conf);
@@ -407,33 +448,18 @@ void print_fh_config(const struct xran_fh_config *fh_config)
printf("\
bbdev_enc %p\n\
bbdev_dec %p\n\
tx_cp_eAxC2Vf %p\n\
tx_up_eAxC2Vf %p\n\
rx_cp_eAxC2Vf %p\n\
rx_up_eAxC2Vf %p\n\
tx_cp_eAxC2Vf [not implemented by fhi_lib]\n\
tx_up_eAxC2Vf [not implemented by fhi_lib]\n\
rx_cp_eAxC2Vf [not implemented by fhi_lib]\n\
rx_up_eAxC2Vf [not implemented by fhi_lib]\n\
log_level %d\n\
max_sections_per_slot %d\n\
max_sections_per_symbol %d\n",
fh_config->bbdev_enc,
fh_config->bbdev_dec,
fh_config->tx_cp_eAxC2Vf,
fh_config->tx_up_eAxC2Vf,
fh_config->rx_cp_eAxC2Vf,
fh_config->rx_up_eAxC2Vf,
fh_config->log_level,
fh_config->max_sections_per_slot,
fh_config->max_sections_per_symbol);
#ifdef F_RELEASE
printf("\
RunSlotPrbMapBySymbolEnable %d\n\
dssEnable %d\n\
dssPeriod %d\n\
technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n",
fh_config->RunSlotPrbMapBySymbolEnable,
fh_config->dssEnable,
fh_config->dssPeriod);
#endif
}
static const paramdef_t *gpd(const paramdef_t *pd, int num, const char *name)
@@ -452,96 +478,57 @@ static uint64_t get_u64_mask(const paramdef_t *pd)
for (int i = 0; i < pd->numelt; ++i) {
int num = pd->iptr[i];
AssertFatal(num >= 0 && num < 64, "cannot put element of %d in 64-bit mask\n", num);
mask |= 1LL << num;
mask |= 1 << num;
}
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)
{
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->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) {
io_cfg->dpdk_dev[i] = strdup(gpd(fhip, nump, ORAN_CONFIG_DPDK_DEVICES)->strlistptr[i]); // VFs devices
}
io_cfg->bbdev_dev[0] = NULL; // BBDev dev name; max devices = 1
io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev
int dpdk_iova_mode_idx = config_paramidx_fromname((paramdef_t *)fhip, nump, ORAN_CONFIG_DPDK_IOVA_MODE);
AssertFatal(dpdk_iova_mode_idx >= 0,"Index for dpdk_iova_mode config option not found!");
io_cfg->dpdkIoVaMode = config_get_processedint(config_get_if(), (paramdef_t *)&fhip[dpdk_iova_mode_idx]); // IOVA mode
io_cfg->dpdkMemorySize = *gpd(fhip, nump, ORAN_CONFIG_DPDK_MEM_SIZE)->uptr; // DPDK max memory allocation
/* the following core assignment is needed for rte_eal_init() function within xran library;
these parameters are machine specific */
io_cfg->core = *gpd(fhip, nump, ORAN_CONFIG_IO_CORE)->iptr; // core used for IO; absolute CPU core ID for xran library, it should be an isolated core
io_cfg->system_core = *gpd(fhip, nump, ORAN_CONFIG_SYSTEM_CORE)->iptr; // absolute CPU core ID for DPDK control threads, it should be an isolated core
io_cfg->pkt_proc_core = get_u64_mask(gpd(fhip, nump, ORAN_CONFIG_WORKER_CORES)); // worker mask 0-63
io_cfg->pkt_proc_core_64_127 = 0x0; // worker mask 64-127; to be used if machine supports more than 64 cores
io_cfg->pkt_aux_core = 0; // sample app says 0 = "do not start"
io_cfg->timing_core = *gpd(fhip, nump, ORAN_CONFIG_IO_CORE)->iptr; // core used by xran
// io_cfg->port[XRAN_VF_MAX] // VFs ports; filled within xran library
io_cfg->io_sleep = 0; // enable sleep on PMD cores; 0 -> no sleep
io_cfg->nEthLinePerPort = *gpd(fhip, nump, ORAN_CONFIG_NETHPERPORT)->uptr; // 1, 2, 3 total number of links per O-RU (Fronthaul Ethernet link)
io_cfg->nEthLineSpeed = *gpd(fhip, nump, ORAN_CONFIG_NETHSPEED)->uptr; // 10G,25G,40G,100G speed of Physical connection on O-RU
io_cfg->one_vf_cu_plane = (io_cfg->num_vfs == num_rus); // C-plane and U-plane use one VF
/* eCPRI One-Way Delay Measurements common settings for O-DU and O-RU;
use owdm to calculate T12 and T34 -> CUS specification, section 2.3.3.3;
this is an optional feature that RU might or might not support;
to verify if RU supports, please check in the official RU documentation or
via M-plane the o-ran-ecpri-delay@<version>.yang capability;
this functionality is improved in F release */
/* if RU does support, io_cfg->eowd_cmn[0] should only be filled as id = O_DU; io_cfg->eowd_cmn[1] only used if id = O_RU */
const uint16_t owdm_enable = *gpd(fhip, nump, ORAN_CONFIG_ECPRI_OWDM)->uptr;
if (owdm_enable) {
io_cfg->eowd_cmn[0].initiator_en = 1; // 1 -> initiator (always O-DU), 0 -> recipient (always O-RU)
io_cfg->eowd_cmn[0].numberOfSamples = 8; // total number of samples to be collected and averaged per port
io_cfg->eowd_cmn[0].filterType = 0; // 0 -> simple average based on number of measurements; not used in xran in both E and F releases
io_cfg->eowd_cmn[0].responseTo = 10000000; // response timeout in [ns]
io_cfg->eowd_cmn[0].measVf = 0; // VF using the OWD transmitter; within xran, the measurements are calculated per each supported VF, but starts from measVf
io_cfg->eowd_cmn[0].measState = 0; // the state of the OWD transmitter; 0 -> OWDMTX_INIT (enum xran_owdm_tx_state)
io_cfg->eowd_cmn[0].measId = 0; // measurement ID to be used by the transmitter
io_cfg->eowd_cmn[0].measMethod = 0; // measurement method; 0 -> XRAN_REQUEST (enum xran_owd_meas_method)
io_cfg->eowd_cmn[0].owdm_enable = 1; // 1 -> enabled; 0 -> disabled
io_cfg->eowd_cmn[0].owdm_PlLength = 40; // payload in the measurement packet; 40 <= PlLength <= 1400
}
/* eCPRI OWDM per port variables for O-DU; this parameter is filled within xran library */
// eowd_port[0][XRAN_VF_MAX]
#ifdef F_RELEASE
io_cfg->bbu_offload = 0; // enable packet handling on BBU cores
#endif
io_cfg->id = 0; // 0 = O-DU
io_cfg->num_vfs = num_dev;
io_cfg->num_rxq = 2; // Assume two HW RX queues per RU
for (int i = 0; i < num_dev; ++i)
io_cfg->dpdk_dev[i] = strdup(gpd(fhip, nump, ORAN_CONFIG_DPDK_DEVICES)->strlistptr[i]);
//io_cfg->bbdev_dev = NULL;
io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // none
io_cfg->dpdkIoVaMode = 0; /* IOVA mode */
io_cfg->dpdkMemorySize = *gpd(fhip, nump, ORAN_CONFIG_DPDK_MEM_SIZE)->uptr;
io_cfg->core = *gpd(fhip, nump, ORAN_CONFIG_IO_CORE)->iptr;
io_cfg->system_core = *gpd(fhip, nump, ORAN_CONFIG_SYSTEM_CORE)->iptr;
io_cfg->pkt_proc_core = get_u64_mask(gpd(fhip, nump, ORAN_CONFIG_WORKER_CORES));
io_cfg->pkt_proc_core_64_127 = 0x0; // bitmap 0 -> no core
io_cfg->pkt_aux_core = 0; /* sapmle app says 0 = "do not start" */
io_cfg->timing_core = *gpd(fhip, nump, ORAN_CONFIG_IO_CORE)->iptr; /* sample app: equal to io_core */
//io_cfg->port = {0}; // all 0
io_cfg->io_sleep = 0; // no sleep
io_cfg->nEthLinePerPort = *gpd(fhip, nump, ORAN_CONFIG_NETHPERPORT)->uptr;
io_cfg->nEthLineSpeed = *gpd(fhip, nump, ORAN_CONFIG_NETHSPEED)->uptr;
io_cfg->one_vf_cu_plane = 0; // false: C/U-plane don't share VF
// io_cfg->eowd_cmn[0] // all 0
// io_cfg->eowd_cmn[1] // all 0
// io_cfg->eowd_port[0]... // all 0
return true;
}
static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat)
{
/* CUS specification, section 3.1.3.1.6
DU_port_ID - used to differentiate processing units at O-DU (e.g., different baseband cards).
BandSector_ID - aggregated cell identifier (distinguishes bands and sectors supported by the O-RU).
CC_ID - distinguishes Carrier Components supported by the O-RU.
RU_Port_ID - designates logical flows such as data layers or spatial streams, and logical flows such as separate
numerologies (e.g. PRACH) or signaling channels requiring special antenna assignments such as SRS.
The assignment of the DU_port_ID, BandSector_ID, CC_ID, and RU_Port_ID
as part of the eAxC ID is done solely by the O-DU via the M-plane.
Each ID field has a flexible bit allocation, but the total eAxC ID field length is fixed, 16 bits. */
// values taken from sample app
switch (cat) {
case XRAN_CATEGORY_A:
eaxcid_conf->mask_cuPortId = 0xf000;
eaxcid_conf->mask_bandSectorId = 0x0f00;
eaxcid_conf->mask_ccId = 0x00f0;
eaxcid_conf->mask_ruPortId = 0x000f;
eaxcid_conf->bit_cuPortId = 0;
eaxcid_conf->bit_bandSectorId = 0; // total number of band sectors supported by O-RU should be retreived by M-plane - <max-num-bands> && <max-num-sectors>
eaxcid_conf->bit_ccId = 0; // total number of CC supported by O-RU should be retreived by M-plane - <max-num-component-carriers>
eaxcid_conf->bit_cuPortId = 12;
eaxcid_conf->bit_bandSectorId = 8;
eaxcid_conf->bit_ccId = 4;
eaxcid_conf->bit_ruPortId = 0;
break;
case XRAN_CATEGORY_B:
@@ -573,7 +560,7 @@ uint8_t *get_ether_addr(const char *addr, struct rte_ether_addr *ether_addr)
return NULL;
}
static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_cat)
bool set_fh_init(struct xran_fh_init *fh_init)
{
memset(fh_init, 0, sizeof(*fh_init));
@@ -588,11 +575,7 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
}
paramdef_t fhip[] = ORAN_GLOBALPARAMS_DESC;
checkedparam_t fhip_CheckParams[] = ORAN_GLOBALPARAMS_CHECK_DESC;
static_assert(sizeofArray(fhip) == sizeofArray(fhip_CheckParams),
"fhip and fhip_CheckParams should have the same size");
int nump = sizeofArray(fhip);
config_set_checkfunctions(fhip, fhip_CheckParams, nump);
int ret = config_get(config_get_if(), fhip, nump, CONFIG_STRING_ORAN);
if (ret <= 0) {
printf("problem reading section \"%s\"\n", CONFIG_STRING_ORAN);
@@ -605,28 +588,42 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
sprintf(aprefix, "%s", CONFIG_STRING_ORAN);
const int nfh = sizeofArray(FHconfigs);
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
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus))
int num_rus = FH_ConfigList.numelt;
int num_ru_addr = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->numelt;
int num_du_addr = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->numelt;
int num_vfs = gpd(fhip, nump, ORAN_CONFIG_DPDK_DEVICES)->numelt;
if (num_ru_addr != num_du_addr) {
printf("need to have same number of DUs and RUs!\n");
return false;
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, xran_cat))
}
if (num_ru_addr != num_vfs) {
printf("need to have as many RU/DU entries as DPDK devices (one VF for CP and UP each)\n");
return false;
}
if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump))
return false;
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, XRAN_CATEGORY_A))
return false;
fh_init->xran_ports = num_rus; // since we use xran as O-DU, xran_ports is set to the number of RUs
fh_init->dpdkBasebandFecMode = 0; // DPDK Baseband FEC device mode (0-SW, 1-HW); not used in xran
fh_init->dpdkBasebandDevice = NULL; // DPDK Baseband device address; not used in xran
/* used to specify a unique prefix for shared memory, and files created by multiple DPDK processes;
it is necessary */
fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr);
/* 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);
xran only checks if (MTU <= 1500), therefore setting any value > 1500, xran assumes 9600 value is used */
fh_init->xran_ports = num_rus;
fh_init->dpdkBasebandFecMode = 0;
fh_init->dpdkBasebandDevice = NULL;
fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr); // see DPDK --file-prefix
fh_init->mtu = *gpd(fhip, nump, ORAN_CONFIG_MTU)->uptr;
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;
// if multiple RUs: xran_ethdi_init_dpdk_io() iterates over
// &p_o_ru_addr[i]
char **du_addrs = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->strlistptr;
fh_init->p_o_du_addr = calloc(num_du_addr, sizeof(struct rte_ether_addr));
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->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");
@@ -637,18 +634,44 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
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
#ifdef F_RELEASE
fh_init->mlogxranenable = 0; // enable mlog; 0 -> disabled
fh_init->dlCpProcBurst = 0; /* 1 -> DL CP processing will be done on single symbol,
0 -> DL CP processing will be spread across all allowed symbols and multiple cores to reduce burstiness */
#endif
fh_init->totalBfWeights = 32;
return true;
}
static enum xran_cp_filterindex get_prach_filterindex_fr1(duplex_mode_t mode, int prach_index)
{
if (mode == duplex_mode_TDD) {
// 38.211 table 6.3.3.2-3 "unpaired spectrum" -> TDD
switch (prach_index) {
case 0 ... 39:
case 256 ... 262:
return XRAN_FILTERINDEX_PRACH_012;
case 40 ... 66:
return XRAN_FILTERINDEX_PRACH_3;
case 67 ... 255:
return XRAN_FILTERINDEX_PRACH_ABC;
}
} else if (mode == duplex_mode_FDD) {
// 38.211 table 6.3.3.2-2 "paired spectrum" -> FDD
switch (prach_index) {
case 0 ... 59:
return XRAN_FILTERINDEX_PRACH_012;
case 60 ... 86:
return XRAN_FILTERINDEX_PRACH_3;
case 87 ... 255:
return XRAN_FILTERINDEX_PRACH_ABC;
default:
AssertFatal(false, "unknown PRACH index %d\n", prach_index);
}
} else {
AssertFatal(false, "unsupported duplex mode %d\n", mode);
}
return XRAN_FILTERINDEX_STANDARD;
}
// PRACH guard interval. Raymond: "[it] is not in the configuration, (i.e. it
// is deterministic depending on others). LiteON must hard-code this in the
// O-RU itself, benetel doesn't (as O-RAN specifies). So we will need to tell
@@ -657,87 +680,75 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
int g_kbar;
static bool set_fh_prach_config(const openair0_config_t *oai0,
const uint32_t max_num_ant,
const paramdef_t *prachp,
int nprach,
struct xran_prach_config *prach_config)
{
const split7_config_t *s7cfg = &oai0->split7;
prach_config->nPrachConfIdx = s7cfg->prach_index; // PRACH Configuration Index
prach_config->nPrachSubcSpacing = oai0->nr_scs_for_raster; // 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz
prach_config->nPrachZeroCorrConf = 0; // PRACH zeroCorrelationZoneConfig; should be saved from config file; not used in xran
prach_config->nPrachRestrictSet = 0; /* PRACH restrictedSetConfig; should be saved from config file; 0 = unrestricted,
1 = restricted type A, 2=restricted type B; not used in xran */
prach_config->nPrachRootSeqIdx = 0; // PRACH Root Sequence Index; should be saved from config file; 1 = 839, 2 = 139; not used in xran
prach_config->nPrachFreqStart = s7cfg->prach_freq_start; // PRACH frequency start (MSG1)
prach_config->nPrachFreqOffset = (s7cfg->prach_freq_start * 12 - oai0->num_rb_dl * 6) * 2; // PRACH frequency offset
prach_config->nPrachFilterIdx = 0; /* PRACH filter index; not used in xran;
in E release hardcoded to XRAN_FILTERINDEX_PRACH_ABC (preamble format A1~3, B1~4, C0, C2)
in F release properly calculated */
/* Return values after initialization */
prach_config->nPrachConfIdx = s7cfg->prach_index;
prach_config->nPrachSubcSpacing = oai0->nr_scs_for_raster;
prach_config->nPrachZeroCorrConf = 0;
prach_config->nPrachRestrictSet = 0;
prach_config->nPrachRootSeqIdx = 0;
prach_config->nPrachFreqStart = s7cfg->prach_freq_start;
prach_config->nPrachFreqOffset = -792; //(s7cfg->prach_freq_start * 12 - oai0->num_rb_dl * 6) * 2 + 4;
if (oai0->nr_band < 100)
prach_config->nPrachFilterIdx = get_prach_filterindex_fr1(oai0->duplex_mode, s7cfg->prach_index);
else
prach_config->nPrachFilterIdx = XRAN_FILTERINDEX_PRACH_ABC;
prach_config->startSymId = 0;
prach_config->lastSymId = 0;
prach_config->startPrbc = 0;
prach_config->numPrbc = 0;
prach_config->timeOffset = 0;
prach_config->freqOffset = 0;
#ifdef F_RELEASE
prach_config->nPrachConfIdxLTE = 0; // used only if DSS enabled and technology is XRAN_RAN_LTE
#endif
/* xran defines PDSCH eAxC IDs as [0...Ntx-1];
xran defines PUSCH eAxC IDs as [0...Nrx-1];
xran assumes PRACH offset >= max(Ntx, Nrx). However, we made a workaround that xran supports PRACH eAxC IDs same as PUSCH eAxC IDs.
This is achieved with is_prach and filter_id parameters in the patch.
Please note that this approach only applies to the RUs that support this functionality, e.g. LITEON RU. */
uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
prach_config->eAxC_offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr;
return true;
}
static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame_config *frame_config)
static bool set_fh_srs_config(struct xran_srs_config *srs_config)
{
const split7_config_t *s7cfg = &oai0->split7;
frame_config->nFrameDuplexType = oai0->duplex_mode == duplex_mode_TDD ? XRAN_TDD : XRAN_FDD; // Frame Duplex type: 0 -> FDD, 1 -> TDD
frame_config->nNumerology = oai0->nr_scs_for_raster; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz
3 -> 120kHz, 4 -> 240kHz */
if (frame_config->nFrameDuplexType == XRAN_FDD)
return true;
// TDD periodicity
frame_config->nTddPeriod = s7cfg->n_tdd_period;
// TDD Slot configuration
struct xran_slot_config *sc = &frame_config->sSlotConfig[0];
for (int slot = 0; slot < frame_config->nTddPeriod; ++slot)
for (int sym = 0; sym < 14; ++sym)
sc[slot].nSymbolType[sym] = s7cfg->slot_dirs[slot].sym_dir[sym];
srs_config->symbMask = 0;
srs_config->eAxC_offset = 8;
return true;
}
static bool set_fh_ru_config(const paramdef_t *rup, uint16_t fftSize, int nru, enum xran_category xran_cat, struct xran_ru_config *ru_config)
static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame_config *frame_config)
{
ru_config->xranTech = XRAN_RAN_5GNR; // 5GNR or LTE
ru_config->xranCat = xran_cat; // mode: Catergory A or Category B
ru_config->xranCompHdrType = XRAN_COMP_HDR_TYPE_STATIC; // dynamic or static udCompHdr handling
ru_config->iqWidth = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH)->uptr; // IQ bit width
const split7_config_t *s7cfg = &oai0->split7;
frame_config->nFrameDuplexType = oai0->duplex_mode == duplex_mode_TDD ? XRAN_TDD : XRAN_FDD;
frame_config->nNumerology = oai0->nr_scs_for_raster;
frame_config->nTddPeriod = s7cfg->n_tdd_period;
struct xran_slot_config *sc = &frame_config->sSlotConfig[0];
for (int slot = 0; slot < frame_config->nTddPeriod; ++slot)
for (int sym = 0; sym < 14; ++sym){
sc[slot].nSymbolType[sym] = s7cfg->slot_dirs[slot].sym_dir[sym];
//if (sym > 7 && slot > 6) sc[slot].nSymbolType[sym] = 1; // LITEON FR2
}
return true;
}
static bool set_fh_ru_config(const paramdef_t *rup, int nru, struct xran_ru_config *ru_config)
{
ru_config->xranTech = XRAN_RAN_5GNR;
ru_config->xranCat = XRAN_CATEGORY_A;
ru_config->xranCompHdrType = XRAN_COMP_HDR_TYPE_STATIC;
ru_config->iqWidth = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH)->uptr;
AssertFatal(ru_config->iqWidth <= 16, "IQ Width cannot be > 16!\n");
ru_config->compMeth = ru_config->iqWidth < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method
ru_config->iqWidth_PRACH = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH_PRACH)->uptr; // IQ bit width for PRACH
ru_config->compMeth = ru_config->iqWidth < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE;
ru_config->iqWidth_PRACH = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH_PRACH)->uptr;
AssertFatal(ru_config->iqWidth_PRACH <= 16, "IQ Width for PRACH cannot be > 16!\n");
ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method for PRACH
AssertFatal(fftSize > 0, "FFT size cannot be 0\n");
ru_config->fftSize = fftSize; // FFT Size
ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER; // order of bytes in int16_t in buffer; big or little endian
ru_config->iqOrder = XRAN_I_Q_ORDER; // order of IQs in the buffer
ru_config->xran_max_frame = 0; // max frame number supported; if not specified, default of 1023 is used
ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE;
ru_config->fftSize = *gpd(rup, nru, ORAN_RU_CONFIG_FFT_SIZE)->uptr;
ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER;
ru_config->iqOrder = XRAN_I_Q_ORDER;
ru_config->xran_max_frame = 0;
return true;
}
@@ -757,12 +768,17 @@ static bool set_maxmin_pd(const paramdef_t *pd, int num, const char *name, uint1
return true;
}
static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat, const openair0_config_t *oai0, struct xran_fh_config *fh_config)
extern uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
bool set_fh_config(int ru_idx, int num_rus, const openair0_config_t *oai0, struct xran_fh_config *fh_config)
{
AssertFatal(num_rus == 1 || num_rus == 2, "only support 1 or 2 RUs as of now\n");
AssertFatal(ru_idx < num_rus, "illegal ru_idx %d: must be < %d\n", ru_idx, num_rus);
DevAssert(oai0->tx_num_channels > 0 && oai0->rx_num_channels > 0);
DevAssert(oai0->tx_bw > 0 && oai0->rx_bw > 0);
//AssertFatal(oai0->tx_num_channels == oai0->rx_num_channels, "cannot handle unequal number of TX/RX channels\n");
DevAssert(oai0->tx_freq[0] > 0);
for (int i = 1; i < oai0->tx_num_channels; ++i)
DevAssert(oai0->tx_freq[0] == oai0->tx_freq[i]);
@@ -771,7 +787,12 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]);
DevAssert(oai0->nr_band > 0);
DevAssert(oai0->nr_scs_for_raster > 0);
AssertFatal(oai0->threequarter_fs == 0, "cannot use three-quarter sampling with O-RAN 7.2 split\n");
// we simply assume that the loading process provides function to_nrarfcn()
// to calculate the ARFCN numbers from frequency. That is not clean, but the
// best we can do without copy-pasting the function.
uint32_t nDLCenterFreqARFCN = to_nrarfcn(oai0->nr_band, oai0->tx_freq[0], oai0->nr_scs_for_raster, oai0->tx_bw);
uint32_t nULCenterFreqARFCN = to_nrarfcn(oai0->nr_band, oai0->rx_freq[0], oai0->nr_scs_for_raster, oai0->rx_bw);
paramdef_t FHconfigs[] = ORAN_FH_DESC;
paramlist_def_t FH_ConfigList = {CONFIG_STRING_ORAN_FH};
@@ -804,110 +825,70 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
memset(fh_config, 0, sizeof(*fh_config));
fh_config->dpdk_port = ru_idx; // DPDK port number used for FH
fh_config->sector_id = 0; // Band sector ID for FH; not used in xran
fh_config->nCC = 1; // number of Component carriers supported on FH; M-plane info
fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH)
fh_config->neAxcUl = 0; // number of eAxc supported on one CC for UL direction = PUSCH; used only if XRAN_CATEGORY_B
fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B
fh_config->nDLFftSize = 0; // DL FFT size; not used in xran
fh_config->nULFftSize = 0; // UL FFT size; not used in xran
fh_config->nDLRBs = oai0->num_rb_dl; // DL PRB; used in oaioran.c/oran-init.c; not used in xran, neither in E nor in F release
fh_config->nULRBs = oai0->num_rb_dl; // UL PRB; used in oaioran.c/oran-init.c; in xran E release not used so the patch fixes it, but in xran F release this value is properly used
fh_config->nDLAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
fh_config->nULAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
fh_config->nDLCenterFreqARFCN = 0; // center frequency for DL in NR-ARFCN; not used in xran
fh_config->nULCenterFreqARFCN = 0; // center frequency for UL in NR-ARFCN; not used in xran
fh_config->ttiCb = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
fh_config->ttiCbParam = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
fh_config->dpdk_port = ru_idx;
fh_config->sector_id = 0;
fh_config->nCC = 1;
fh_config->neAxc = oai0->tx_num_channels / num_rus;
fh_config->neAxcUl = oai0->rx_num_channels / num_rus;
fh_config->nAntElmTRx = oai0->tx_num_channels / num_rus;
fh_config->nDLFftSize = 1024;
fh_config->nULFftSize = 1024;
fh_config->nDLRBs = oai0->num_rb_dl;
fh_config->nULRBs = oai0->num_rb_dl;
fh_config->nDLAbsFrePointA = 27968160;
fh_config->nULAbsFrePointA = 27968160;
fh_config->nDLCenterFreqARFCN = nDLCenterFreqARFCN;
fh_config->nULCenterFreqARFCN = nULCenterFreqARFCN;
fh_config->ttiCb = NULL;
fh_config->ttiCbParam = NULL;
fh_config->Tadv_cp_dl = *gpd(fhp, nfh, ORAN_FH_CONFIG_TADV_CP_DL)->uptr;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_CP_DL, &fh_config->T2a_min_cp_dl, &fh_config->T2a_max_cp_dl))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_CP_UL, &fh_config->T2a_min_cp_ul, &fh_config->T2a_max_cp_ul))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_UP, &fh_config->T2a_min_up, &fh_config->T2a_max_up))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA3, &fh_config->Ta3_min, &fh_config->Ta3_max))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &fh_config->T1a_min_cp_dl, &fh_config->T1a_max_cp_dl))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_UL, &fh_config->T1a_min_cp_ul, &fh_config->T1a_max_cp_ul))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_UP, &fh_config->T1a_min_up, &fh_config->T1a_max_up))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &fh_config->Ta4_min, &fh_config->Ta4_max))
return false;
fh_config->enableCP = 1;
fh_config->prachEnable = 1;
fh_config->srsEnable = 0;
fh_config->puschMaskEnable = 0;
fh_config->puschMaskSlot = 0;
fh_config->cp_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_CP_VLAN_TAG)->uptr;
fh_config->up_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_UP_VLAN_TAG)->uptr;
fh_config->debugStop = 0;
fh_config->debugStopCount = 0;
fh_config->DynamicSectionEna = 0;
fh_config->GPS_Alpha = 0;
fh_config->GPS_Beta = 0;
/* DU delay profile */
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &fh_config->T1a_min_cp_dl, &fh_config->T1a_max_cp_dl)) // E - min not used in xran, max yes; F - both min and max are used in xran
if (!set_fh_prach_config(oai0, prachp, nprach, &fh_config->prach_conf))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_UL, &fh_config->T1a_min_cp_ul, &fh_config->T1a_max_cp_ul)) // both E and F - min not used in xran, max yes
if (!set_fh_srs_config(&fh_config->srs_conf))
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_UP, &fh_config->T1a_min_up, &fh_config->T1a_max_up)) // both E and F - min not used in xran, max yes
return false;
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &fh_config->Ta4_min, &fh_config->Ta4_max)) // both E and F - min not used in xran, max yes
return false;
fh_config->enableCP = 1; // enable C-plane
fh_config->prachEnable = 1; // enable PRACH
fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B
#ifdef F_RELEASE
fh_config->srsEnableCp = 0; // enable SRS CP; used only if XRAN_CATEGORY_B
fh_config->SrsDelaySym = 0; // number of SRS delay symbols; used only if XRAN_CATEGORY_B
#endif
fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU
fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU
fh_config->cp_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_CP_VLAN_TAG)->uptr; // C-plane VLAN tag; not used in xran; needed for M-plane
fh_config->up_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_UP_VLAN_TAG)->uptr; // U-plane VLAN tag; not used in xran; needed for M-plane
fh_config->debugStop = 0; // enable auto stop; only used if id = O_RU
fh_config->debugStopCount = 0; // enable auto stop after number of Tx packets; not used in xran
fh_config->DynamicSectionEna = 0; // enable dynamic C-Plane section allocation
fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha
fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100
if (!set_fh_prach_config(oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf))
return false;
/* SRS only used if XRAN_CATEGORY_B
Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */
// fh_config->srs_conf = {0};
if (!set_fh_frame_config(oai0, &fh_config->frame_conf))
return false;
if (!set_fh_ru_config(rup, oai0->split7.fftSize, nru, xran_cat, &fh_config->ru_conf))
if (!set_fh_ru_config(rup, nru, &fh_config->ru_conf))
return false;
fh_config->bbdev_enc = NULL; // call back to poll BBDev encoder
fh_config->bbdev_dec = NULL; // call back to poll BBDev decoder
/* CUS specification, section 3.1.3.1.6
This parameter is an eAxC identifier (eAxC ID) and identifies the specific data flow associated with each
C-Plane (ecpriRtcid) or U-Plane (ecpriPcid) message.
Each of bellow parameters is a matrix [XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR] */
// fh_config->tx_cp_eAxC2Vf // mapping of C-Plane (ecpriRtcid) to VF; not used in xran
// fh_config->tx_up_eAxC2Vf // mapping of U-Plane (ecpriPcid) to VF; not used in xran
// fh_config->rx_cp_eAxC2Vf // mapping of C-Plane (ecpriRtcid) to VF; not used in xran
// fh_config->rx_up_eAxC2Vf // mapping of U-Plane (ecpriPcid) to VF; not used in xran
fh_config->log_level = 1; // configuration of log level; 1 -> enabled
/* Parameters that should be retreived via M-plane
O-RU defines them for Section Type 1 (Most DL/UL radio channels) and 3 (PRACH and mixed-numerology channels)
Note: When PRACH having same numerology as other UL channels, Section type 1 can alternatively be used by O-DU for PRACH signaling.
In this case, O-RU is not expected to perform any PRACH specific processing. */
fh_config->max_sections_per_slot = 0; // not used in xran
fh_config->max_sections_per_symbol = 0; // not used in xran
#ifdef F_RELEASE
fh_config->RunSlotPrbMapBySymbolEnable = 0; // enable PRB mapping by symbol with multisection
fh_config->dssEnable = 0; // enable DSS (extension-9)
fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR
// fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled
#endif
return true;
}
bool get_xran_config(const openair0_config_t *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config)
{
/* This xran integration release is only valid for O-RU CAT A.
Therefore, each FH parameter is hardcoded to CAT A.
If you are interested in CAT B, please be aware that parameters of fh_init and fh_config structs must be modified accordingly. */
enum xran_category xran_cat = XRAN_CATEGORY_A;
if (!set_fh_init(fh_init, xran_cat)) {
printf("could not read FHI 7.2/ORAN config\n");
return false;
}
for (int32_t o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) {
if (!set_fh_config(o_xu_id, fh_init->xran_ports, xran_cat, openair0_cfg, &fh_config[o_xu_id])) {
printf("could not read FHI 7.2/RU-specific config\n");
return false;
}
}
fh_config->bbdev_enc = NULL;
fh_config->bbdev_dec = NULL;
// fh_config->tx_cp_eAxC2Vf [not implemented by fhi_lib]
// fh_config->tx_up_eAxC2Vf [not implemented by fhi_lib]
// fh_config->rx_cp_eAxC2Vf [not implemented by fhi_lib]
// fh_config->rx_up_eAxC2Vf [not implemented by fhi_lib]
fh_config->log_level = 1;
fh_config->max_sections_per_slot = 14;
fh_config->max_sections_per_symbol = 14;
return true;
}

View File

@@ -26,14 +26,14 @@
#include "stdint.h"
struct xran_fh_init;
struct xran_fh_config;
struct openair0_config;
bool get_xran_config(const struct openair0_config *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config);
void print_fh_init(const struct xran_fh_init *fh_init);
struct xran_fh_config;
void print_fh_config(const struct xran_fh_config *fh_config);
bool set_fh_init(struct xran_fh_init *fh_init);
struct openair0_config;
bool set_fh_config(int ru_idx, int num_rus, const struct openair0_config *oai0_cfg, struct xran_fh_config *fh_config);
// hack to workaround LiteOn limitation
extern int g_kbar;

View File

@@ -29,9 +29,9 @@
#include "oaioran.h"
#include "common/utils/assertions.h"
#include "common/utils/LOG/log.h"
#include "common_lib.h"
/* PRACH data samples are 32 bits wide (16bits for I/Q). Each packet contains
* 840 samples for long sequence or 144 for short sequence. The payload length
* is 840*16*2/8 octets.*/
@@ -88,16 +88,20 @@ static struct xran_prb_map get_xran_prb_map_dl(const struct xran_fh_config *f)
.cc_id = 0,
.ru_port_id = 0,
.tti_id = 0,
.nPrbElm = 1,
.nPrbElm = 14,//1,
};
struct xran_prb_elm *e = &prbmap.prbMap[0];
for (int i=0; i < prbmap.nPrbElm; i++){
struct xran_prb_elm *e = &prbmap.prbMap[i];
e->nStartSymb = 0;
e->numSymb = 14;
e->numSymb = 1; //14;
e->nRBStart = 0;
e->nRBSize = f->nDLRBs;
e->nBeamIndex = 0;
e->nBeamIndex = 1;
e->compMethod = f->ru_conf.compMeth;
e->iqWidth = f->ru_conf.iqWidth;
}
return prbmap;
}
@@ -111,27 +115,21 @@ static struct xran_prb_map get_xran_prb_map_ul(const struct xran_fh_config *f)
.ru_port_id = 0,
.tti_id = 0,
.start_sym_id = 0,
.nPrbElm = 1,
.nPrbElm = 14,//1, // read this from config file to make it dynamic
};
struct xran_prb_elm *e = &prbmap.prbMap[0];
e->nStartSymb = 0;
e->numSymb = 14;
for (int i=0; i < prbmap.nPrbElm; i++){
struct xran_prb_elm *e = &prbmap.prbMap[i];
e->nStartSymb = 0; //0
e->numSymb = 1;//14;
e->nRBStart = 0;
e->nRBSize = f->nULRBs;
e->nBeamIndex = 0;
e->nBeamIndex = 1;
e->compMethod = f->ru_conf.compMeth;
e->iqWidth = f->ru_conf.iqWidth;
}
return prbmap;
}
static uint32_t next_power_2(uint32_t num)
{
uint32_t power = 2;
while (power < num)
power <<= 1;
return power;
}
static uint32_t oran_allocate_uplane_buffers(
void *instHandle,
struct xran_buffer_list list[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
@@ -141,13 +139,10 @@ static uint32_t oran_allocate_uplane_buffers(
{
xran_status_t status;
uint32_t pool;
/* xran_bm_init() uses rte_pktmbuf_pool_create() which recommends to use a power of two for the buffers;
the E release sample app didn't take this into account, but we introduced it ourselves;
the F release sample app took this into account, so we can proudly say we assumed correctly */
uint32_t numBufs = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT) - 1;
uint32_t numBufs = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT;
status = xran_bm_init(instHandle, &pool, numBufs, bufSize);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, pool, numBufs, bufSize);
printf("xran_bm_init() hInstance %p poolIdx %d elements %d size %d\n", instHandle, pool, numBufs, bufSize);
int count = 0;
for (uint32_t a = 0; a < ant; ++a) {
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
@@ -170,7 +165,7 @@ static uint32_t oran_allocate_uplane_buffers(
}
}
}
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %d\n", instHandle, pool, count);
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %d count %d\n", instHandle, pool, count);
return pool;
}
@@ -218,33 +213,26 @@ static void oran_allocate_cplane_buffers(void *instHandle,
struct xran_flat_buffer buf[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
uint32_t ant,
uint32_t sect,
#ifdef F_RELEASE
uint32_t mtu,
const struct xran_fh_config *fh_config,
#endif
uint32_t size_of_prb_map,
oran_cplane_prb_config *prb_conf)
const oran_cplane_prb_config *prb_conf)
{
xran_status_t status;
uint32_t count1 = 0;
#ifdef E_RELEASE
uint32_t count2 = 0;
uint32_t poolSec;
uint32_t numBufsSec = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT * sect * XRAN_MAX_FRAGMENT);
uint32_t numBufsSec = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT * sect * XRAN_MAX_FRAGMENT;
uint32_t bufSizeSec = sizeof(struct xran_section_desc);
status = xran_bm_init(instHandle, &poolSec, numBufsSec, bufSizeSec);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolSec, numBufsSec, bufSizeSec);
#endif
printf("xran_bm_init() hInstance %p poolIdx %d elements %d size %d\n", instHandle, poolSec, numBufsSec, bufSizeSec);
uint32_t poolPrb;
uint32_t numBufsPrb = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT) - 1;
uint32_t numBufsPrb = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT;
uint32_t bufSizePrb = size_of_prb_map;
status = xran_bm_init(instHandle, &poolPrb, numBufsPrb, bufSizePrb);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolPrb, numBufsPrb, bufSizePrb);
printf("xran_bm_init() hInstance %p poolIdx %d elements %d size %d\n", instHandle, poolPrb, numBufsPrb, bufSizePrb);
uint32_t count1 = 0;
uint32_t count2 = 0;
for (uint32_t a = 0; a < ant; a++) {
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
list[a][j].pBuffers = &buf[a][j];
@@ -262,15 +250,13 @@ static void oran_allocate_cplane_buffers(void *instHandle,
fb->pData = ptr;
fb->pCtrl = mb;
struct xran_prb_map *src = &prb_conf->slotMap;
// the original sample app code copies up to size_of_prb_map, but I think
// this is wrong because the way it is computed leads to a number larger
// than sizeof(map)
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
const struct xran_prb_map *src = &prb_conf->slotMap;
if ((j % prb_conf->nTddPeriod) == prb_conf->mixed_slot_index)
src = &prb_conf->mixedSlotMap;
#ifdef E_RELEASE
/* as per E release sample app, the memory is copied up to size_of_prb_map
which translates to >= sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm)*5,
but we assume that RB allocation is done as 1 RE/UE so the total memory size is sizeof(struct xran_prb_map);
this is improved in F release */
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
memcpy(p_rb_map, src, sizeof(*src));
for (uint32_t elm_id = 0; elm_id < p_rb_map->nPrbElm; ++elm_id) {
@@ -292,19 +278,10 @@ static void oran_allocate_cplane_buffers(void *instHandle,
}
}
}
#elif defined F_RELEASE
if (fh_config->RunSlotPrbMapBySymbolEnable) {
xran_init_PrbMap_by_symbol_from_cfg(src, ptr, mtu, fh_config->nDLRBs);
} else {
xran_init_PrbMap_from_cfg(src, ptr, mtu);
}
#endif
}
}
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %u\n", instHandle, poolPrb, count1);
#ifdef E_RELEASE
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %u\n", instHandle, poolSec, count2);
#endif
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %d count %d\n", instHandle, poolPrb, count1);
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %d count %d\n", instHandle, poolSec, count2);
}
/* callback not actively used */
@@ -317,9 +294,6 @@ static void oran_allocate_buffers(void *handle,
int xran_inst,
int num_sectors,
oran_port_instance_t *portInstances,
#ifdef F_RELEASE
uint32_t mtu,
#endif
const struct xran_fh_config *fh_config)
{
AssertFatal(num_sectors == 1, "only support one sector at the moment\n");
@@ -327,6 +301,7 @@ static void oran_allocate_buffers(void *handle,
AssertFatal(handle != NULL, "no handle provided\n");
uint32_t xran_max_antenna_nr = RTE_MAX(fh_config->neAxc, fh_config->neAxcUl);
uint32_t xran_max_sections_per_slot = RTE_MAX(fh_config->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT);
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256);
AssertFatal(pi->buf_list != NULL, "out of memory\n");
@@ -344,31 +319,25 @@ static void oran_allocate_buffers(void *handle,
oran_mixed_slot_t info = get_mixed_slot_info(&fh_config->frame_conf);
struct xran_prb_map dlPm = get_xran_prb_map_dl(fh_config);
struct xran_prb_map dlPmMixed = dlPm;
dlPmMixed.prbMap[0].nStartSymb = 0;
dlPmMixed.prbMap[0].numSymb = info.num_dlsym;
dlPmMixed.nPrbElm = info.num_dlsym;
for (int i=0; i < dlPmMixed.nPrbElm; i++){
struct xran_prb_elm *e = &dlPmMixed.prbMap[i];
e->nStartSymb = 0; // start symbol always 0 for DL
}
//dlPmMixed.prbMap[0].nStartSymb = 0;
//dlPmMixed.prbMap[0].numSymb = info.num_dlsym;
oran_cplane_prb_config dlConf = {
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
.mixed_slot_index = info.idx,
.slotMap = dlPm,
.mixedSlotMap = dlPmMixed,
};
#ifdef E_RELEASE
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
#elif defined F_RELEASE
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPmMixed, mtu);
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
#endif
oran_allocate_cplane_buffers(pi->instanceHandle,
bl->srccp,
bl->bufs.tx_prbmap,
xran_max_antenna_nr,
xran_max_sections_per_slot,
#ifdef F_RELEASE
mtu,
fh_config,
#endif
size_of_prb_map,
&dlConf);
@@ -377,8 +346,13 @@ static void oran_allocate_buffers(void *handle,
struct xran_prb_map ulPm = get_xran_prb_map_ul(fh_config);
struct xran_prb_map ulPmMixed = ulPm;
ulPmMixed.prbMap[0].nStartSymb = info.start_ulsym;
ulPmMixed.prbMap[0].numSymb = info.num_ulsym;
ulPmMixed.nPrbElm = info.num_ulsym; //1
for (int i=0; i < ulPmMixed.nPrbElm; i++){
struct xran_prb_elm *e = &ulPmMixed.prbMap[i];
e->nStartSymb = info.start_ulsym; // numSymb is always 1 for UL
}
//ulPmMixed.prbMap[0].nStartSymb = info.start_ulsym;
//ulPmMixed.prbMap[0].numSymb = info.num_ulsym;
oran_cplane_prb_config ulConf = {
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
.mixed_slot_index = info.idx,
@@ -390,10 +364,6 @@ static void oran_allocate_buffers(void *handle,
bl->bufs.rx_prbmap,
xran_max_antenna_nr,
xran_max_sections_per_slot,
#ifdef F_RELEASE
mtu,
fh_config,
#endif
size_of_prb_map,
&ulConf);
@@ -429,24 +399,39 @@ static void oran_allocate_buffers(void *handle,
}
}
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->pusch_tag);
xran_5g_prach_req(pi->instanceHandle, prach, prachdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag);
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->RxCbTag[0][0]);
xran_5g_prach_req(pi->instanceHandle, prach, prachdecomp, oai_xran_fh_rx_prach_callback, &portInstances->PrachCbTag[0][0]);
}
int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config)
int *oai_oran_initialize(const openair0_config_t *openair0_cfg)
{
int32_t xret = 0;
print_fh_init(xran_fh_init);
xret = xran_init(0, NULL, xran_fh_init, NULL, &gxran_handle);
struct xran_fh_init init = {0};
if (!set_fh_init(&init)) {
printf("could not read FHI 7.2/ORAN config\n");
return NULL;
}
print_fh_init(&init);
/* read all configuration before starting anything */
struct xran_fh_config xran_fh_config[XRAN_PORTS_NUM] = {0};
for (int32_t o_xu_id = 0; o_xu_id < init.xran_ports; o_xu_id++) {
if (!set_fh_config(o_xu_id, init.xran_ports, openair0_cfg, &xran_fh_config[o_xu_id])) {
printf("could not read FHI 7.2/RU-specific config\n");
return NULL;
}
print_fh_config(&xran_fh_config[o_xu_id]);
}
xret = xran_init(0, NULL, &init, NULL, &gxran_handle);
if (xret != XRAN_STATUS_SUCCESS) {
printf("xran_init failed %d\n", xret);
exit(-1);
}
/** process all the O-RU|O-DU for use case */
for (int32_t o_xu_id = 0; o_xu_id < xran_fh_init->xran_ports; o_xu_id++) {
print_fh_config(&xran_fh_config[o_xu_id]);
for (int32_t o_xu_id = 0; o_xu_id < init.xran_ports; o_xu_id++) {
xret = xran_open(gxran_handle, &xran_fh_config[o_xu_id]);
if (xret != XRAN_STATUS_SUCCESS) {
printf("xran_open failed %d\n", xret);
@@ -454,17 +439,8 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi
}
int sector = 0;
printf("Initialize ORAN port instance %d (%d) sector %d\n", o_xu_id, xran_fh_init->xran_ports, sector);
oran_port_instance_t *pi = &gPortInst[o_xu_id][sector];
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
pi->prach_tag = tag;
pi->pusch_tag = tag;
#ifdef E_RELEASE
LOG_W(PHY, "Please be aware that E release support will be removed by the end of January 2025. Instead, F release will be mandatory.\n");
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, &xran_fh_config[o_xu_id]);
#elif defined F_RELEASE
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
#endif
if ((xret = xran_reg_physide_cb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
printf("xran_reg_physide_cb failed %d\n", xret);

View File

@@ -50,13 +50,14 @@ typedef struct oran_port_instance_t {
void *instanceHandle;
//uint32_t dpdkPoolIndex[MAX_SW_XRAN_INTERFACE_NUM];
struct xran_cb_tag prach_tag;
struct xran_cb_tag pusch_tag;
struct xran_cb_tag RxCbTag[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR];
struct xran_cb_tag PrachCbTag[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR];
} oran_port_instance_t;
extern struct xran_fh_config gxran_fh_config[XRAN_PORTS_NUM];
extern void *gxran_handle;
int *oai_oran_initialize(struct xran_fh_init *fh_init, struct xran_fh_config *fh_config);
struct openair0_config;
int *oai_oran_initialize(const struct openair0_config *openair0_cfg);
#endif /* ORAN_INIT_H */

View File

@@ -31,14 +31,13 @@
#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"
#define ORAN_CONFIG_NETHPERPORT "eth_lines"
#define ORAN_CONFIG_NETHSPEED "eth_speed"
#define ORAN_CONFIG_DPDK_MEM_SIZE "dpdk_mem_size"
#define ORAN_CONFIG_DPDK_IOVA_MODE "dpdk_iova_mode"
#define ORAN_CONFIG_ECPRI_OWDM "owdm_enable"
// clang-format off
// TODO: PCI addr check
@@ -48,38 +47,23 @@
{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_DU_ADDR, "Ether addr of DU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \
{ORAN_CONFIG_RU_ADDR, "Ether addr of RU\n", PARAMFLAG_MANDATORY, .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_MTU, "MTU of Eth interface\n", PARAMFLAG_MANDATORY, .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}, \
{ORAN_CONFIG_NETHSPEED, "ethernet speed link\n", 0, .uptr=NULL, .defuintval=10, TYPE_UINT, 0}, \
{ORAN_CONFIG_DPDK_MEM_SIZE, "DPDK huge page pre-allocation in MiB\n", 0, .uptr=NULL, .defuintval=8192, TYPE_UINT, 0}, \
{ORAN_CONFIG_DPDK_IOVA_MODE, "DPDK IOVA mode\n", 0, .strptr=NULL, .defstrval="PA", TYPE_STRING, 0}, \
{ORAN_CONFIG_ECPRI_OWDM, "eCPRI One-Way Delay Measurements\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
}
// clang-format off
#define ORAN_GLOBALPARAMS_CHECK_DESC { \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"PA", "VA"}, {0, 1}, 2} }, \
{ .s5 = { NULL } }, \
}
// clang-format on
#define CONFIG_STRING_ORAN_FH "fh_config"
#define ORAN_FH_CONFIG_TADV_CP_DL "Tadv_cp_dl"
#define ORAN_FH_CONFIG_T2A_CP_DL "T2a_cp_dl"
#define ORAN_FH_CONFIG_T2A_CP_UL "T2a_cp_ul"
#define ORAN_FH_CONFIG_T2A_UP "T2a_up"
#define ORAN_FH_CONFIG_TA3 "Ta3"
#define ORAN_FH_CONFIG_T1A_CP_DL "T1a_cp_dl"
#define ORAN_FH_CONFIG_T1A_CP_UL "T1a_cp_ul"
#define ORAN_FH_CONFIG_T1A_UP "T1a_up"
@@ -91,12 +75,17 @@
// clang-format off
#define ORAN_FH_DESC { \
{ORAN_FH_CONFIG_TADV_CP_DL, "Tadv parameter of RU\n", PARAMFLAG_MANDATORY, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{ORAN_FH_CONFIG_T2A_CP_DL, "T2a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T2A_CP_UL, "T2a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T2A_UP, "T2a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_TA3, "Ta3" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_CP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{ORAN_FH_CONFIG_UP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{ORAN_FH_CONFIG_CP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=566, TYPE_UINT, 0}, \
{ORAN_FH_CONFIG_UP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=566, TYPE_UINT, 0}, \
}
// clang-format on
@@ -104,11 +93,13 @@
#define ORAN_RU_CONFIG_IQWIDTH "iq_width"
#define ORAN_RU_CONFIG_IQWIDTH_PRACH "iq_width_prach"
#define ORAN_RU_CONFIG_FFT_SIZE "fft_size"
// clang-format off
#define ORAN_RU_DESC {\
{ORAN_RU_CONFIG_IQWIDTH, "sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \
{ORAN_RU_CONFIG_IQWIDTH_PRACH, "PRACH sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \
{ORAN_RU_CONFIG_FFT_SIZE, "Size of FFT at RU\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=12, TYPE_UINT8, 0}, \
}
// clang-format on
@@ -124,4 +115,5 @@
}
// clang-format on
#endif /* ORAN_PARAMS_H */

View File

@@ -31,13 +31,8 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "openair1/PHY/defs_gNB.h"
#include "common/utils/threadPool/thread-pool.h"
#include "oaioran.h"
#include "oran-config.h"
// include the following file for VERSIONX, version of xran lib, to print it during
// startup. Only relevant for printing, if it ever makes problem, remove this
// line and the use of VERSIONX further below. It is relative to phy/fhi_lib/lib/api
#include "../../app/src/common.h"
typedef struct {
eth_state_t e;
@@ -175,14 +170,14 @@ int trx_oran_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
cap = (RRU_capabilities_t *)&rru_config_msg->msg[0];
cap->FH_fmt = OAI_IF4p5_only;
cap->num_bands = 1;
cap->band_list[0] = 78;
cap->band_list[0] = 257; //78;
// cap->num_concurrent_bands = 1; component carriers
cap->nb_rx[0] = 1; // device->openair0_cfg->rx_num_channels;
cap->nb_tx[0] = 1; // device->openair0_cfg->tx_num_channels;
cap->nb_rx[0] = 2; // device->openair0_cfg->rx_num_channels;
cap->nb_tx[0] = 2; // device->openair0_cfg->tx_num_channels;
cap->max_pdschReferenceSignalPower[0] = -27;
cap->max_rxgain[0] = 90;
cap->N_RB_DL[0] = 106;
cap->N_RB_UL[0] = 106;
cap->N_RB_DL[0] = 66;
cap->N_RB_UL[0] = 66;
s->capabilities_sent = 1;
@@ -202,9 +197,27 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
ru_info.rxdataF = ru->common.rxdataF;
ru_info.prach_buf = ru->prach_rxsigF[0]; // index: [prach_oca][ant_id]
PHY_VARS_gNB **gNB_list = ru->gNB_list, *gNB;
// if (ru->num_gNB == 1){
//gNB = gNB_list[0];
//printf(" #################################### COPY THE LIST OF BEAMS\n\n");
//ru_info.beamID = gNB->common_vars.beam_id;
//printf("slot %d beam %d\n", *slot, ru_info.beamID[0][*slot*14]);
/*for (int i=0;i<2;i++){
for (int s=0; s<80;s++){
printf("#slot %d port %d beam %u\n", s, i, ru_info.beamID[i][s]);
}
}*/
//}
RU_proc_t *proc = &ru->proc;
extern int sl_ahead;
int f, sl;
LOG_D(PHY, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
start_meas(&ru->rx_fhaul);
int ret = xran_fh_rx_read_slot(&ru_info, &f, &sl);
@@ -214,12 +227,32 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX function \n", f, sl);
}
int slots_per_frame = 10 << (ru->openair0_cfg.nr_scs_for_raster);
int slots_per_frame = 80; // 10 << (ru->openair0_cfg.nr_scs_for_raster);
proc->tti_rx = sl;
proc->frame_rx = f;
proc->tti_tx = (sl + sl_ahead) % slots_per_frame;
proc->frame_tx = (sl > (slots_per_frame - 1 - sl_ahead)) ? (f + 1) & 1023 : f;
if (ru->common.beam_id){
//ru_info.beamID = ru->common.beam_id; // ru->common.beam_id[i][slot_tx * fp->symbols_per_slot] //14 hardcoed for now
gNB = gNB_list[0];
for (int i = 0; i < 80*14; i++) //80 hardcoded for now
{
if (ru->common.beam_id[0][i] != -1){
nfapi_nr_dig_beam_t *beam = &gNB->gNB_config.dbt_config.dig_beam_list[ru->common.beam_id[0][i]];
//printf("before: ru->common.beam_id[0][%d] %d slot %d symbol %d \n", i, ru->common.beam_id[0][i], proc->tti_tx, i%14);
ru_info.beamID[0][i] = beam->txru_list[0].dig_beam_weight_Re;
//if (i%14 ==0 && ru->common.beam_id[0][i] == 0)
//printf("slot %d symbol %d beam index %d beam RU %d\n", proc->tti_tx , i%14, ru->common.beam_id[0][i], ru_info.beamID[0][i]);
}else{
ru_info.beamID[0][i] = 1;
//printf("slot %d symbol %d beam index %d beam RU %d\n", proc->tti_tx , i%14, ru->common.beam_id[0][i], ru_info.beamID[0][i]);
}
}
update_beams_ctx(ru_info.beamID);
}
//printf("received %d.%d, expected %d.%d\n", proc->frame_rx,proc->tti_rx,*frame,*slot);
if (proc->first_rx == 0) {
if (proc->tti_rx != *slot) {
LOG_E(PHY,
@@ -240,12 +273,14 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
*slot);
*frame = proc->frame_rx;
}
} else {
proc->first_rx = 0;
LOG_I(PHY, "before adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
*frame = proc->frame_rx;
*slot = proc->tti_rx;
LOG_I(PHY, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
}
}
@@ -311,22 +346,14 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d
eth->oran_priv = NULL; // define_oran_pointer();
device->priv = eth;
device->openair0_cfg = &openair0_cfg[0];
eth->last_msg = (rru_config_msg_type_t)-1;
LOG_I(HW, "Initializing O-RAN 7.2 FH interface through xran library (compiled against headers of %s)\n", VERSIONX);
printf("ORAN: %s\n", __FUNCTION__);
initNotifiedFIFO(&oran_sync_fifo);
struct xran_fh_init fh_init = {0};
struct xran_fh_config fh_config[XRAN_PORTS_NUM] = {0};
#ifndef OAI_MPLANE_SUPPORT
bool success = get_xran_config(openair0_cfg, &fh_init, fh_config);
AssertFatal(success, "cannot get configuration for xran\n");
#else
/* TODO: M-plane integration */
#endif
eth->oran_priv = oai_oran_initialize(&fh_init, fh_config);
eth->oran_priv = oai_oran_initialize(openair0_cfg);
AssertFatal(eth->oran_priv != NULL, "can not initialize fronthaul");
// create message queues for ORAN sync
return 0;

View File

@@ -43,10 +43,12 @@ typedef struct ru_info_s {
// Needed for Prach
int16_t **prach_buf;
int beamID[2][1120]; // 80 hardcoded for now
} ru_info_t;
int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot);
int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp);
int update_beams_ctx(int beamID[2][1120]);
int compute_xran_statistics();

View File

@@ -11,7 +11,7 @@ gNBs =
// 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 }) });
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1 }) });
nr_cellid = 12345678L;