mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-17 06:30:31 +00:00
Compare commits
10 Commits
develop
...
nr-oru_dma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7ed7bfcfa | ||
|
|
fb50be508d | ||
|
|
7b538f8fad | ||
|
|
dc7ec0aafd | ||
|
|
fc3f253a60 | ||
|
|
443eda642e | ||
|
|
85f40d0188 | ||
|
|
f9b45aee6a | ||
|
|
3e81a8a372 | ||
|
|
a54b0f84ad |
@@ -1836,7 +1836,13 @@ add_executable(nr-oru
|
||||
${OPENAIR_DIR}/openair1/SCHED_NR/nr_ru_procedures.c
|
||||
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
|
||||
${OPENAIR_DIR}/executables/main_nr_ru.c
|
||||
${OPENAIR_DIR}/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
|
||||
${OPENAIR_DIR}/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c
|
||||
${OPENAIR_DIR}/openair1/PHY/NR_TRANSPORT/nr_prach.c
|
||||
)
|
||||
|
||||
target_compile_definitions(nr-oru PRIVATE NR_ORU)
|
||||
|
||||
target_link_libraries(nr-oru PRIVATE
|
||||
UTIL NR_PHY_RU PHY_NR shlib_loader dl
|
||||
radio_common softmodem_common)
|
||||
@@ -1946,6 +1952,55 @@ target_link_libraries(nr-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
|
||||
|
||||
# ======================================================================
|
||||
# 🚀 HACK: DOCA DMA ACCELERATION FOR FRONTHAUL (nr-oru & nr-softmodem)
|
||||
# ======================================================================
|
||||
|
||||
option(ENABLE_DOCA_DMA "Activate DOCA DMA driver for Fronthaul 7.2" OFF)
|
||||
|
||||
if (ENABLE_DOCA_DMA)
|
||||
message(STATUS "🚀 [HACK] Integrating DOCA from /opt/mellanox/doca")
|
||||
|
||||
add_definitions(-DENABLE_DOCA_DMA)
|
||||
|
||||
# 1. 定义基础路径
|
||||
set(DOCA_BASE "/opt/mellanox/doca")
|
||||
set(DOCA_LIB_PATH "${DOCA_BASE}/lib/aarch64-linux-gnu")
|
||||
|
||||
# 2. 直接指定库文件的绝对路径(不再用 -l 参数,而是直接用文件路径)
|
||||
# 这样链接器就没有任何借口说找不到文件了
|
||||
set(DOCA_LIBS
|
||||
"${DOCA_LIB_PATH}/libdoca_common.so"
|
||||
"${DOCA_LIB_PATH}/libdoca_dma.so"
|
||||
"${DOCA_LIB_PATH}/libdoca_argp.so"
|
||||
)
|
||||
|
||||
# 3. 头文件路径还是要有的
|
||||
include_directories(
|
||||
"${DOCA_BASE}/include"
|
||||
"${DOCA_BASE}/samples"
|
||||
"${DOCA_BASE}/samples/doca_dma"
|
||||
)
|
||||
|
||||
# 4. 辅助源码
|
||||
set(DOCA_HELPER_SRCS
|
||||
"${DOCA_BASE}/samples/common.c"
|
||||
"${DOCA_BASE}/samples/doca_dma/dma_common.c"
|
||||
)
|
||||
|
||||
# 5. 链接到目标
|
||||
target_sources(nr-oru PRIVATE ${DOCA_HELPER_SRCS})
|
||||
target_sources(nr-softmodem PRIVATE ${DOCA_HELPER_SRCS})
|
||||
|
||||
target_link_libraries(nr-oru PRIVATE ${DOCA_LIBS})
|
||||
target_link_libraries(nr-softmodem PRIVATE ${DOCA_LIBS})
|
||||
|
||||
# 如果有这个子库,也强行挂载
|
||||
if (TARGET oai_xrandev)
|
||||
target_link_libraries(oai_xrandev PRIVATE ${DOCA_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
###################################"
|
||||
# Addexecutables for tests
|
||||
####################################
|
||||
|
||||
2264
cmake_targets/tools/oran_fhi_integration_patches/F/bf3_oru_F.patch
Normal file
2264
cmake_targets/tools/oran_fhi_integration_patches/F/bf3_oru_F.patch
Normal file
File diff suppressed because it is too large
Load Diff
2171
doc/BlueField3_DPU_nroru_FH7p2_implementation.md
Normal file
2171
doc/BlueField3_DPU_nroru_FH7p2_implementation.md
Normal file
File diff suppressed because it is too large
Load Diff
1
doc/images/nr-oru_as_odu_fh7p2_scratch.svg
Normal file
1
doc/images/nr-oru_as_odu_fh7p2_scratch.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 20 KiB |
@@ -176,6 +176,8 @@ int main(int argc, char **argv)
|
||||
init_NR_RU(config_get_if(), NULL);
|
||||
|
||||
RU_t *ru = RC.ru[0];
|
||||
|
||||
start_NR_RU();
|
||||
|
||||
while (oai_exit == 0)
|
||||
sleep(1);
|
||||
|
||||
10
executables/nr-oru.c
Normal file
10
executables/nr-oru.c
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Specific functions for nr-oru executables
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
#include <sys/sysinfo.h>
|
||||
#include <math.h>
|
||||
|
||||
//socket handshake
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/system.h"
|
||||
@@ -52,6 +58,9 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1};
|
||||
|
||||
static void NRRCconfig_RU(configmodule_interface_t *cfg);
|
||||
|
||||
void print_shadow_gnb_config(nfapi_nr_config_request_scf_t *cfg);
|
||||
|
||||
void nroru_init_nr_transport(PHY_VARS_gNB *gNB);
|
||||
/*************************************************************/
|
||||
/* Southbound Fronthaul functions, RCC/RAU */
|
||||
|
||||
@@ -85,6 +94,23 @@ void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
|
||||
}
|
||||
|
||||
void fh_if4p5_south_out_dma_host(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
printf("We are now in fh_if4p5_south_out_dma! HOSTTTTTTT\n");
|
||||
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
|
||||
|
||||
if ((nr_slot_select(&ru->config, ru->proc.frame_tx, ru->proc.tti_tx) & NR_DOWNLINK_SLOT) > 0)
|
||||
send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
|
||||
}
|
||||
|
||||
void fh_if4p5_south_out_dma_device(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
printf("************************\nWe are now in fh_if4p5_south_out_dma! DEVICEEEEEEEE\n************************\n");
|
||||
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
|
||||
|
||||
if ((nr_slot_select(&ru->config, ru->proc.frame_tx, ru->proc.tti_tx) & NR_DOWNLINK_SLOT) > 0)
|
||||
send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
|
||||
}
|
||||
/*************************************************************/
|
||||
/* Input Fronthaul from south RCC/RAU */
|
||||
|
||||
@@ -239,6 +265,126 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *slot) {
|
||||
} while (symbol_mask > 0 || prach_rx > 0); // haven't received all PUSCH symbols and PRACH information
|
||||
}
|
||||
|
||||
void fh_if4p5_south_in_dma_host(RU_t *ru,
|
||||
int *frame,
|
||||
int *slot) {
|
||||
|
||||
printf("We are now in fh_if4p5_south_in_dma. HOSTTTTTT!\n");
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int f,sl;
|
||||
uint16_t packet_type;
|
||||
uint32_t symbol_number=0;
|
||||
uint32_t symbol_mask_full=0;
|
||||
|
||||
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
|
||||
recv_IF4p5(ru, &f, &sl, &packet_type, &symbol_number);
|
||||
|
||||
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sl] = proc->symbol_mask[sl] | (1<<symbol_number);
|
||||
else if (packet_type == IF4p5_PULTICK) {
|
||||
if ((proc->first_rx == 0) && (f != *frame))
|
||||
LOG_E(PHY, "rx_fh_if4p5: PULTICK received frame %d != expected %d\n", f, *frame);
|
||||
|
||||
if ((proc->first_rx == 0) && (sl != *slot))
|
||||
LOG_E(PHY, "rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n", sl, *slot, proc->first_rx);
|
||||
|
||||
break;
|
||||
} else if (packet_type == IF4p5_PRACH) {
|
||||
// nothing in RU for RAU
|
||||
}
|
||||
|
||||
LOG_D(PHY,"rx_fh_if4p5: subframe %d symbol mask %x\n",*slot,proc->symbol_mask[sl]);
|
||||
} while(proc->symbol_mask[sl] != symbol_mask_full);
|
||||
|
||||
//caculate timestamp_rx, timestamp_tx based on frame and subframe
|
||||
proc->tti_rx = sl;
|
||||
proc->frame_rx = f;
|
||||
proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + get_samples_slot_timestamp(fp, proc->tti_rx);
|
||||
// proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe);
|
||||
proc->tti_tx = (sl+ru->sl_ahead)%fp->slots_per_frame;
|
||||
proc->frame_tx = (sl > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (f + 1) & 1023 : f;
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
if (proc->tti_rx != *slot) {
|
||||
LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*slot);
|
||||
exit_fun("Exiting");
|
||||
}
|
||||
|
||||
if (proc->frame_rx != *frame) {
|
||||
LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
|
||||
exit_fun("Exiting");
|
||||
}
|
||||
} else {
|
||||
proc->first_rx = 0;
|
||||
*frame = proc->frame_rx;
|
||||
*slot = proc->tti_rx;
|
||||
}
|
||||
|
||||
proc->symbol_mask[proc->tti_rx] = 0;
|
||||
LOG_D(PHY,"RU %d: fh_if4p5_south_in sleeping ...\n",ru->idx);
|
||||
}
|
||||
|
||||
void fh_if4p5_south_in_dma_device(RU_t *ru,
|
||||
int *frame,
|
||||
int *slot) {
|
||||
|
||||
printf("************************\nWe are now in fh_if4p5_south_in_dma! DEVICEEEEEEEE\n************************\n");
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int f,sl;
|
||||
uint16_t packet_type;
|
||||
uint32_t symbol_number=0;
|
||||
uint32_t symbol_mask_full=0;
|
||||
|
||||
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
|
||||
recv_IF4p5(ru, &f, &sl, &packet_type, &symbol_number);
|
||||
|
||||
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sl] = proc->symbol_mask[sl] | (1<<symbol_number);
|
||||
else if (packet_type == IF4p5_PULTICK) {
|
||||
if ((proc->first_rx == 0) && (f != *frame))
|
||||
LOG_E(PHY, "rx_fh_if4p5: PULTICK received frame %d != expected %d\n", f, *frame);
|
||||
|
||||
if ((proc->first_rx == 0) && (sl != *slot))
|
||||
LOG_E(PHY, "rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n", sl, *slot, proc->first_rx);
|
||||
|
||||
break;
|
||||
} else if (packet_type == IF4p5_PRACH) {
|
||||
// nothing in RU for RAU
|
||||
}
|
||||
|
||||
LOG_D(PHY,"rx_fh_if4p5_dma_device: subframe %d symbol mask %x\n",*slot,proc->symbol_mask[sl]);
|
||||
} while(proc->symbol_mask[sl] != symbol_mask_full);
|
||||
|
||||
//caculate timestamp_rx, timestamp_tx based on frame and subframe
|
||||
proc->tti_rx = sl;
|
||||
proc->frame_rx = f;
|
||||
proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + get_samples_slot_timestamp(fp, proc->tti_rx);
|
||||
// proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe);
|
||||
proc->tti_tx = (sl+ru->sl_ahead)%fp->slots_per_frame;
|
||||
proc->frame_tx = (sl > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (f + 1) & 1023 : f;
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
if (proc->tti_rx != *slot) {
|
||||
LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*slot);
|
||||
exit_fun("Exiting");
|
||||
}
|
||||
|
||||
if (proc->frame_rx != *frame) {
|
||||
LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
|
||||
exit_fun("Exiting");
|
||||
}
|
||||
} else {
|
||||
proc->first_rx = 0;
|
||||
*frame = proc->frame_rx;
|
||||
*slot = proc->tti_rx;
|
||||
}
|
||||
|
||||
proc->symbol_mask[proc->tti_rx] = 0;
|
||||
LOG_D(PHY,"RU %d: fh_if4p5_south_in sleeping ...\n",ru->idx);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
/* Input Fronthaul from North RRU */
|
||||
|
||||
@@ -831,23 +977,45 @@ void *ru_thread(void *param)
|
||||
if (ru->nr_start_if) {
|
||||
LOG_I(PHY, "starting transport\n");
|
||||
ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params);
|
||||
LOG_I(PHY, "testing1\n");
|
||||
AssertFatal(ret == 0, "RU %u: openair0_transport_init() ret %d: cannot initialize transport protocol\n", ru->idx, ret);
|
||||
|
||||
if (ru->ifdevice.get_internal_parameter != NULL) {
|
||||
/* it seems the device can "overwrite" (request?) to set the callbacks
|
||||
* for fh_south_in()/fh_south_out() differently */
|
||||
void *t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in");
|
||||
if (t != NULL)
|
||||
ru->fh_south_in = t;
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out");
|
||||
if (t != NULL)
|
||||
ru->fh_south_out = t;
|
||||
LOG_I(PHY, "testing2\n");
|
||||
void *t = NULL;
|
||||
|
||||
// --- DMA_DEVICE mode ---
|
||||
if (ru->if_south == REMOTE_IF4p5_DMA_DEVICE) {
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in_dma_device");
|
||||
if (t != NULL) { ru->fh_south_in = t; LOG_I(PHY, "testing2.1 (DMA DEVICE IN)\n"); }
|
||||
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out_dma_device");
|
||||
if (t != NULL) { ru->fh_south_out = t; LOG_I(PHY, "testing2.2 (DMA DEVICE OUT)\n"); }
|
||||
}
|
||||
// --- DMA_HOST ---
|
||||
else if (ru->if_south == REMOTE_IF4p5_DMA_HOST) {
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in_dma_host");
|
||||
if (t != NULL) { ru->fh_south_in = t; LOG_I(PHY, "testing2.1 (DMA HOST IN)\n"); }
|
||||
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out_dma_host");
|
||||
if (t != NULL) { ru->fh_south_out = t; LOG_I(PHY, "testing2.2 (DMA HOST OUT)\n"); }
|
||||
}
|
||||
// --- REMOTE_IF4p5 ---
|
||||
else {
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in");
|
||||
if (t != NULL) { ru->fh_south_in = t; LOG_I(PHY, "testing2.1 (STANDARD IN)\n"); }
|
||||
|
||||
t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out");
|
||||
if (t != NULL) { ru->fh_south_out = t; LOG_I(PHY, "testing2.2 (STANDARD OUT)\n"); }
|
||||
}
|
||||
|
||||
} else {
|
||||
malloc_IF4p5_buffer(ru);
|
||||
}
|
||||
|
||||
int cpu = sched_getcpu();
|
||||
if (ru->ru_thread_core > -1 && cpu != ru->ru_thread_core) {
|
||||
LOG_I(PHY, "testing3\n");
|
||||
/* we start the ru_thread using threadCreate(), which already sets CPU
|
||||
* affinity; let's force it here again as per feature request #732 */
|
||||
cpu_set_t cpuset;
|
||||
@@ -960,8 +1128,14 @@ void *ru_thread(void *param)
|
||||
// do RX front-end processing (frequency-shift, dft) if needed
|
||||
int slot_type = nr_slot_select(&ru->config, proc->frame_rx, proc->tti_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
if (!wait_free_rx_tti(&gNB->L1_rx_out, rx_tti_busy, proc->frame_rx, proc->tti_rx))
|
||||
break; // nothing to wait for: we have to stop
|
||||
|
||||
if (ru->if_south == REMOTE_IF4p5_DMA_DEVICE) {
|
||||
LOG_D(PHY, "Standalone O-RU mode: bypass wait_free_rx_tti for frame %d, slot %d\n",
|
||||
proc->frame_rx, proc->tti_rx);
|
||||
} else {
|
||||
if (!wait_free_rx_tti(&gNB->L1_rx_out, rx_tti_busy, proc->frame_rx, proc->tti_rx))
|
||||
break; // nothing to wait for: we have to stop
|
||||
}
|
||||
if (ru->feprx) {
|
||||
ru->feprx(ru,proc->tti_rx);
|
||||
LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
|
||||
@@ -990,16 +1164,16 @@ void *ru_thread(void *param)
|
||||
} // end if (ru->feprx)
|
||||
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
|
||||
notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
|
||||
resTx->key = proc->tti_tx;
|
||||
processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx);
|
||||
*syncMsgTx = (processingData_L1tx_t){.gNB = gNB,
|
||||
.frame = proc->frame_tx,
|
||||
.slot = proc->tti_tx,
|
||||
.frame_rx = proc->frame_rx,
|
||||
.slot_rx = proc->tti_rx,
|
||||
.timestamp_tx = proc->timestamp_tx};
|
||||
pushNotifiedFIFO(&gNB->L1_tx_out, resTx);
|
||||
// notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
|
||||
// resTx->key = proc->tti_tx;
|
||||
// processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx);
|
||||
// *syncMsgTx = (processingData_L1tx_t){.gNB = gNB,
|
||||
// .frame = proc->frame_tx,
|
||||
// .slot = proc->tti_tx,
|
||||
// .frame_rx = proc->frame_rx,
|
||||
// .slot_rx = proc->tti_rx,
|
||||
// .timestamp_tx = proc->timestamp_tx};
|
||||
// pushNotifiedFIFO(&gNB->L1_tx_out, resTx);
|
||||
}
|
||||
|
||||
ru_thread_status = 0;
|
||||
@@ -1171,6 +1345,42 @@ void set_function_spec_param(RU_t *ru)
|
||||
ru->ifdevice.eth_params = &ru->eth_params;
|
||||
break;
|
||||
|
||||
case REMOTE_IF4p5_DMA_HOST:
|
||||
ru->do_prach = 0;
|
||||
ru->feprx = NULL; // DFTs
|
||||
ru->feptx_prec = nr_feptx_prec; // Precoding operation
|
||||
ru->feptx_ofdm = NULL; // no OFDM mod
|
||||
ru->fh_south_in = fh_if4p5_south_in_dma_host; // synchronous IF4p5 reception
|
||||
ru->fh_south_out = fh_if4p5_south_out_dma_host; // synchronous IF4p5 transmission
|
||||
ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in_dma_host : NULL; // asynchronous UL if synch_to_other
|
||||
ru->fh_north_out = NULL;
|
||||
ru->fh_north_asynch_in = NULL;
|
||||
ru->start_rf = NULL; // no local RF
|
||||
ru->stop_rf = NULL;
|
||||
ru->start_write_thread = NULL;
|
||||
ru->nr_start_if = nr_start_if; // need to start if interface for IF4p5
|
||||
ru->ifdevice.host_type = RAU_HOST;
|
||||
ru->ifdevice.eth_params = &ru->eth_params;
|
||||
break;
|
||||
|
||||
case REMOTE_IF4p5_DMA_DEVICE:
|
||||
ru->do_prach = 0;
|
||||
ru->feprx = NULL; // DFTs
|
||||
ru->feptx_prec = nr_feptx_prec; // Precoding operation
|
||||
ru->feptx_ofdm = NULL; // no OFDM mod
|
||||
ru->fh_south_in = fh_if4p5_south_in_dma_device; // synchronous IF4p5 reception
|
||||
ru->fh_south_out = fh_if4p5_south_out_dma_device; // synchronous IF4p5 transmission
|
||||
ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in_dma_device : NULL; // asynchronous UL if synch_to_other
|
||||
ru->fh_north_out = NULL;
|
||||
ru->fh_north_asynch_in = NULL;
|
||||
ru->start_rf = NULL; // no local RF
|
||||
ru->stop_rf = NULL;
|
||||
ru->start_write_thread = NULL;
|
||||
ru->nr_start_if = nr_start_if; // need to start if interface for IF4p5
|
||||
ru->ifdevice.host_type = RAU_HOST;
|
||||
ru->ifdevice.eth_params = &ru->eth_params;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south);
|
||||
break;
|
||||
@@ -1196,6 +1406,151 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
|
||||
ru->ts_offset = 0;
|
||||
// use gNB_list[0] as a reference for RU frame parameters
|
||||
// NOTE: multiple CC_id are not handled here yet!
|
||||
|
||||
if (ru->if_south == REMOTE_IF4p5_DMA_DEVICE) {
|
||||
if(RC.nb_nr_L1_inst == 0){
|
||||
LOG_I(PHY, "No local L1 instance in nr-oru. Setting sync_var to 0\n");
|
||||
sync_var = 0;
|
||||
}
|
||||
LOG_I(PHY, "DMA [Device]: Initializing Control Plane handshake with Host at %s:%d\n",
|
||||
ru->dma_ctrl_ip, ru->dma_ctrl_port);
|
||||
|
||||
int sock = 0;
|
||||
struct sockaddr_in serv_addr;
|
||||
dma_sync_config_t sync_cfg;
|
||||
|
||||
// 1. create Socket
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
AssertFatal(0, "DMA: Socket creation error \n");
|
||||
}
|
||||
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(ru->dma_ctrl_port);
|
||||
|
||||
// 2. shift IP address
|
||||
if (inet_pton(AF_INET, ru->dma_ctrl_ip, &serv_addr.sin_addr) <= 0) {
|
||||
AssertFatal(0, "DMA: Invalid address/ Address not supported \n");
|
||||
}
|
||||
|
||||
// 3. connect to Host
|
||||
LOG_I(PHY, "DMA: Waiting for Host to come online...\n");
|
||||
while (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
|
||||
LOG_D(PHY, "DMA: Connection failed, retrying in 1s...\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// 4. receive package
|
||||
int expected_size = sizeof(dma_sync_config_t);
|
||||
int total_read = 0;
|
||||
char *ptr = (char *)&sync_cfg;
|
||||
|
||||
LOG_I(PHY, "DMA: Waiting for config from Host (Expected: %d bytes)...\n", expected_size);
|
||||
|
||||
while (total_read < expected_size) {
|
||||
int n = read(sock, ptr + total_read, expected_size - total_read);
|
||||
if (n <= 0) {
|
||||
perror("read");
|
||||
break;
|
||||
}
|
||||
total_read += n;
|
||||
LOG_I(PHY, "DMA: Received %d bytes chunk (Total: %d/%d)\n", n, total_read, expected_size);
|
||||
}
|
||||
|
||||
if (total_read == expected_size && sync_cfg.magic == 0x0A1D3A00) {
|
||||
LOG_I(PHY, "✅ DMA: Handshake SUCCESS! All %d bytes received.\n", total_read);
|
||||
|
||||
// rebuild shadow gNB
|
||||
|
||||
// A. make sure RC.gNB is initialized
|
||||
if (RC.gNB == NULL) {
|
||||
RC.gNB = (PHY_VARS_gNB **)malloc(sizeof(PHY_VARS_gNB *));
|
||||
RC.gNB[0] = (PHY_VARS_gNB *)calloc(1, sizeof(PHY_VARS_gNB));
|
||||
}
|
||||
|
||||
// B. match RU and shadow gNB
|
||||
ru->gNB_list[0] = RC.gNB[0];
|
||||
ru->num_gNB = 1;
|
||||
nfapi_nr_config_request_scf_t *gNB_cfg_dma_d = &RC.gNB[0]->gNB_config;
|
||||
|
||||
// --- 1. basic setting
|
||||
gNB_cfg_dma_d->cell_config.frame_duplex_type.value = sync_cfg.config__cell_config__frame_duplex_type__value;
|
||||
gNB_cfg_dma_d->cell_config.frame_duplex_type.tl.tag = 0x100D;
|
||||
|
||||
// --- 2. SSB config ---
|
||||
gNB_cfg_dma_d->ssb_table.ssb_mask_list[0].ssb_mask.value = sync_cfg.config__ssb_table__ssb_mask_list_0__ssb_mask__value;
|
||||
gNB_cfg_dma_d->ssb_table.ssb_mask_list[1].ssb_mask.value = sync_cfg.config__ssb_table__ssb_mask_list_1__ssb_mask__value;
|
||||
gNB_cfg_dma_d->ssb_table.case_v3.value = sync_cfg.config__ssb_table__case_v3__value;
|
||||
gNB_cfg_dma_d->ssb_config.scs_common.value = sync_cfg.config__ssb_config__scs_common__value;
|
||||
|
||||
// --- 3. PRACH config ---
|
||||
gNB_cfg_dma_d->prach_config.prach_ConfigurationIndex.value = sync_cfg.config__prach_config__prach_ConfigurationIndex__value;
|
||||
gNB_cfg_dma_d->prach_config.num_prach_fd_occasions.value = sync_cfg.config__prach_config__num_prach_fd_occasions__value;
|
||||
gNB_cfg_dma_d->prach_config.prach_sequence_length.value = sync_cfg.config__prach_config__prach_sequence_length__value;
|
||||
gNB_cfg_dma_d->prach_config.prach_ConfigurationIndex.tl.tag = 0x1029; // or using MACRO NFAPI_NR_CONFIG_PRACH_CONFIGURATION_INDEX_TAG
|
||||
gNB_cfg_dma_d->prach_config.num_prach_fd_occasions.tl.tag = 0x102C;
|
||||
gNB_cfg_dma_d->prach_config.prach_sequence_length.tl.tag = 0x102E;
|
||||
|
||||
gNB_cfg_dma_d->prach_config.num_prach_fd_occasions_list =
|
||||
(nfapi_nr_num_prach_fd_occasions_t *)calloc(1, sizeof(nfapi_nr_num_prach_fd_occasions_t));
|
||||
gNB_cfg_dma_d->prach_config.num_prach_fd_occasions_list[0].k1.value = sync_cfg.config__prach_config__num_prach_fd_occasions_list_0__k1__value;
|
||||
|
||||
// --- 4. Carrier config ---
|
||||
int scs = gNB_cfg_dma_d->ssb_config.scs_common.value;
|
||||
gNB_cfg_dma_d->carrier_config.dl_grid_size[scs].value = sync_cfg.config__carrier_config__dl_grid_size__value;
|
||||
gNB_cfg_dma_d->carrier_config.ul_grid_size[scs].value = sync_cfg.config__carrier_config__ul_grid_size__value;
|
||||
gNB_cfg_dma_d->carrier_config.num_rx_ant.value = sync_cfg.config__carrier_config__num_rx_ant__value;
|
||||
gNB_cfg_dma_d->carrier_config.num_tx_ant.value = sync_cfg.config__carrier_config__num_tx_ant__value;
|
||||
gNB_cfg_dma_d->carrier_config.dl_frequency.value = sync_cfg.config__carrier_config__dl_frequency__value;
|
||||
gNB_cfg_dma_d->carrier_config.uplink_frequency.value = sync_cfg.config__carrier_config__ul_frequency__value;
|
||||
gNB_cfg_dma_d->carrier_config.dl_frequency.tl.tag = NFAPI_NR_CONFIG_DL_FREQUENCY_TAG;
|
||||
gNB_cfg_dma_d->carrier_config.uplink_frequency.tl.tag = NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG;
|
||||
|
||||
for(int i = 0; i < 5; i++){
|
||||
gNB_cfg_dma_d->carrier_config.dl_k0[i].value = sync_cfg.config__carrier_config__dl_k0__value[i];
|
||||
gNB_cfg_dma_d->carrier_config.ul_k0[i].value = sync_cfg.config__carrier_config__ul_k0__value[i];
|
||||
}
|
||||
|
||||
// --- 5. TDD Table
|
||||
gNB_cfg_dma_d->tdd_table.tdd_period.value = sync_cfg.config__tdd_table__tdd_period__value;
|
||||
gNB_cfg_dma_d->tdd_table.tdd_period.tl.tag = sync_cfg.config__tdd_table__tdd_period__tl__tag;
|
||||
|
||||
//
|
||||
//RC.gNB[0]->ofdm_offset_divisor = sync_cfg.ofdm_offset_divisor;
|
||||
|
||||
int max_slots_to_map = 10 * (1 << gNB_cfg_dma_d->ssb_config.scs_common.value);
|
||||
// allocate Slot
|
||||
gNB_cfg_dma_d->tdd_table.max_tdd_periodicity_list =
|
||||
(nfapi_nr_max_tdd_periodicity_t *)calloc(max_slots_to_map, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
|
||||
for (int slot = 0; slot < max_slots_to_map; slot++) {
|
||||
// allocate symbols
|
||||
gNB_cfg_dma_d->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list =
|
||||
(nfapi_nr_max_num_of_symbol_per_slot_t *)calloc(14, sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
|
||||
|
||||
for (int sym = 0; sym < 14; sym++) {
|
||||
int flat_idx = slot * 14 + sym;
|
||||
gNB_cfg_dma_d->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value =
|
||||
sync_cfg.config__tdd_table__max_tdd_periodicity_list__max_num_of_symbol_per_slot_list__slot_config__value[flat_idx];
|
||||
|
||||
gNB_cfg_dma_d->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.tl.tag =
|
||||
NFAPI_NR_CONFIG_SLOT_CONFIG_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(PHY, "✅ DMA: Shadow gNB configuration tree successfully rebuilt!\n");
|
||||
|
||||
print_shadow_gnb_config(&RC.gNB[0]->gNB_config);
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
AssertFatal(0, "❌ DMA: Handshake Failed! \n [Detail]: Read: %d bytes, Expected: %d bytes\n[Magic]: Received: 0x%08X, Expected: 0x0A1D3A00\n", total_read, sizeof(dma_sync_config_t), sync_cfg.magic);
|
||||
}
|
||||
|
||||
|
||||
close(sock);
|
||||
LOG_I(PHY, "DMA: Control Plane handshake completed. Shadow gNB is ready.\n");
|
||||
}
|
||||
|
||||
if (ru->num_gNB > 0) {
|
||||
LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p RC.gNB[0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], RC.gNB[0], ru->rf_config_file);
|
||||
@@ -1229,8 +1584,140 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ru->gNB_list[0]){
|
||||
if (ru->if_south == REMOTE_IF4p5_DMA_DEVICE) {
|
||||
for (int i = 0; i < ru->num_gNB; i++) {
|
||||
gNB0 = ru->gNB_list[i];
|
||||
init_nr_prach(gNB0);
|
||||
nroru_init_nr_transport(gNB0);
|
||||
}
|
||||
}
|
||||
}
|
||||
set_function_spec_param(ru);
|
||||
init_RU_proc(ru);
|
||||
|
||||
if (ru->if_south == REMOTE_IF4p5_DMA_HOST) {
|
||||
LOG_I(PHY, "Host [Master]: Initializing Control Plane server at %s:%d\n",
|
||||
ru->dma_ctrl_ip, ru->dma_ctrl_port);
|
||||
|
||||
int server_fd, new_socket;
|
||||
struct sockaddr_in address;
|
||||
int opt = 1;
|
||||
int addrlen = sizeof(address);
|
||||
|
||||
// 1. create Socket
|
||||
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
|
||||
AssertFatal(0, "Host: Socket failed\n");
|
||||
}
|
||||
|
||||
// 2. select port
|
||||
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
|
||||
AssertFatal(0, "Host: setsockopt failed\n");
|
||||
}
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(ru->dma_ctrl_port);
|
||||
|
||||
// bind IP
|
||||
if (inet_pton(AF_INET, ru->dma_ctrl_ip, &address.sin_addr) <= 0) {
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
// 3. Bind & Listen
|
||||
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
|
||||
AssertFatal(0, "Host: Bind failed at %s:%d\n", ru->dma_ctrl_ip, ru->dma_ctrl_port);
|
||||
}
|
||||
if (listen(server_fd, 3) < 0) {
|
||||
AssertFatal(0, "Host: Listen failed\n");
|
||||
}
|
||||
|
||||
LOG_I(PHY, "Host: Waiting for DPU (Device) to connect...\n");
|
||||
|
||||
// 4. Accept
|
||||
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
|
||||
AssertFatal(0, "Host: Accept failed\n");
|
||||
}
|
||||
|
||||
LOG_I(PHY, "✅ Host: DPU Connected! Synchronizing physical layer parameters...\n");
|
||||
// 5. prepare and send config package
|
||||
LOG_I(PHY, "Host: Packing configuration for DPU...\n");
|
||||
|
||||
dma_sync_config_t sync_pkt;
|
||||
|
||||
memset(&sync_pkt, 0, sizeof(dma_sync_config_t));
|
||||
|
||||
sync_pkt.magic = 0x0A1D3A00; // magic token (OAI_DMA),DPU need to match it
|
||||
|
||||
nfapi_nr_config_request_scf_t *gNB_cfg_dma_h = &RC.gNB[0]->gNB_config;//
|
||||
|
||||
// --- 1. config->ssb_table ---
|
||||
sync_pkt.config__ssb_table__ssb_mask_list_0__ssb_mask__value = gNB_cfg_dma_h->ssb_table.ssb_mask_list[0].ssb_mask.value;
|
||||
sync_pkt.config__ssb_table__ssb_mask_list_1__ssb_mask__value = gNB_cfg_dma_h->ssb_table.ssb_mask_list[1].ssb_mask.value;
|
||||
sync_pkt.config__ssb_table__case_v3__value = gNB_cfg_dma_h->ssb_table.case_v3.value;
|
||||
|
||||
// --- 2. config->ssb_config ---
|
||||
sync_pkt.config__ssb_config__scs_common__value = gNB_cfg_dma_h->ssb_config.scs_common.value;
|
||||
|
||||
// --- 4. config->prach_config ---
|
||||
sync_pkt.config__prach_config__prach_ConfigurationIndex__value = gNB_cfg_dma_h->prach_config.prach_ConfigurationIndex.value;
|
||||
sync_pkt.config__prach_config__num_prach_fd_occasions__value = gNB_cfg_dma_h->prach_config.num_prach_fd_occasions.value;
|
||||
sync_pkt.config__prach_config__num_prach_fd_occasions_list_0__k1__value = gNB_cfg_dma_h->prach_config.num_prach_fd_occasions_list[0].k1.value;
|
||||
sync_pkt.config__prach_config__prach_sequence_length__value = gNB_cfg_dma_h->prach_config.prach_sequence_length.value;
|
||||
|
||||
// --- 6. config->cell_config ---
|
||||
sync_pkt.config__cell_config__frame_duplex_type__value = gNB_cfg_dma_h->cell_config.frame_duplex_type.value;
|
||||
|
||||
// --- 7. config->carrier_config ---
|
||||
sync_pkt.config__carrier_config__dl_grid_size__value = gNB_cfg_dma_h->carrier_config.dl_grid_size[gNB_cfg_dma_h->ssb_config.scs_common.value].value;
|
||||
sync_pkt.config__carrier_config__ul_grid_size__value = gNB_cfg_dma_h->carrier_config.ul_grid_size[gNB_cfg_dma_h->ssb_config.scs_common.value].value;
|
||||
sync_pkt.config__carrier_config__num_rx_ant__value = gNB_cfg_dma_h->carrier_config.num_rx_ant.value;
|
||||
sync_pkt.config__carrier_config__num_tx_ant__value = gNB_cfg_dma_h->carrier_config.num_tx_ant.value;
|
||||
sync_pkt.config__carrier_config__dl_frequency__value = gNB_cfg_dma_h->carrier_config.dl_frequency.value;
|
||||
sync_pkt.config__carrier_config__ul_frequency__value = gNB_cfg_dma_h->carrier_config.uplink_frequency.value;
|
||||
|
||||
for(int i = 0; i < 5; i++){
|
||||
sync_pkt.config__carrier_config__dl_k0__value[i] = gNB_cfg_dma_h->carrier_config.dl_k0[i].value;
|
||||
sync_pkt.config__carrier_config__ul_k0__value[i] = gNB_cfg_dma_h->carrier_config.ul_k0[i].value;
|
||||
|
||||
}
|
||||
// --- 8.ofdm_offset_divisor
|
||||
sync_pkt.ofdm_offset_divisor = RC.gNB[0]->ofdm_offset_divisor;
|
||||
// --- 5. config->tdd_table
|
||||
sync_pkt.config__tdd_table__tdd_period__value = gNB_cfg_dma_h->tdd_table.tdd_period.value;
|
||||
sync_pkt.config__tdd_table__tdd_period__tl__tag = gNB_cfg_dma_h->tdd_table.tdd_period.tl.tag;
|
||||
|
||||
if (gNB_cfg_dma_h->tdd_table.max_tdd_periodicity_list != NULL) {
|
||||
int max_slots_to_map = 10 * (1 << gNB_cfg_dma_h->ssb_config.scs_common.value);
|
||||
for (int slot = 0; slot < max_slots_to_map; slot++) {
|
||||
if (gNB_cfg_dma_h->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list != NULL) {
|
||||
for (int sym = 0; sym < 14; sym++) {
|
||||
int flat_idx = slot * 14 + sym;
|
||||
sync_pkt.config__tdd_table__max_tdd_periodicity_list__max_num_of_symbol_per_slot_list__slot_config__value[flat_idx] =
|
||||
gNB_cfg_dma_h->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- send to DPU ---
|
||||
LOG_I(PHY, "Host: Sending %lu bytes of sync configuration to DPU...\n", sizeof(dma_sync_config_t));
|
||||
|
||||
ssize_t sent_bytes = send(new_socket, &sync_pkt, sizeof(dma_sync_config_t), 0);
|
||||
if (sent_bytes != sizeof(dma_sync_config_t)) {
|
||||
LOG_E(PHY, "Host: Failed to send full configuration! Sent %zd bytes.\n", sent_bytes);
|
||||
} else {
|
||||
LOG_I(PHY, "Host: Configuration successfully sent to DPU.\n");
|
||||
}
|
||||
|
||||
close(new_socket);
|
||||
close(server_fd);
|
||||
|
||||
LOG_I(PHY, "Host: Control Plane handshake completed. Releasing RU init.\n");
|
||||
}
|
||||
|
||||
if (ru->if_south != REMOTE_IF4p5) {
|
||||
int threadCnt = ru->num_tpcores;
|
||||
if (threadCnt < 2)
|
||||
@@ -1437,9 +1924,29 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
ru->if_south = REMOTE_IF4p5;
|
||||
ru->function = NGFI_RAU_IF4p5;
|
||||
ru->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
|
||||
} else if (strcmp(str, "dma_if4p5_host") == 0) {
|
||||
ru->if_south = REMOTE_IF4p5_DMA_HOST;
|
||||
ru->function = NGFI_RAU_IF4p5;
|
||||
ru->eth_params.transp_preference = ETH_DMA_IF4p5_MODE;
|
||||
} else if (strcmp(str, "dma_if4p5_device") == 0) {
|
||||
ru->if_south = REMOTE_IF4p5_DMA_DEVICE;
|
||||
ru->function = NGFI_RAU_IF4p5;
|
||||
ru->eth_params.transp_preference = ETH_DMA_IF4p5_MODE;
|
||||
}
|
||||
} /* strcmp(local_rf, "yes") != 0 */
|
||||
|
||||
if (config_isparamset(param, RU_DMA_CTRL_IP_IDX)) {
|
||||
ru->dma_ctrl_ip = strdup(*param[RU_DMA_CTRL_IP_IDX].strptr);
|
||||
} else {
|
||||
ru->dma_ctrl_ip = strdup("127.0.0.1"); // default value
|
||||
}
|
||||
|
||||
if (config_isparamset(param, RU_DMA_CTRL_PORT_IDX)) {
|
||||
ru->dma_ctrl_port = (uint16_t)*param[RU_DMA_CTRL_PORT_IDX].uptr;
|
||||
} else {
|
||||
ru->dma_ctrl_port = 8888; // default value
|
||||
}
|
||||
|
||||
ru->nb_tx = *param[RU_NB_TX_IDX].uptr;
|
||||
ru->nb_rx = *param[RU_NB_RX_IDX].uptr;
|
||||
ru->att_tx = *param[RU_ATT_TX_IDX].uptr;
|
||||
@@ -1471,3 +1978,84 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
return;
|
||||
}
|
||||
|
||||
void print_shadow_gnb_config(nfapi_nr_config_request_scf_t *cfg) {
|
||||
LOG_I(PHY, "========================================================\n");
|
||||
LOG_I(PHY, " [DMA Device] SHADOW gNB CONFIG DUMP \n");
|
||||
LOG_I(PHY, "========================================================\n");
|
||||
|
||||
LOG_I(PHY, "[Cell] PCI: %d, Duplex Type: %d (0:FDD, 1:TDD)\n",
|
||||
cfg->cell_config.phy_cell_id.value,
|
||||
cfg->cell_config.frame_duplex_type.value);
|
||||
|
||||
LOG_I(PHY, "[SSB] SCS Common: %d, Mask0: 0x%08x, Mask1: 0x%08x\n",
|
||||
cfg->ssb_config.scs_common.value,
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
|
||||
|
||||
LOG_I(PHY, "[PRACH] Config Index: %d, FD Occasions: %d, Seq Length: %d\n",
|
||||
cfg->prach_config.prach_ConfigurationIndex.value,
|
||||
cfg->prach_config.num_prach_fd_occasions.value,
|
||||
cfg->prach_config.prach_sequence_length.value);
|
||||
|
||||
int scs = cfg->ssb_config.scs_common.value;
|
||||
LOG_I(PHY, "[Carrier] DL Grid Size (PRBs): %d, UL Grid Size: %d\n",
|
||||
cfg->carrier_config.dl_grid_size[scs].value,
|
||||
cfg->carrier_config.ul_grid_size[scs].value);
|
||||
LOG_I(PHY, "[Antenna] RX: %d, TX: %d\n",
|
||||
cfg->carrier_config.num_rx_ant.value,
|
||||
cfg->carrier_config.num_tx_ant.value);
|
||||
|
||||
LOG_I(PHY, "[TDD] Periodicity: %d\n", cfg->tdd_table.tdd_period.value);
|
||||
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list != NULL) {
|
||||
int slots_per_frame = 10 * (1 << scs);
|
||||
LOG_I(PHY, "[TDD] Frame layout for SCS=%d (Printing first %d slots):\n", scs, slots_per_frame);
|
||||
|
||||
for (int slot = 0; slot < slots_per_frame && slot < 160; slot++) {
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list != NULL) {
|
||||
char slot_pattern[15];
|
||||
|
||||
for (int sym = 0; sym < 14; sym++) {
|
||||
uint8_t val = cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value;
|
||||
if (val == 0) slot_pattern[sym] = 'D';
|
||||
else if (val == 1) slot_pattern[sym] = 'U';
|
||||
else if (val == 2) slot_pattern[sym] = 'F';
|
||||
else slot_pattern[sym] = '?';
|
||||
}
|
||||
slot_pattern[14] = '\0';
|
||||
|
||||
LOG_I(PHY, " Slot %2d: [%s]\n", slot, slot_pattern);
|
||||
} else {
|
||||
LOG_I(PHY, " Slot %2d: [NULL Pointer - Unconfigured]\n", slot);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY, "[TDD] Error: max_tdd_periodicity_list is NULL!\n");
|
||||
}
|
||||
LOG_I(PHY, "========================================================\n");
|
||||
}
|
||||
|
||||
//helper function for nr-oru
|
||||
void nroru_init_nr_transport(PHY_VARS_gNB *gNB)
|
||||
{
|
||||
int max_nb_jobs = 16;
|
||||
bool ret;
|
||||
|
||||
ret = spsc_q_alloc(&gNB->pucch_queue, max_nb_jobs, sizeof(NR_gNB_PUCCH_job_t));
|
||||
DevAssert(ret);
|
||||
|
||||
ret = spsc_q_alloc(&gNB->pusch_queue, max_nb_jobs, sizeof(NR_gNB_PUSCH_job_t));
|
||||
DevAssert(ret);
|
||||
|
||||
ret = spsc_q_alloc(&gNB->srs_queue, max_nb_jobs, sizeof(NR_gNB_SRS_job_t));
|
||||
DevAssert(ret);
|
||||
|
||||
gNB->max_nb_pusch = max_nb_jobs;
|
||||
gNB->ulsch = (NR_gNB_ULSCH_t *)malloc16(gNB->max_nb_pusch * sizeof(NR_gNB_ULSCH_t));
|
||||
if (gNB->ulsch) {
|
||||
memset(gNB->ulsch, 0, gNB->max_nb_pusch * sizeof(NR_gNB_ULSCH_t));
|
||||
}
|
||||
|
||||
gNB->rx_total_gain_dB = 130;
|
||||
LOG_I(PHY, "Standalone ORU mode: PUCCH, PUSCH, and SRS queues successfully mock-initialized.\n");
|
||||
}
|
||||
@@ -316,6 +316,22 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *
|
||||
: fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples)
|
||||
+ (fp->symbols_per_slot * fp->ofdm_symbol_size);
|
||||
fp->samples_per_frame = 10 * fp->samples_per_subframe;
|
||||
//reconfigure for nr-oru
|
||||
if(fp->dl_CarrierFreq == 0){
|
||||
uint64_t dl_bw_khz = (12*cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value)*(15<<cfg->ssb_config.scs_common.value);
|
||||
fp->dl_CarrierFreq = ((dl_bw_khz >> 1) + cfg->carrier_config.dl_frequency.value) * 1000;
|
||||
}
|
||||
if(fp->ul_CarrierFreq == 0){
|
||||
uint64_t ul_bw_khz = (12*cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value)*(15<<cfg->ssb_config.scs_common.value);
|
||||
fp->ul_CarrierFreq = ((ul_bw_khz >> 1) + cfg->carrier_config.uplink_frequency.value) * 1000;
|
||||
|
||||
if(fp->ofdm_offset_divisor == 0){
|
||||
fp->ofdm_offset_divisor = 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq);
|
||||
|
||||
fp->Ncp = Ncp;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
#include "common/utils/threadPool/notified_fifo.h"
|
||||
|
||||
#include "defs_nr_dma.h"
|
||||
|
||||
#define MAX_BANDS_PER_RRU 4
|
||||
#define MAX_RRU_CONFIG_SIZE 1024
|
||||
|
||||
@@ -348,12 +350,14 @@ typedef struct RU_proc_t_s {
|
||||
} RU_proc_t;
|
||||
|
||||
typedef enum {
|
||||
LOCAL_RF =0,
|
||||
REMOTE_IF5 =1,
|
||||
REMOTE_MBP_IF5 =2,
|
||||
REMOTE_IF4p5 =3,
|
||||
REMOTE_IF1pp =4,
|
||||
MAX_RU_IF_TYPES =5
|
||||
LOCAL_RF =0,
|
||||
REMOTE_IF5 =1,
|
||||
REMOTE_MBP_IF5 =2,
|
||||
REMOTE_IF4p5 =3,
|
||||
REMOTE_IF1pp =4,
|
||||
REMOTE_IF4p5_DMA_HOST =5,
|
||||
REMOTE_IF4p5_DMA_DEVICE =6,
|
||||
MAX_RU_IF_TYPES =7
|
||||
} RU_if_south_t;
|
||||
|
||||
|
||||
@@ -608,6 +612,11 @@ typedef struct RU_t_s {
|
||||
/// number of cores for RU ThreadPool
|
||||
int num_tpcores;
|
||||
void* scopeData;
|
||||
|
||||
char *dma_ctrl_ip;
|
||||
//dma CP ip
|
||||
uint16_t dma_ctrl_port;
|
||||
//dma CP port
|
||||
} RU_t;
|
||||
|
||||
|
||||
|
||||
78
openair1/PHY/defs_nr_dma.h
Normal file
78
openair1/PHY/defs_nr_dma.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Top-level defines and structure definitions
|
||||
*/
|
||||
#ifndef __DEFS_NR_DMA_H__
|
||||
#define __DEFS_NR_DMA_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DMA_SYNC_MAGIC 0xDA7A0A10
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t magic;
|
||||
|
||||
// --- 1. config->ssb_table ---
|
||||
uint32_t config__ssb_table__ssb_mask_list_0__ssb_mask__value;
|
||||
uint32_t config__ssb_table__ssb_mask_list_1__ssb_mask__value;
|
||||
uint32_t config__ssb_table__case_v3__value;
|
||||
|
||||
// --- 2. config->ssb_config ---
|
||||
uint8_t config__ssb_config__scs_common__value;
|
||||
|
||||
// --- 3. config->analog_beamforming_ve ---
|
||||
uint16_t config__analog_beamforming_ve__num_beams_period_vendor_ext__tl__tag;
|
||||
uint16_t config__analog_beamforming_ve__num_beams_period_vendor_ext__tl__length;
|
||||
uint8_t config__analog_beamforming_ve__num_beams_period_vendor_ext__value;
|
||||
|
||||
uint16_t config__analog_beamforming_ve__analog_bf_vendor_ext__tl__tag;
|
||||
uint16_t config__analog_beamforming_ve__analog_bf_vendor_ext__tl__length;
|
||||
uint8_t config__analog_beamforming_ve__analog_bf_vendor_ext__value;
|
||||
|
||||
// --- 4. config->prach_config ---
|
||||
uint16_t config__prach_config__prach_ConfigurationIndex__tl__tag;
|
||||
uint8_t config__prach_config__prach_ConfigurationIndex__value;
|
||||
uint8_t config__prach_config__num_prach_fd_occasions__value;
|
||||
uint16_t config__prach_config__num_prach_fd_occasions_list_0__k1__value;
|
||||
uint8_t config__prach_config__prach_sequence_length__value;
|
||||
|
||||
// --- 5. config->tdd_table ---
|
||||
uint16_t config__tdd_table__tdd_period__tl__tag;
|
||||
uint8_t config__tdd_table__tdd_period__value;
|
||||
|
||||
// 【Big Boss】: 160 slots * 14 symbols = 2240 bytes
|
||||
// 用于复原那个噩梦般的多级指针嵌套值
|
||||
uint8_t config__tdd_table__max_tdd_periodicity_list__max_num_of_symbol_per_slot_list__slot_config__value[160 * 14];
|
||||
|
||||
// --- 6. config->cell_config ---
|
||||
uint8_t config__cell_config__frame_duplex_type__tl__tag;
|
||||
uint8_t config__cell_config__frame_duplex_type__value;
|
||||
|
||||
// --- 7. config->carrier_config ---
|
||||
// 对 dl_k0 和 ul_k0 进行完整映射
|
||||
uint16_t config__carrier_config__dl_k0__value[5];
|
||||
uint16_t config__carrier_config__ul_k0__value[5];
|
||||
|
||||
uint16_t config__carrier_config__dl_grid_size__value;
|
||||
uint16_t config__carrier_config__ul_grid_size__value;
|
||||
uint16_t config__carrier_config__num_rx_ant__value;
|
||||
uint16_t config__carrier_config__num_tx_ant__value;
|
||||
|
||||
uint32_t config__carrier_config__dl_frequency__value;
|
||||
uint32_t config__carrier_config__dl_bandwidth__value;
|
||||
|
||||
uint32_t config__carrier_config__ul_frequency__value;
|
||||
uint32_t config__carrier_config__ul_bandwidth__value;
|
||||
|
||||
uint8_t ofdm_offset_divisor;
|
||||
|
||||
// --- 9. DMA 内存锚点 ---//目前还没分配
|
||||
uint64_t dma_remote_addr;
|
||||
uint32_t dma_rkey;
|
||||
|
||||
} dma_sync_config_t;
|
||||
|
||||
#endif
|
||||
@@ -75,7 +75,9 @@ typedef enum {
|
||||
#define CONFIG_STRING_RU_NUM_INTERFACES "num_interfaces"
|
||||
#define CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION "half_slot_parallelization"
|
||||
#define CONFIG_STRING_RU_RU_THREAD_CORE "ru_thread_core"
|
||||
#define CONFIG_STRING_RU_GPIO_CONTROL "gpio_controller"
|
||||
#define CONFIG_STRING_RU_GPIO_CONTROL "gpio_controller"
|
||||
#define CONFIG_STRING_DMA_CTRL_PLANE_IP "dma_ctrl_ip"
|
||||
#define CONFIG_STRING_DMA_CTRL_PLANE_PORT "dma_ctrl_port"
|
||||
|
||||
#define HLP_RU_SF_AHEAD "LTE TX processing advance"
|
||||
#define HLP_RU_SL_AHEAD "NR TX processing advance"
|
||||
@@ -133,6 +135,9 @@ typedef enum {
|
||||
#define RU_HALF_SLOT_PARALLELIZATION 40
|
||||
#define RU_RU_THREAD_CORE 41
|
||||
#define RU_GPIO_CONTROL 42
|
||||
#define RU_DMA_CTRL_IP_IDX 43
|
||||
#define RU_DMA_CTRL_PORT_IDX 44
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* RU configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -182,6 +187,8 @@ typedef enum {
|
||||
{CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION, HLP_RU_HALF_SLOT_PARALLELIZATION, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_RU_RU_THREAD_CORE, HLP_RU_RU_THREAD_CORE, 0, .iptr=NULL, .defintval=-1, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_GPIO_CONTROL, HLP_RU_GPIO_CONTROL, 0, .strptr=NULL, .defstrval="generic", TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_DMA_CTRL_PLANE_IP, NULL, 0, .strptr=NULL, .defstrval="127.0.0.1", TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_DMA_CTRL_PLANE_PORT, NULL, 0, .uptr=NULL, .defuintval=8888, TYPE_UINT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define ETH_UDP_IF4p5_MODE 2
|
||||
#define ETH_RAW_IF4p5_MODE 3
|
||||
#define ETH_UDP_IF5_ECPRI_MODE 4
|
||||
#define ETH_DMA_IF4p5_MODE 5
|
||||
|
||||
// COMMOM HEADER LENGTHS
|
||||
|
||||
|
||||
@@ -729,8 +729,8 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||
uint8_t *dst1 = (uint8_t *)(pos + (neg_len == 0 ? ((start_totalRB * N_SC_PER_PRB) - (num_totalRB * 6)) : 0));
|
||||
// negative half
|
||||
uint8_t *dst2 = (uint8_t *)(pos + (start_totalRB * N_SC_PER_PRB) + fftsize - (num_totalRB * 6));
|
||||
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
|
||||
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
|
||||
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);//<----------------------------------- need to get rid of this
|
||||
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);//<------------------------- need to get rid of this
|
||||
}
|
||||
}
|
||||
} // idxDesc
|
||||
|
||||
@@ -434,7 +434,7 @@ static void oran_allocate_buffers(void *handle,
|
||||
void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config)
|
||||
{
|
||||
int32_t xret = 0;
|
||||
|
||||
printf("We are initialing the oran!!!!!!!\n");
|
||||
#if defined K_RELEASE
|
||||
xran_mem_mgr_leak_detector_init();
|
||||
#endif
|
||||
@@ -462,6 +462,7 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
#endif
|
||||
|
||||
/** process all the O-RU|O-DU for use case */
|
||||
printf("testing3.1\n");
|
||||
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]);
|
||||
#if defined F_RELEASE
|
||||
@@ -480,7 +481,7 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
|
||||
pi->prach_tag = tag;
|
||||
pi->pusch_tag = tag;
|
||||
|
||||
printf("testing3.2\n");
|
||||
#if defined K_RELEASE
|
||||
oran_allocate_buffers(gxran_handle[0], o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
|
||||
if ((xret = xran_timingsource_reg_tticb(NULL, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
|
||||
@@ -490,10 +491,12 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
#elif defined F_RELEASE
|
||||
LOG_W(HW, "Please be aware that F release support will be removed in the future. Consider switching to K release.\n");
|
||||
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
|
||||
printf("testing3.2\n");
|
||||
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);
|
||||
exit(-1);
|
||||
}
|
||||
printf("testing3.3\n");
|
||||
#endif
|
||||
|
||||
// retrieve and store prach duration
|
||||
@@ -502,6 +505,7 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
uint8_t idx = xran_fh_config[o_xu_id].perMu[mu].prach_conf.nPrachConfIdx;
|
||||
#elif defined F_RELEASE
|
||||
uint8_t idx = xran_fh_config[o_xu_id].prach_conf.nPrachConfIdx;
|
||||
printf("testing3.4\n");
|
||||
#endif
|
||||
const struct xran_frame_config *fc = &xran_fh_config[o_xu_id].frame_conf;
|
||||
g_prach_info[o_xu_id] = get_nr_prach_occasion_info_from_index(idx,
|
||||
@@ -512,12 +516,12 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
#endif
|
||||
fc->nFrameDuplexType == XRAN_FDD ? duplex_mode_FDD : duplex_mode_TDD);
|
||||
}
|
||||
|
||||
printf("testing3.5\n");
|
||||
// store config after xran initialization -- xran makes modifications to
|
||||
// these structs during initialization
|
||||
memcpy(&g_fh_init, xran_fh_init, sizeof(*xran_fh_init));
|
||||
memcpy(&g_fh_config, xran_fh_config, sizeof(*xran_fh_config) * xran_fh_init->xran_ports);
|
||||
|
||||
printf("testing3.6\n");
|
||||
return gxran_handle;
|
||||
}
|
||||
|
||||
|
||||
@@ -357,15 +357,221 @@ void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
stop_meas(&ru->tx_fhaul);
|
||||
}
|
||||
|
||||
void oran_fh_if4p5_south_in_dma_device(RU_t *ru, int *frame, int *slot)
|
||||
{
|
||||
//printf("Let's see if we are in oran_fh_if4p5_south_in_dma_device rn???\n ");
|
||||
|
||||
|
||||
int ret = 0; // return code for PUSCH/PRACH processing
|
||||
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.rxdataF = ru->common.rxdataF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
.prach_buf = NULL,
|
||||
};
|
||||
|
||||
/* Firstly, process PUSCH packets */
|
||||
RU_proc_t *proc = &ru->proc; // to check if (frame,slot) combination corresponds to the expected PUSCH one
|
||||
int f, sl;
|
||||
LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
start_meas(&ru->rx_fhaul);
|
||||
ret = xran_fh_rx_read_slot(&ru_info, &f, &sl);
|
||||
stop_meas(&ru->rx_fhaul);
|
||||
LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX function \n", f, sl);
|
||||
}
|
||||
|
||||
/* Secondly, process PRACH packets */
|
||||
int f_prach, sl_prach;
|
||||
#if defined F_RELEASE
|
||||
// no PRACH callback (no queue) in F release so use the expected combination
|
||||
f_prach = *frame;
|
||||
sl_prach = *slot;
|
||||
#endif
|
||||
ret = xran_fh_rx_prach_read_slot(ru->gNB_list[0], &ru_info, &f_prach, &sl_prach);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX PRACH function \n", f_prach, sl_prach);
|
||||
}
|
||||
|
||||
int slots_per_frame = 10 << (ru->openair0_cfg.nr_scs_for_raster);
|
||||
proc->tti_rx = sl;
|
||||
proc->frame_rx = f;
|
||||
proc->tti_tx = (sl + ru->sl_ahead) % slots_per_frame;
|
||||
proc->frame_tx = (sl > (slots_per_frame - 1 - ru->sl_ahead)) ? (f + 1) & 1023 : f;
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
print_fhi_counters(&ru_info, proc->frame_rx, proc->tti_rx);
|
||||
if (proc->tti_rx != *slot) {
|
||||
LOG_E(HW,
|
||||
"Received Time doesn't correspond to the time we think it is (slot mismatch, received %d.%d, expected %d.%d)\n",
|
||||
proc->frame_rx,
|
||||
proc->tti_rx,
|
||||
*frame,
|
||||
*slot);
|
||||
*slot = proc->tti_rx;
|
||||
}
|
||||
|
||||
if (proc->frame_rx != *frame) {
|
||||
LOG_E(HW,
|
||||
"Received Time doesn't correspond to the time we think it is (frame mismatch, %d.%d , expected %d.%d)\n",
|
||||
proc->frame_rx,
|
||||
proc->tti_rx,
|
||||
*frame,
|
||||
*slot);
|
||||
*frame = proc->frame_rx;
|
||||
}
|
||||
} else {
|
||||
proc->first_rx = 0;
|
||||
LOG_I(HW, "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(HW, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
|
||||
}
|
||||
}
|
||||
|
||||
void oran_fh_if4p5_south_out_dma_device(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
printf("Let's see if we are in oran_fh_if4p5_south_out_dma_device rn???\n ");
|
||||
start_meas(&ru->tx_fhaul);
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.txdataF_BF = ru->common.txdataF_BF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
};
|
||||
|
||||
// printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp);
|
||||
|
||||
int ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n");
|
||||
}
|
||||
stop_meas(&ru->tx_fhaul);
|
||||
}
|
||||
|
||||
void oran_fh_if4p5_south_in_dma_host(RU_t *ru, int *frame, int *slot)
|
||||
{
|
||||
printf("Let's see if we are in oran_fh_if4p5_south_in_dma_host rn???\n ");
|
||||
int ret = 0; // return code for PUSCH/PRACH processing
|
||||
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.rxdataF = ru->common.rxdataF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
.prach_buf = NULL,
|
||||
};
|
||||
|
||||
/* Firstly, process PUSCH packets */
|
||||
RU_proc_t *proc = &ru->proc; // to check if (frame,slot) combination corresponds to the expected PUSCH one
|
||||
int f, sl;
|
||||
LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
start_meas(&ru->rx_fhaul);
|
||||
ret = xran_fh_rx_read_slot(&ru_info, &f, &sl);
|
||||
stop_meas(&ru->rx_fhaul);
|
||||
LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX function \n", f, sl);
|
||||
}
|
||||
|
||||
/* Secondly, process PRACH packets */
|
||||
int f_prach, sl_prach;
|
||||
#if defined F_RELEASE
|
||||
// no PRACH callback (no queue) in F release so use the expected combination
|
||||
f_prach = *frame;
|
||||
sl_prach = *slot;
|
||||
#endif
|
||||
ret = xran_fh_rx_prach_read_slot(ru->gNB_list[0], &ru_info, &f_prach, &sl_prach);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX PRACH function \n", f_prach, sl_prach);
|
||||
}
|
||||
|
||||
int slots_per_frame = 10 << (ru->openair0_cfg.nr_scs_for_raster);
|
||||
proc->tti_rx = sl;
|
||||
proc->frame_rx = f;
|
||||
proc->tti_tx = (sl + ru->sl_ahead) % slots_per_frame;
|
||||
proc->frame_tx = (sl > (slots_per_frame - 1 - ru->sl_ahead)) ? (f + 1) & 1023 : f;
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
print_fhi_counters(&ru_info, proc->frame_rx, proc->tti_rx);
|
||||
if (proc->tti_rx != *slot) {
|
||||
LOG_E(HW,
|
||||
"Received Time doesn't correspond to the time we think it is (slot mismatch, received %d.%d, expected %d.%d)\n",
|
||||
proc->frame_rx,
|
||||
proc->tti_rx,
|
||||
*frame,
|
||||
*slot);
|
||||
*slot = proc->tti_rx;
|
||||
}
|
||||
|
||||
if (proc->frame_rx != *frame) {
|
||||
LOG_E(HW,
|
||||
"Received Time doesn't correspond to the time we think it is (frame mismatch, %d.%d , expected %d.%d)\n",
|
||||
proc->frame_rx,
|
||||
proc->tti_rx,
|
||||
*frame,
|
||||
*slot);
|
||||
*frame = proc->frame_rx;
|
||||
}
|
||||
} else {
|
||||
proc->first_rx = 0;
|
||||
LOG_I(HW, "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(HW, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
|
||||
}
|
||||
}
|
||||
|
||||
void oran_fh_if4p5_south_out_dma_host(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
printf("Let's see if we are in oran_fh_if4p5_south_out_dma_host rn???\n ");
|
||||
start_meas(&ru->tx_fhaul);
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.txdataF_BF = ru->common.txdataF_BF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
};
|
||||
|
||||
// printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp);
|
||||
|
||||
int ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp);
|
||||
if (ret != 0) {
|
||||
printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n");
|
||||
}
|
||||
stop_meas(&ru->tx_fhaul);
|
||||
}
|
||||
|
||||
void *get_internal_parameter(char *name)
|
||||
{
|
||||
printf("ORAN: %s\n", __FUNCTION__);
|
||||
printf("ORAN: %s (requesting: %s)\n", __FUNCTION__, name);
|
||||
|
||||
// 1. standard IF4p5
|
||||
if (!strcmp(name, "fh_if4p5_south_in"))
|
||||
return (void *)oran_fh_if4p5_south_in;
|
||||
if (!strcmp(name, "fh_if4p5_south_out"))
|
||||
return (void *)oran_fh_if4p5_south_out;
|
||||
|
||||
// 2. DMA DEVICE (DPU side)
|
||||
if (!strcmp(name, "fh_if4p5_south_in_dma_device"))
|
||||
return (void *)oran_fh_if4p5_south_in_dma_device;
|
||||
if (!strcmp(name, "fh_if4p5_south_out_dma_device"))
|
||||
return (void *)oran_fh_if4p5_south_out_dma_device;
|
||||
|
||||
// 3. DMA HOST interface (host side)
|
||||
if (!strcmp(name, "fh_if4p5_south_in_dma_host"))
|
||||
return (void *)oran_fh_if4p5_south_in_dma_host;
|
||||
if (!strcmp(name, "fh_if4p5_south_out_dma_host"))
|
||||
return (void *)oran_fh_if4p5_south_out_dma_host;
|
||||
|
||||
printf("ORAN: %s - Warning: Unknown parameter name [%s]\n", __FUNCTION__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 7;
|
||||
tr_preference = "dma_if4p5_device"; # important: activate FHI7.2
|
||||
# choose dma functions, act as slave(device)
|
||||
dma_ctrl_ip = "192.168.100.1";
|
||||
dma_ctrl_port = 3889;
|
||||
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
ngap_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("mlx5_core.sf.2", "mlx5_core.sf.4"); # one VF can be used as well //0000:03:00.0 //auxiliary:mlx5_core.sf.2
|
||||
system_core = 11;
|
||||
io_core = 12;
|
||||
worker_cores = (13);
|
||||
vlan_tag = 5;
|
||||
ru_addr = ("8c:1f:64:d1:10:46", "8c:1f:64:d1:10:46");
|
||||
mtu = 9000;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (500, 700);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 400);
|
||||
Ta4 = (0, 400);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,256 @@
|
||||
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
|
||||
Active_gNBs = ( "gNB-OAI-DU");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
# gNB_DU_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI-DU";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
|
||||
nr_cellid = 1;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pusch_AntennaPorts = 4;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
force_UL256qam_off = 1;
|
||||
# maxMIMO_layers = 2;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
# n_TimingAdvanceOffset = 0;
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# center frequency = 3950.4 MHz
|
||||
# selected SSB frequency = 3950.4 MHz
|
||||
absoluteFrequencySSB = 663360;
|
||||
dl_frequencyBand = 77;
|
||||
# frequency point A = 3901.26 MHz
|
||||
dl_absoluteFrequencyPointA = 660084;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 273;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1
|
||||
#
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 77;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 273;
|
||||
pMax = 23;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 1099;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 152;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 0;
|
||||
preambleReceivedTargetPower = -100;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 8;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 3;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#one (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
|
||||
msg3_DeltaPreamble = 2;
|
||||
p0_NominalWithGrant = -96;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 0;
|
||||
p0_nominal = -96;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 0x1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 5;
|
||||
nrofDownlinkSlots = 3;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
node_type = "NODE_NGAP";
|
||||
local_n_address = "127.0.0.1";
|
||||
remote_n_address = "127.0.0.1";
|
||||
local_n_portd = 2153;
|
||||
remote_n_portd = 2153;
|
||||
pusch_TargetSNRx10 = 170;
|
||||
pucch_TargetSNRx10 = 230;
|
||||
dl_bler_target_upper = .35;
|
||||
dl_bler_target_lower = .15;
|
||||
ul_bler_target_upper = .35;
|
||||
ul_bler_target_lower = .15;
|
||||
pusch_FailureThres = 100;
|
||||
ul_max_mcs = 28;
|
||||
min_grant_prb = 1;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 100;
|
||||
pucch0_dtx_threshold = 80;
|
||||
pusch_dtx_threshold = 10;
|
||||
max_ldpc_iterations = 10;
|
||||
tx_amp_backoff_dB = 12; # needs to match O-RU configuration
|
||||
L1_rx_thread_core = 8;
|
||||
L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread
|
||||
phase_compensation = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 5;
|
||||
tr_preference = "dma_if4p5_host"; # important: activate FHI7.2
|
||||
# choose dma function, act as host
|
||||
dma_ctrl_ip = "192.168.100.1";
|
||||
dma_ctrl_port = 3889;
|
||||
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
ngap_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:01:00.3"); # one VF can be used as well
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
ru_addr = ("8c:1f:64:d1:10:46","8c:1f:64:d1:10:46");
|
||||
mtu = 9000;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 10;
|
||||
tr_preference = "dma_if4p5_device"; # important: activate FHI7.2
|
||||
# choose dma functions, act as slave(device)
|
||||
dma_ctrl_ip = "192.168.100.1";
|
||||
dma_ctrl_port = 3889;
|
||||
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
ngap_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("mlx5_core.sf.2"); # one VF can be used as well
|
||||
system_core = 11;
|
||||
io_core = 12;
|
||||
worker_cores = (13);
|
||||
ru_addr = ("70:b3:d5:e1:5b:81", "70:b3:d5:e1:5b:81");
|
||||
mtu = 9216;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,275 @@
|
||||
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
|
||||
nr_cellid = 1;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
maxMIMO_layers = 2;
|
||||
pusch_AntennaPorts = 4;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
# force_UL256qam_off = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
# n_TimingAdvanceOffset = 0;
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# center frequency = 3350.01 MHz
|
||||
# selected SSB frequency = 3349.92 MHz
|
||||
absoluteFrequencySSB = 623328;
|
||||
dl_frequencyBand = 78;
|
||||
# frequency point A = 3300.87 MHz
|
||||
dl_absoluteFrequencyPointA = 620058;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 273;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1
|
||||
#
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 273;
|
||||
pMax = 23;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 1099;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 152;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 0;
|
||||
preambleReceivedTargetPower = -100;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 8;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 3;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#one (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
|
||||
msg3_DeltaPreamble = 2;
|
||||
p0_NominalWithGrant = -96;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 0;
|
||||
p0_nominal = -96;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 0x1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ({ ipv4 = "172.21.6.5"; });
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.51";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.51";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 180;
|
||||
pucch_TargetSNRx10 = 220;
|
||||
dl_bler_target_upper = .35;
|
||||
dl_bler_target_lower = .15;
|
||||
ul_bler_target_upper = .35;
|
||||
ul_bler_target_lower = .15;
|
||||
pusch_FailureThres = 1000;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 100;
|
||||
pucch0_dtx_threshold = 80;
|
||||
pusch_dtx_threshold = 10;
|
||||
max_ldpc_iterations = 15;
|
||||
tx_amp_backoff_dB = 12; # needs to match O-RU configuration
|
||||
L1_rx_thread_core = 8;
|
||||
L1_tx_thread_core = 10;
|
||||
phase_compensation = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 10;
|
||||
tr_preference = "dma_if4p5_host"; # important: activate FHI7.2
|
||||
# choose dma function, act as host
|
||||
dma_ctrl_ip = "192.168.100.2";
|
||||
dma_ctrl_port = 3889;
|
||||
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
ngap_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:c1:11.0", "0000:c1:11.1"); # one VF can be used as well
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
ru_addr = ("70:b3:d5:e1:5b:81", "70:b3:d5:e1:5b:81");
|
||||
mtu = 9216;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user