mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 12:40:28 +00:00
Compare commits
1 Commits
more_time_
...
liteon_dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a435fe341 |
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user