Compare commits

...

10 Commits

Author SHA1 Message Date
Qizhi Pan
a7ed7bfcfa preliminary DMA design section 2026-05-26 10:04:57 +00:00
Qizhi Pan
fb50be508d typo 2026-05-22 16:01:32 +00:00
Qizhi Pan
7b538f8fad nr-oru can be connected to an RU. Done a scratch of the configuration doc 2026-05-22 15:54:44 +00:00
Qizhi Pan
dc7ec0aafd nr-oru running stable in dpu. need to validate with real RU attached 2026-05-19 11:57:14 +00:00
Qizhi Pan
fc3f253a60 Merge branch 'develop' into nr-oru_dma 2026-05-07 12:23:46 +00:00
Qizhi Pan
443eda642e change interface 2026-05-07 12:22:44 +00:00
Qizhi Pan
85f40d0188 change south_in_dma to south_in_dma_host & south_in_dma_device 2026-05-06 14:01:24 +00:00
Qizhi Pan
f9b45aee6a configure for dpu 2026-04-22 15:03:57 +00:00
panq
3e81a8a372 control plane initially done. Need to test on DPU 2026-04-22 12:56:52 +00:00
panq
a54b0f84ad wip: add REMOTE_IF4p5_DMA types and structure placeholders for dma nr-oru 2026-04-16 14:56:27 +00:00
19 changed files with 6087 additions and 34 deletions

View File

@@ -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
####################################

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -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
View File

@@ -0,0 +1,10 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
/*!
* \brief Specific functions for nr-oru executables
*/

View File

@@ -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");
}

View File

@@ -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;

View File

@@ -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;

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
};
});
};

View File

@@ -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;
};
});
};

View File

@@ -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;
};
});
};

View File

@@ -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;
};
});
};