Merge branch 'integration_2026_w06' into 'develop'

Integration `2026.w06`

* !3690 [FHI72] Support large DU delay profiles in the xran F, and include ProtO-RU emulator designed to run 7.2 with an USRP
* !3887 Update RHEL UBI image source to `registry.redhat.io`
* !3882 Change Aerial to pack directly in nvIPC message buffer
* !3895 CI: Ensure OAI-FLEXRIC-RAN-Integration-Test pipeline always uses latest commit for non-MR builds
* !3873 Ensure noise power is non-zero
* !3889 Enable imscope for split7.2
* !3801 Resolve "7.2 split ru_thread slot miss
* !3898 Fix config_libconfig_get for string
* !3876 Removing the duplicate loop in ULSCH power computation

Closes #972

See merge request oai/openairinterface5g!3888
This commit is contained in:
Jaroslava Fiedlerova
2026-02-06 07:42:09 +00:00
28 changed files with 868 additions and 531 deletions

View File

@@ -115,6 +115,7 @@ pipeline {
} else {
sh "git fetch"
sh "git checkout -f ${commitID}"
sh "git reset --hard origin/${commitID}"
}
} else {
echo "\u274C Some parameters are missing"

View File

@@ -1,5 +1,5 @@
diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h
index ac5f471..ed9ab7d 100644
index ac5f471..b1acb26 100644
--- a/fhi_lib/app/src/common.h
+++ b/fhi_lib/app/src/common.h
@@ -28,7 +28,7 @@
@@ -7,7 +7,7 @@ index ac5f471..ed9ab7d 100644
#include <rte_mbuf.h>
-#define VERSIONX "oran_f_release_v1.0"
+#define VERSIONX "oran_f_release_v1.7"
+#define VERSIONX "oran_f_release_v1.8"
#define APP_O_DU 0
#define APP_O_RU 1
@@ -530,7 +530,7 @@ index 59b6850..322d238 100644
\ No newline at end of file
+}
diff --git a/fhi_lib/lib/src/xran_cb_proc.c b/fhi_lib/lib/src/xran_cb_proc.c
index 08660f3..2bb5187 100644
index 08660f3..b5de607 100644
--- a/fhi_lib/lib/src/xran_cb_proc.c
+++ b/fhi_lib/lib/src/xran_cb_proc.c
@@ -25,7 +25,10 @@
@@ -544,6 +544,55 @@ index 08660f3..2bb5187 100644
#include <rte_common.h>
#include <rte_eal.h>
#include <rte_errno.h>
@@ -106,6 +109,12 @@ void xran_timer_arm_for_deadline(struct rte_timer *tim, void* arg, void *p_dev_
+ nSubframeIdx*SLOTNUM_PER_SUBFRAME(p_xran_dev_ctx->interval_us_local)
+ nSlotIdx;
+ /* correction to rx_tti for Ta4 values larger than a TTI */
+ rx_tti -= p_xran_dev_ctx->offset_num_slots_up_ul;
+ if (rx_tti < 0) {
+ rx_tti += (SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME(p_xran_dev_ctx->interval_us_local)*1024);
+ }
+
p_xran_dev_ctx->cb_timer_ctx[p_xran_dev_ctx->timer_put % MAX_CB_TIMER_CTX].tti_to_process = rx_tti;
if (xran_if_current_state == XRAN_RUNNING){
rte_timer_cb_t fct = (rte_timer_cb_t)arg;
@@ -195,6 +204,7 @@ xran_timing_create_cbs(void *args)
max_dl_delay_offset += interval_us_local;
numSlots++;
}
+ p_dev_ctx->offset_num_slots_cp_dl = numSlots;
/* Delay from start of 'a' slot */
delay_cp_dl_max = max_dl_delay_offset - p_dev_ctx->fh_cfg.T1a_max_cp_dl;
@@ -227,6 +237,7 @@ xran_timing_create_cbs(void *args)
ul_delay_offset += interval_us_local;
numSlots++;
}
+ p_dev_ctx->offset_num_slots_cp_ul = numSlots;
delay_cp_ul = ul_delay_offset - p_dev_ctx->fh_cfg.T1a_max_cp_ul;
sym_cp_ul = (delay_cp_ul*1000/(interval_us_local*1000/N_SYM_PER_SLOT)+1);
uint8_t ul_offset_sym = (numSlots+1)*N_SYM_PER_SLOT - sym_cp_ul;
@@ -242,8 +253,18 @@ xran_timing_create_cbs(void *args)
delay_up = p_dev_ctx->fh_cfg.T1a_max_up;
time_diff_us = p_dev_ctx->fh_cfg.Ta4_max;
+ uint32_t ul_up_delay_offset=interval_us_local;
+ numSlots=0;
+ while(time_diff_us > ul_up_delay_offset) {
+ ul_up_delay_offset += interval_us_local;
+ numSlots++;
+ }
+ p_dev_ctx->offset_num_slots_up_ul = numSlots;
+
+ printf("offset_num_slots_cp_dl=%d, offset_num_slots_cp_ul=%d, offset_num_slots_up_ul=%d\n",
+ p_dev_ctx->offset_num_slots_cp_dl, p_dev_ctx->offset_num_slots_cp_ul, p_dev_ctx->offset_num_slots_up_ul);
- delay_cp2up = delay_up-delay_cp_dl_max;
+ delay_cp2up = p_dev_ctx->fh_cfg.T1a_max_cp_dl - p_dev_ctx->fh_cfg.T1a_max_up;
time_diff_nSymb = time_diff_us*1000/(interval_us_local*1000/N_SYM_PER_SLOT);
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index dc40ad9..1b88013 100644
--- a/fhi_lib/lib/src/xran_common.c
@@ -1032,7 +1081,7 @@ index 4acade1..c939edc 100644
for(i = 0; i < xran_ports_num; i++){
g_xran_dev_ctx[i] = pCtx;
diff --git a/fhi_lib/lib/src/xran_dev.h b/fhi_lib/lib/src/xran_dev.h
index 0371a53..dd76b49 100644
index 0371a53..778b38d 100644
--- a/fhi_lib/lib/src/xran_dev.h
+++ b/fhi_lib/lib/src/xran_dev.h
@@ -201,6 +201,7 @@ struct __rte_cache_aligned xran_device_ctx
@@ -1043,6 +1092,18 @@ index 0371a53..dd76b49 100644
int64_t offset_sec;
int64_t offset_nsec; //offset to GPS time calcuated based on alpha and beta
uint32_t interval_us_local;
@@ -254,6 +255,11 @@ struct __rte_cache_aligned xran_device_ctx
int32_t sym_up; /**< when we start sym 0 of up with respect to OTA time as measured in symbols */
int32_t sym_up_ul;
+ /* used to support large T1a/Ta4 values */
+ int32_t offset_num_slots_cp_dl;
+ int32_t offset_num_slots_cp_ul;
+ int32_t offset_num_slots_up_ul;
+
xran_fh_tti_callback_fn ttiCb[XRAN_CB_MAX];
void *TtiCbParam[XRAN_CB_MAX];
uint32_t SkipTti[XRAN_CB_MAX];
diff --git a/fhi_lib/lib/src/xran_frame_struct.c b/fhi_lib/lib/src/xran_frame_struct.c
index fbb1298..44aaf92 100644
--- a/fhi_lib/lib/src/xran_frame_struct.c
@@ -1082,7 +1143,7 @@ index 7ed0a3a..8e66945 100644
#ifdef __cplusplus
}
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 7c472d7..7c7cf91 100644
index 7c472d7..db03d94 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -35,7 +35,11 @@
@@ -1132,7 +1193,42 @@ index 7c472d7..7c7cf91 100644
print_dbg("PRACH eAxC_offset %d\n", pPrachCPConfig->eAxC_offset);
/* Save some configs for app */
@@ -1169,6 +1192,10 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
@@ -623,6 +646,8 @@ xran_prepare_cp_dl_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
return ret;
}
+uint32_t prev_dl_tti = -1;
+
void
tx_cp_dl_cb(struct rte_timer *tim, void *arg)
{
@@ -655,7 +680,7 @@ tx_cp_dl_cb(struct rte_timer *tim, void *arg)
if(first_call && p_xran_dev_ctx->enableCP)
{
- tti = pTCtx[(xran_lib_ota_tti[PortId] & 1) ^ 1].tti_to_process;
+ tti = pTCtx[(xran_lib_ota_tti[PortId] & 1) ^ 1].tti_to_process + p_xran_dev_ctx->offset_num_slots_cp_dl;
buf_id = tti % XRAN_N_FE_BUF_LEN;
slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME(interval_us_local));
@@ -665,6 +690,16 @@ tx_cp_dl_cb(struct rte_timer *tim, void *arg)
{
/* Wrap around to next second */
frame_id = (frame_id + NUM_OF_FRAMES_PER_SECOND) & 0x3ff;
+ prev_dl_tti = -1;
+ }
+ else if (p_xran_dev_ctx->offset_num_slots_cp_dl > 0 && prev_dl_tti == xran_fs_get_max_slot(PortId) - 1 + p_xran_dev_ctx->offset_num_slots_cp_dl)
+ {
+ prev_dl_tti = tti;
+ tti = xran_fs_get_max_slot(PortId) + p_xran_dev_ctx->offset_num_slots_cp_dl;
+ }
+ else
+ {
+ prev_dl_tti = tti;
}
ctx_id = tti % XRAN_MAX_SECTIONDB_CTX;
@@ -1169,6 +1204,10 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
@@ -1143,7 +1239,45 @@ index 7c472d7..7c7cf91 100644
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
frame_id, subframe_id, slot_id, tti,
beam_id, cc_id, port_id, occasionid, seqid);
@@ -1338,6 +1365,10 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg)
@@ -1213,6 +1252,7 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
return ret;
}
+uint32_t prev_ul_tti = -1;
void
tx_cp_ul_cb(struct rte_timer *tim, void *arg)
@@ -1254,7 +1294,7 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg)
pTCtx = &p_xran_dev_ctx->timer_ctx[0];
interval = p_xran_dev_ctx->interval_us_local;
PortId = p_xran_dev_ctx->xran_port_id;
- tti = pTCtx[(xran_lib_ota_tti[PortId] & 1) ^ 1].tti_to_process;
+ tti = pTCtx[(xran_lib_ota_tti[PortId] & 1) ^ 1].tti_to_process + p_xran_dev_ctx->offset_num_slots_cp_ul;
buf_id = tti % XRAN_N_FE_BUF_LEN;
ctx_id = tti % XRAN_MAX_SECTIONDB_CTX;
@@ -1264,7 +1304,20 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg)
/* Wrap around to next second */
if(tti == 0)
+ {
frame_id = (frame_id + NUM_OF_FRAMES_PER_SECOND) & 0x3ff;
+ prev_ul_tti = tti;
+ }
+ else if (p_xran_dev_ctx->offset_num_slots_cp_ul > 0 && prev_ul_tti == xran_fs_get_max_slot(PortId) - 1 + p_xran_dev_ctx->offset_num_slots_cp_ul)
+ {
+ prev_ul_tti = tti;
+ tti = xran_fs_get_max_slot(PortId) + p_xran_dev_ctx->offset_num_slots_cp_ul;
+ }
+ else
+ {
+ prev_ul_tti = tti;
+ }
+
if(xran_get_ru_category(pHandle) == XRAN_CATEGORY_A)
num_eAxc = xran_get_num_eAxc(pHandle);
else
@@ -1338,6 +1391,10 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg)
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
@@ -1154,7 +1288,7 @@ index 7c472d7..7c7cf91 100644
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
frame_id, subframe_id, slot_id, tti,
beam_id, cc_id, port_id, occasionid, seqid);
@@ -1570,6 +1601,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
@@ -1570,6 +1627,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
{
case ECPRI_IQ_DATA:
pkt_data[num_data++] = pkt;
@@ -1162,7 +1296,7 @@ index 7c472d7..7c7cf91 100644
break;
// For RU emulation
case ECPRI_RT_CONTROL_DATA:
@@ -1587,7 +1619,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
@@ -1587,7 +1645,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
break;
default:
if (p_dev_ctx->fh_init.io_cfg.id == O_DU) {
@@ -1171,7 +1305,7 @@ index 7c472d7..7c7cf91 100644
}
break;
}
@@ -1876,7 +1908,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI
@@ -1876,7 +1934,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI
for (i = 0; i < nNumInstances; i++) {
/* Allocate Memory for CC handles */
@@ -1180,7 +1314,7 @@ index 7c472d7..7c7cf91 100644
if(pCcHandle == NULL)
return XRAN_STATUS_RESOURCE;
@@ -2347,8 +2379,7 @@ ring_processing_func_per_port(void* args)
@@ -2347,8 +2405,7 @@ ring_processing_func_per_port(void* args)
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) {
if (ctx->vf2xran_port[i] == port_id) {
for(qi = 0; qi < ctx->rxq_per_port[port_id]; qi++){
@@ -1190,7 +1324,7 @@ index 7c472d7..7c7cf91 100644
}
}
}
@@ -2414,9 +2445,6 @@ xran_spawn_workers(void)
@@ -2414,9 +2471,6 @@ xran_spawn_workers(void)
nWorkerCore = nWorkerCore << 1;
}
@@ -1200,7 +1334,7 @@ index 7c472d7..7c7cf91 100644
printf("O-XU %d\n", eth_ctx->io_cfg.id);
printf("HW %d\n", icx_cpu);
printf("Num cores %d\n", total_num_cores);
@@ -2453,7 +2481,7 @@ xran_spawn_workers(void)
@@ -2453,7 +2507,7 @@ xran_spawn_workers(void)
eth_ctx->time_wrk_cfg.arg = NULL;
eth_ctx->time_wrk_cfg.state = 1;
@@ -1209,7 +1343,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2475,7 +2503,7 @@ xran_spawn_workers(void)
@@ -2475,7 +2529,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1218,7 +1352,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2502,7 +2530,7 @@ xran_spawn_workers(void)
@@ -2502,7 +2556,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1227,7 +1361,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2536,7 +2564,7 @@ xran_spawn_workers(void)
@@ -2536,7 +2590,7 @@ xran_spawn_workers(void)
else
p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt;
@@ -1236,7 +1370,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2559,7 +2587,7 @@ xran_spawn_workers(void)
@@ -2559,7 +2613,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1245,7 +1379,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2586,7 +2614,7 @@ xran_spawn_workers(void)
@@ -2586,7 +2640,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1254,7 +1388,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2613,7 +2641,7 @@ xran_spawn_workers(void)
@@ -2613,7 +2667,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1263,7 +1397,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2628,7 +2656,7 @@ xran_spawn_workers(void)
@@ -2628,7 +2682,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1272,7 +1406,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2643,7 +2671,7 @@ xran_spawn_workers(void)
@@ -2643,7 +2697,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1281,7 +1415,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2682,7 +2710,7 @@ xran_spawn_workers(void)
@@ -2682,7 +2736,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1290,7 +1424,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2697,7 +2725,7 @@ xran_spawn_workers(void)
@@ -2697,7 +2751,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1299,7 +1433,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2712,7 +2740,7 @@ xran_spawn_workers(void)
@@ -2712,7 +2766,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1308,7 +1442,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2727,7 +2755,7 @@ xran_spawn_workers(void)
@@ -2727,7 +2781,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1317,7 +1451,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2766,7 +2794,7 @@ xran_spawn_workers(void)
@@ -2766,7 +2820,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1326,7 +1460,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2781,7 +2809,7 @@ xran_spawn_workers(void)
@@ -2781,7 +2835,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 Eth Tx **/
@@ -1335,7 +1469,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
@@ -2797,7 +2825,7 @@ xran_spawn_workers(void)
@@ -2797,7 +2851,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 - CP GEN **/
@@ -1344,7 +1478,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2812,7 +2840,7 @@ xran_spawn_workers(void)
@@ -2812,7 +2866,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1353,7 +1487,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2827,7 +2855,7 @@ xran_spawn_workers(void)
@@ -2827,7 +2881,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 UP GEN **/
@@ -1362,7 +1496,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2861,7 +2889,7 @@ xran_spawn_workers(void)
@@ -2861,7 +2915,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1371,7 +1505,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2876,7 +2904,7 @@ xran_spawn_workers(void)
@@ -2876,7 +2930,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1380,7 +1514,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2891,7 +2919,7 @@ xran_spawn_workers(void)
@@ -2891,7 +2945,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1389,7 +1523,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2906,7 +2934,7 @@ xran_spawn_workers(void)
@@ -2906,7 +2960,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1398,7 +1532,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2921,7 +2949,7 @@ xran_spawn_workers(void)
@@ -2921,7 +2975,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1407,7 +1541,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2969,7 +2997,7 @@ xran_spawn_workers(void)
@@ -2969,7 +3023,7 @@ xran_spawn_workers(void)
/* p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; */
@@ -1416,7 +1550,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3004,7 +3032,7 @@ xran_spawn_workers(void)
@@ -3004,7 +3058,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1425,7 +1559,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3031,7 +3059,7 @@ xran_spawn_workers(void)
@@ -3031,7 +3085,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1434,7 +1568,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3062,7 +3090,7 @@ xran_spawn_workers(void)
@@ -3062,7 +3116,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1443,7 +1577,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3089,7 +3117,7 @@ xran_spawn_workers(void)
@@ -3089,7 +3143,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1452,7 +1586,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3115,7 +3143,7 @@ xran_spawn_workers(void)
@@ -3115,7 +3169,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1461,7 +1595,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3130,7 +3158,7 @@ xran_spawn_workers(void)
@@ -3130,7 +3184,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1470,7 +1604,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3145,7 +3173,7 @@ xran_spawn_workers(void)
@@ -3145,7 +3199,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1479,7 +1613,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3184,7 +3212,7 @@ xran_spawn_workers(void)
@@ -3184,7 +3238,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 FH RX and BBDEV */
@@ -1488,7 +1622,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3199,7 +3227,7 @@ xran_spawn_workers(void)
@@ -3199,7 +3253,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1497,7 +1631,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3214,7 +3242,7 @@ xran_spawn_workers(void)
@@ -3214,7 +3268,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1506,7 +1640,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3229,7 +3257,7 @@ xran_spawn_workers(void)
@@ -3229,7 +3283,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1515,7 +1649,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3266,7 +3294,7 @@ xran_spawn_workers(void)
@@ -3266,7 +3320,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1524,7 +1658,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3281,7 +3309,7 @@ xran_spawn_workers(void)
@@ -3281,7 +3335,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1533,7 +1667,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3296,7 +3324,7 @@ xran_spawn_workers(void)
@@ -3296,7 +3350,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1542,7 +1676,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3311,7 +3339,7 @@ xran_spawn_workers(void)
@@ -3311,7 +3365,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1551,7 +1685,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3326,7 +3354,7 @@ xran_spawn_workers(void)
@@ -3326,7 +3380,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 UP GEN **/
@@ -1560,7 +1694,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3348,7 +3376,7 @@ xran_spawn_workers(void)
@@ -3348,7 +3402,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1569,7 +1703,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3363,7 +3391,7 @@ xran_spawn_workers(void)
@@ -3363,7 +3417,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1578,7 +1712,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3378,7 +3406,7 @@ xran_spawn_workers(void)
@@ -3378,7 +3432,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1587,7 +1721,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3393,7 +3421,7 @@ xran_spawn_workers(void)
@@ -3393,7 +3447,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1596,7 +1730,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3408,7 +3436,7 @@ xran_spawn_workers(void)
@@ -3408,7 +3462,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1605,7 +1739,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3435,7 +3463,7 @@ xran_spawn_workers(void)
@@ -3435,7 +3489,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1614,7 +1748,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3450,7 +3478,7 @@ xran_spawn_workers(void)
@@ -3450,7 +3504,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1623,7 +1757,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3465,7 +3493,7 @@ xran_spawn_workers(void)
@@ -3465,7 +3519,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1632,7 +1766,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3480,7 +3508,7 @@ xran_spawn_workers(void)
@@ -3480,7 +3534,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1641,7 +1775,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3495,7 +3523,7 @@ xran_spawn_workers(void)
@@ -3495,7 +3549,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 FH RX and BBDEV */
@@ -1650,7 +1784,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3510,7 +3538,7 @@ xran_spawn_workers(void)
@@ -3510,7 +3564,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1659,7 +1793,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3537,7 +3565,7 @@ xran_spawn_workers(void)
@@ -3537,7 +3591,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1668,7 +1802,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3562,7 +3590,7 @@ xran_spawn_workers(void)
@@ -3562,7 +3616,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1677,7 +1811,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3577,7 +3605,7 @@ xran_spawn_workers(void)
@@ -3577,7 +3631,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1686,7 +1820,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3602,7 +3630,7 @@ xran_spawn_workers(void)
@@ -3602,7 +3656,7 @@ xran_spawn_workers(void)
}
/** 3 UP GEN **/
@@ -1695,7 +1829,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3627,7 +3655,7 @@ xran_spawn_workers(void)
@@ -3627,7 +3681,7 @@ xran_spawn_workers(void)
}
/** 4 UP GEN **/
@@ -1704,7 +1838,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3642,7 +3670,7 @@ xran_spawn_workers(void)
@@ -3642,7 +3696,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 5 UP GEN **/
@@ -1713,7 +1847,7 @@ index 7c472d7..7c7cf91 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3754,6 +3782,7 @@ xran_open(void *pHandle, struct xran_fh_config* pConf)
@@ -3754,6 +3808,7 @@ xran_open(void *pHandle, struct xran_fh_config* pConf)
p_xran_dev_ctx->puschMaskSlot = pConf->puschMaskSlot;
p_xran_dev_ctx->DynamicSectionEna = pConf->DynamicSectionEna;
p_xran_dev_ctx->RunSlotPrbMapBySymbolEnable = pConf->RunSlotPrbMapBySymbolEnable;
@@ -1721,7 +1855,7 @@ index 7c472d7..7c7cf91 100644
p_xran_dev_ctx->dssEnable = pConf->dssEnable;
p_xran_dev_ctx->dssPeriod = pConf->dssPeriod;
for(i=0; i<pConf->dssPeriod; i++) {
@@ -4034,6 +4063,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
@@ -4034,6 +4089,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
return tti;
}
@@ -1746,7 +1880,7 @@ index 7c472d7..7c7cf91 100644
int32_t
xran_set_debug_stop(int32_t value, int32_t count)
{
@@ -4208,7 +4255,7 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
@@ -4208,7 +4281,7 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
int32_t i = 0, j = 0, nPrbElm = 0;
int16_t iqwidth = p_PrbMapIn->prbMap[0].iqWidth;
struct xran_prb_elm *p_prb_elm_src, *p_prb_elm_dst;
@@ -1755,7 +1889,7 @@ index 7c472d7..7c7cf91 100644
int32_t nRBStart_tmp, nRBremain, nStartSymb, nEndSymb, nRBStart, nRBEnd, nRBSize;
// int32_t eth_xran_up_headers_sz = sizeof(struct eth_xran_up_pkt_hdr);
// int32_t nmaxRB = (mtu - eth_xran_up_headers_sz - RTE_PKTMBUF_HEADROOM)/XRAN_PAYLOAD_1_RB_SZ(iqwidth);
@@ -4217,7 +4264,6 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
@@ -4217,7 +4290,6 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
if (mtu==9600)
nmaxRB--; //for some reason when mtu is 9600, only 195 RB can be sent, not 196
@@ -1763,7 +1897,7 @@ index 7c472d7..7c7cf91 100644
memcpy(p_PrbMapOut, p_PrbMapIn, sizeof(struct xran_prb_map));
for(i = 0; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++)
{
@@ -4292,26 +4338,30 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
@@ -4292,26 +4364,30 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
for(; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++)
{
@@ -2045,7 +2179,7 @@ index 72249bc..6b30084 100644
#include <rte_config.h>
diff --git a/fhi_lib/lib/src/xran_tx_proc.c b/fhi_lib/lib/src/xran_tx_proc.c
index 45a17a8..85ce6fa 100644
index 45a17a8..cca2dcc 100644
--- a/fhi_lib/lib/src/xran_tx_proc.c
+++ b/fhi_lib/lib/src/xran_tx_proc.c
@@ -35,7 +35,11 @@
@@ -2060,7 +2194,19 @@ index 45a17a8..85ce6fa 100644
#include <rte_common.h>
#include <rte_eal.h>
@@ -1514,7 +1518,11 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32
@@ -1399,6 +1403,11 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32
if(0!=ptr_sect_elm->cur_index)
{
+ /* prevent xran from sending DL U-plane packets when it should not */
+ if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU && xran_fs_get_slot_type(xran_port_id, 0, tti, XRAN_SLOT_TYPE_DL) != 1)
+ {
+ return 0;
+ }
num_sections = ptr_sect_elm->cur_index;
/* iterate C-Plane configuration to generate corresponding U-Plane */
vf_id = p_xran_dev_ctx->map2vf[direction][cc_id][ant_id][XRAN_UP_VF];
@@ -1514,7 +1523,11 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32
mb_oran_hdr_ext->buf_addr = ext_buff;
mb_oran_hdr_ext->buf_iova = ((struct rte_mempool_objhdr*)RTE_PTR_SUB(mb_base, rte_mempool_objhdr_size))->iova + RTE_PTR_DIFF(ext_buff, mb_base);
mb_oran_hdr_ext->buf_len = ext_buff_len;
@@ -2072,7 +2218,7 @@ index 45a17a8..85ce6fa 100644
mb_oran_hdr_ext->shinfo = p_share_data;
mb_oran_hdr_ext->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM, (uint16_t)mb_oran_hdr_ext->buf_len) - rte_ether_hdr_size;
mb_oran_hdr_ext->data_len = (uint16_t)(mb_oran_hdr_ext->data_len + rte_ether_hdr_size);
@@ -1532,8 +1540,13 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32
@@ -1532,8 +1545,13 @@ xran_process_tx_sym_cp_on_opt(void* pHandle, uint8_t ctx_id, uint32_t tti, int32
/* Fill in the ethernet header. */
#ifndef TRANSMIT_BURST
@@ -2086,7 +2232,7 @@ index 45a17a8..85ce6fa 100644
((struct rte_ether_hdr*)pStart)->ether_type = ETHER_TYPE_ECPRI_BE; /* ethertype */
#endif
nPktSize = sizeof(struct rte_ether_hdr)
@@ -1878,7 +1891,11 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s
@@ -1878,7 +1896,11 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s
mb_oran_hdr_ext->buf_addr = ext_buff;
mb_oran_hdr_ext->buf_iova = ((struct rte_mempool_objhdr*)RTE_PTR_SUB(mb_base, rte_mempool_objhdr_size))->iova + RTE_PTR_DIFF(ext_buff, mb_base);
mb_oran_hdr_ext->buf_len = ext_buff_len;
@@ -2098,7 +2244,7 @@ index 45a17a8..85ce6fa 100644
mb_oran_hdr_ext->shinfo = p_share_data;
mb_oran_hdr_ext->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM, (uint16_t)mb_oran_hdr_ext->buf_len) - rte_ether_hdr_size;
mb_oran_hdr_ext->data_len = (uint16_t)(mb_oran_hdr_ext->data_len + rte_ether_hdr_size);
@@ -1887,8 +1904,13 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s
@@ -1887,8 +1909,13 @@ xran_process_tx_srs_cp_on(void* pHandle, uint8_t ctx_id, uint32_t tti, int32_t s
pStart = (char*)((char*)mb_oran_hdr_ext->buf_addr + mb_oran_hdr_ext->data_off);
/* Fill in the ethernet header. */

View File

@@ -319,6 +319,32 @@ int config_libconfig_set(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
}
}
static const char *config_type_to_name(int type)
{
switch (type) {
case CONFIG_TYPE_NONE:
return "none";
case CONFIG_TYPE_GROUP:
return "group";
case CONFIG_TYPE_INT:
return "integer";
case CONFIG_TYPE_INT64:
return "64-bit integer";
case CONFIG_TYPE_FLOAT:
return "float";
case CONFIG_TYPE_STRING:
return "string";
case CONFIG_TYPE_BOOL:
return "boolean";
case CONFIG_TYPE_ARRAY:
return "array";
case CONFIG_TYPE_LIST:
return "list";
default:
return "unknown";
}
}
int config_libconfig_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix)
{
config_setting_t *setting;
@@ -348,17 +374,26 @@ int config_libconfig_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
switch(cfgoptions[i].type) {
case TYPE_STRING:
if ( config_lookup_string(&(libconfig_privdata.cfg), cfgpath, (const char**)&str)) {
config_check_valptr(cfg, &cfgoptions[i], 1, strlen(str) + 1);
if ( strlen(str)+1 > cfgoptions[i].numelt )
fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
cfgpath,str,cfgoptions[i].numelt);
snprintf( *cfgoptions[i].strptr , cfgoptions[i].numelt, "%s", str);
printf_params(cfg, "[LIBCONFIG] %s: \"%s\"\n", cfgpath, *cfgoptions[i].strptr);
} else {
setting = config_lookup(&(libconfig_privdata.cfg), cfgpath);
if (setting != NULL) {
int type = config_setting_type(setting);
if (type == CONFIG_TYPE_STRING) {
const char *strng = config_setting_get_string(setting);
config_check_valptr(cfg, &cfgoptions[i], 1, strlen(strng) + 1);
if (strlen(strng) + 1 > cfgoptions[i].numelt)
fprintf(stderr,
"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
cfgpath,
strng,
cfgoptions[i].numelt);
snprintf(*cfgoptions[i].strptr, cfgoptions[i].numelt, "%s", strng);
printf_params(cfg, "[LIBCONFIG] %s: \"%s\"\n", cfgpath, *cfgoptions[i].strptr);
} else {
fprintf(stderr,"[LIBCONFIG] expected a string input for %s but got type %s\n", cfgpath, config_type_to_name(type));
fatalerror = 1;
}
} else
defval = config_common_getdefault(cfg, &cfgoptions[i], prefix);
}
break;
case TYPE_STRINGLIST:

View File

@@ -719,7 +719,37 @@ RU must be rebooted so the changes apply.
- The measured throughput was **520 Mbps DL** and **40 Mbps UL**.
- With newer OAI versions, throughput degrades. This issue is currently under investigation.
### Configure Network Interfaces and DPDK VFs
#### ProtO-RU
[ProtO-RU](https://github.com/NUS-CIR/ProtO-RU) is a software implementation of an O-RAN 7.2 RU using a NI USRP.
Different from other COTS RUs, ProtO-RU requires a larger DU delay profile which is larger than the TTI interval.
The OAI configuration file [`gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf) corresponds to:
- TDD pattern `DDDSU`, 2.5ms
- Bandwidth 40MHz
- MTU 9216
- 1T1R
##### RU configuration
First, compile the RU as outlined in the [building ProtO-RU tutorial](https://github.com/NUS-CIR/ProtO-RU/tree/proto-ru?tab=readme-ov-file#building-proto-ru).
Then, ensure that both your DU and ProtO-RU host are PTP synchronized.
Next, use the RU config, [protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml](https://github.com/NUS-CIR/ProtO-RU/blob/proto-ru/proto-ru/conf-files/protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml), which corresponds to the above mentioned DU config file.
In addition, please adapt the DU MAC address and VLAN tag to your needs.
ProtO-RU was successfully tested with USRP B210.
If you are using a different SDR (e.g., N310), you will need to update the ProtO-RU and the DU configurations accordingly.
Launch ProtO-RU with the adapted configuration file with the command:
```bash
sudo ./ru_emulator -c <path-to/protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml>
```
Finally, start the OAI gNB.
## Configure Network Interfaces and DPDK VFs
The 7.2 fronthaul uses the xran library, which requires DPDK. In this step, we
need to configure network interfaces to send data to the RU, and configure DPDK

View File

@@ -26,7 +26,7 @@
#---------------------------------------------------------------------
FROM registry.access.redhat.com/ubi9/ubi:latest AS ran-base
FROM registry.redhat.io/ubi9/ubi:latest AS ran-base
LABEL MAINTAINER OpenAirInterface <contact@openairinterface.org>
ARG NEEDED_GIT_PROXY
ARG TARGETARCH

View File

@@ -31,7 +31,7 @@ FROM ran-build:latest AS enb-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-enb
FROM registry.redhat.io/ubi9/ubi:latest AS oai-enb
ENV TZ=Europe/Paris
RUN dnf update -y && \

View File

@@ -38,7 +38,7 @@ RUN /bin/sh oaienv && \
./build_oai -w AW2SORI -t Ethernet
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb-aw2s
FROM registry.redhat.io/ubi9/ubi:latest AS oai-gnb-aw2s
ENV TZ=Europe/Paris
# Install EPEL for RHEL9

View File

@@ -30,7 +30,7 @@ FROM ran-base:latest AS gnb-base
FROM ran-build-fhi72:latest AS gnb-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb-fhi72
FROM registry.redhat.io/ubi9/ubi:latest AS oai-gnb-fhi72
ENV TZ=Europe/Paris
# Install EPEL for RHEL9

View File

@@ -31,7 +31,7 @@ FROM ran-build:latest AS gnb-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb
FROM registry.redhat.io/ubi9/ubi:latest AS oai-gnb
ENV TZ=Europe/Paris
# Install EPEL for RHEL9

View File

@@ -31,7 +31,7 @@ FROM ran-build:latest AS ru-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-lte-ru
FROM registry.redhat.io/ubi9/ubi:latest AS oai-lte-ru
ENV TZ=Europe/Paris
RUN dnf update -y && \

View File

@@ -31,7 +31,7 @@ FROM ran-build:latest AS lte-ue-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-lte-ue
FROM registry.redhat.io/ubi9/ubi:latest AS oai-lte-ue
ENV TZ=Europe/Paris
RUN dnf update -y && \

View File

@@ -32,7 +32,7 @@ FROM ran-build:latest AS gnb-build
RUN cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-nr-cuup
FROM registry.redhat.io/ubi9/ubi:latest AS oai-nr-cuup
ENV TZ=Europe/Paris
# Install EPEL

View File

@@ -31,7 +31,7 @@ FROM ran-build:latest AS nr-ue-build
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-nr-ue
FROM registry.redhat.io/ubi9/ubi:latest AS oai-nr-ue
ENV TZ=Europe/Paris
# Install EPEL for RHEL9

View File

@@ -46,7 +46,7 @@ RUN /bin/sh oaienv && \
ninja -k10 -j36
#start from scratch for target executable
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-physim
FROM registry.redhat.io/ubi9/ubi:latest AS oai-physim
RUN dnf update -y && \
dnf install -y \

View File

@@ -675,11 +675,28 @@ int main( int argc, char **argv ) {
wait_nfapi_init("main?");
}
if (IS_SOFTMODEM_IMSCOPE_ENABLED || IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
sleep(1);
scopeParms_t p;
p.argc = &argc;
p.argv = argv;
p.gNB = RC.gNB[0];
p.ru = RC.ru[0];
if (IS_SOFTMODEM_IMSCOPE_ENABLED) {
load_softscope("im", &p);
}
AssertFatal(!(IS_SOFTMODEM_IMSCOPE_ENABLED && IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED),
"Data recoding and ImScope cannot be enabled at the same time\n");
if (IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
load_module_shlib("imscope_record", NULL, 0, &p);
}
}
if (RC.nb_nr_L1_inst > 0) {
wait_RUs();
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
if (IS_SOFTMODEM_DOSCOPE || IS_SOFTMODEM_IMSCOPE_ENABLED || IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
if (IS_SOFTMODEM_DOSCOPE) {
sleep(1);
scopeParms_t p;
p.argc = &argc;
@@ -689,14 +706,6 @@ int main( int argc, char **argv ) {
if (IS_SOFTMODEM_DOSCOPE) {
load_softscope("nr", &p);
}
if (IS_SOFTMODEM_IMSCOPE_ENABLED) {
load_softscope("im", &p);
}
AssertFatal(!(IS_SOFTMODEM_IMSCOPE_ENABLED && IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED),
"Data recoding and ImScope cannot be enabled at the same time\n");
if (IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
load_module_shlib("imscope_record", NULL, 0, &p);
}
}
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF && NFAPI_MODE != NFAPI_MODE_AERIAL) {

View File

@@ -63,6 +63,10 @@ char cpu_buf_recv[RECV_BUF_LEN];
uint16_t sfn = 0, slot = 0;
nv_ipc_t *ipc;
static nv_ipc_config_t nv_ipc_config;
static int cpu_msg_buf_size = 0;
static int cpu_data_buf_size = 0;
void nvIPC_Stop()
{
LOG_I(NR_MAC, "Received STOP.indication\n");
@@ -95,7 +99,7 @@ static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
nfapi_vnf_config_t * vnf_config = get_config();
if (vnf_config != 0) {
// first, unpack the header
fapi_phy_api_msg fapi_msg;
fapi_message_header_t fapi_msg;
if (!(pull8(&pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg.opaque_handle, end)
&& pull16(&pReadPackedMessage, &fapi_msg.message_id, end)
&& pull32(&pReadPackedMessage, &fapi_msg.message_length, end))) {
@@ -195,267 +199,78 @@ static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
return 0;
}
int8_t buf[1024];
int get_cpu_msg_buf_size()
{
return cpu_msg_buf_size;
}
int get_cpu_data_buf_size()
{
return cpu_data_buf_size;
}
nv_ipc_config_t nv_ipc_config;
bool allocate_msg(nv_ipc_msg_t *send_msg)
{
return ipc->tx_allocate(ipc, send_msg, 0) == 0;
}
void release_msg(nv_ipc_msg_t *send_msg)
{
ipc->tx_release(ipc, send_msg);
}
bool send_nvipc_msg(nv_ipc_msg_t *send_msg)
{
int send_retval = ipc->tx_send_msg(ipc, send_msg);
if (send_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, send_msg);
return false;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return true;
}
bool aerial_nr_send_p5_message(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len)
{
nfapi_vnf_pnf_info_t *pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
if (pnf) {
uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)];
// Create the message
nv_ipc_msg_t send_msg = {.msg_id = msg->message_id,
.cell_id = 0,
// For P5 we don't need CPU_DATA
.data_pool = NV_IPC_MEMPOOL_CPU_MSG,
.data_len = 0,
.data_buf = NULL};
// Allocate the message
if (!allocate_msg(&send_msg)) {
return false;
}
int packedMessageLengthFAPI = -1;
packedMessageLengthFAPI =
vnf->_public.pack_func(msg, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config);
return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg) == 0;
// Pack directly into it
if ((packedMessageLengthFAPI =
vnf->_public.pack_func(msg, msg_len, send_msg.msg_buf, get_cpu_msg_buf_size(), &vnf->_public.codec_config))
< 0) {
release_msg(&send_msg);
return false;
}
if (packedMessageLengthFAPI <= 0) {
LOG_E(NFAPI_VNF, "Error packing message 0x%02x\n", msg->message_id);
release_msg(&send_msg);
return false;
}
// Set the length
send_msg.msg_len = packedMessageLengthFAPI + 8; // adding 8 to account for the size of the FAPI header
// Send
return send_nvipc_msg(&send_msg);
} else {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
return false;
}
}
bool aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p4_p5_message_header_t *header)
{
if (ipc == NULL) {
return false;
}
nv_ipc_msg_t send_msg = {0};
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
// if(config && config->pack_p4_p5_vendor_extension) {
// result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
// } else {
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
// }
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return true;
}
bool aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p7_message_header_t *header)
{
if (ipc == NULL) {
return false;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
case 0x8f:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return true;
}
bool aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_nr_p7_message_header_t *header)
{
if (ipc == NULL) {
return false;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = dataLength;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return false;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return true;
}
// Always allocate message buffer, but allocate data buffer only when data_len > 0
static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg)
{
@@ -568,6 +383,10 @@ int nvIPC_Init(nvipc_params_t nvipc_params_s)
{
// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller)
load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM);
// save the mempool sizes for later use in packing
cpu_msg_buf_size = nv_ipc_get_buf_size(&nv_ipc_config, NV_IPC_MEMPOOL_CPU_MSG);
cpu_data_buf_size = nv_ipc_get_buf_size(&nv_ipc_config, NV_IPC_MEMPOOL_CPU_DATA);
// Create nv_ipc_t instance
LOG_I(NFAPI_VNF, "%s: creating IPC interface with prefix %s\n", __func__, nvipc_params_s.nvipc_shm_prefix);
strcpy(nv_ipc_config.transport_config.shm.prefix, nvipc_params_s.nvipc_shm_prefix);
@@ -588,10 +407,9 @@ int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req)
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
// int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
int retval = p7_config->send_p7_msg(get_p7_vnf(), &ul_tti_req->header);
bool retval = p7_config->send_p7_msg(get_p7_vnf(), &ul_tti_req->header);
if (retval != 0) {
if (!retval) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
// Reset number of PDUs so that it is not resent
@@ -608,9 +426,9 @@ int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req)
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
// int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
int retval = p7_config->send_p7_msg(get_p7_vnf(), &ul_dci_req->header);
if (retval != 0) {
bool retval = p7_config->send_p7_msg(get_p7_vnf(), &ul_dci_req->header);
if (!retval) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
ul_dci_req->numPdus = 0;
@@ -623,10 +441,9 @@ int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
// LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN),
// tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
int retval = p7_config->send_p7_msg(get_p7_vnf(), &tx_data_req->header);
if (retval != 0) {
bool retval = p7_config->send_p7_msg(get_p7_vnf(), &tx_data_req->header);
if (!retval) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
tx_data_req->Number_of_PDUs = 0;
@@ -640,11 +457,12 @@ int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = p7_config->send_p7_msg(get_p7_vnf(), &dl_config_req->header);
bool retval = p7_config->send_p7_msg(get_p7_vnf(), &dl_config_req->header);
dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nGroup = 0;
if (retval != 0) {
if (!retval) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;
@@ -653,8 +471,9 @@ int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
nfapi_nr_slot_indication_scf_t nr_slot_resp = {.header.message_id = 0x8F, .sfn = frame, .slot = slot};
int retval = p7_config->send_p7_msg(get_p7_vnf(), &nr_slot_resp.header);
if (retval != 0) {
bool retval = p7_config->send_p7_msg(get_p7_vnf(), &nr_slot_resp.header);
if (!retval) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;

View File

@@ -41,22 +41,12 @@
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
typedef struct {
uint8_t num_msg;
uint8_t opaque_handle;
uint16_t message_id;
uint32_t message_length;
} fapi_phy_api_msg;
int get_cpu_msg_buf_size();
int get_cpu_data_buf_size();
bool allocate_msg(nv_ipc_msg_t* send_msg);
void release_msg(nv_ipc_msg_t* send_msg);
bool send_nvipc_msg(nv_ipc_msg_t* send_msg);
bool aerial_nr_send_p5_message(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len);
bool aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p4_p5_message_header_t *header);
bool aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p7_message_header_t *header);
bool aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_nr_p7_message_header_t *header);
int nvIPC_Init(nvipc_params_t nvipc_params_s);
int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot);
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);

View File

@@ -114,10 +114,10 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
void *pPackedBuf,
void *pDataBuf,
uint32_t packedBufLen,
uint32_t dataBufLen,
int32_t dataBufLen,
nfapi_p7_codec_config_t *config,
nfapi_vnf_p7_config_t *p7_config,
uint32_t *data_len)
int32_t *data_len)
{
if (pMessageBuf == NULL || pPackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
@@ -130,7 +130,7 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
uint8_t *pPackedDataField = &pDataPackedMessage[0];
uint8_t *pPackedDataFieldStart = &pDataPackedMessage[0];
uint8_t **ppWriteData = &pPackedDataField;
const uint32_t dataBufLen32 = (dataBufLen + 3) / 4;
const int32_t dataBufLen32 = (dataBufLen + 3) / 4;
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)pMessageHeader;
// Actual payloads are packed in a separate buffer
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
@@ -180,40 +180,67 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
return (int32_t)(pMessageHeader->message_length);
}
bool aerial_nr_send_p7_message(vnf_p7_t *vnf_p7, nfapi_nr_p7_message_header_t *header)
{
uint8_t FAPI_buffer[1024 * 64];
// Common to both cases, we can set it now
// In most cases we don't need the data pool, only the CPU_MSG
nv_ipc_msg_t send_msg = {.msg_id = header->message_id, .data_pool = NV_IPC_MEMPOOL_CPU_MSG, .cell_id = 0};
// Check if TX_DATA request, if true, need to pack to data_buf
if (header->message_id == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) {
// for this we need the secondary CPU_DATA pool
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
// Allocate the message after setting the data pool
if (!allocate_msg(&send_msg)) {
LOG_E(NFAPI_VNF, "Error in allocating nvipc message\n");
return false;
}
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)header;
uint64_t size = 0;
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; ++i) {
size += pNfapiMsg->pdu_list[i].PDU_length;
}
AssertFatal(size <= 1024 * 1024 * 2, "Message data larger than available buffer, tried to pack %" PRId64, size);
uint8_t FAPI_data_buffer[1024 * 1024 * 2]; // 2MB
uint32_t data_len = 0;
AssertFatal(size <= get_cpu_data_buf_size(), "Message data larger than available buffer, tried to pack %" PRId64, size);
int32_t data_len = 0;
int32_t len_FAPI = aerial_pack_tx_data_request(header,
FAPI_buffer,
FAPI_data_buffer,
sizeof(FAPI_buffer),
sizeof(FAPI_data_buffer),
send_msg.msg_buf,
send_msg.data_buf,
get_cpu_msg_buf_size(),
get_cpu_data_buf_size(),
&vnf_p7->_public.codec_config,
((nfapi_vnf_p7_config_t *)vnf_p7),
&data_len);
// Set both lengths
send_msg.msg_len = len_FAPI + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = data_len;
if (len_FAPI <= 0) {
LOG_E(NFAPI_VNF, "Problem packing TX_DATA_request\n");
release_msg(&send_msg);
return false;
} else {
return aerial_send_P7_msg_with_data(FAPI_buffer, len_FAPI, FAPI_data_buffer, data_len, header) == 0;
}
// Send
return send_nvipc_msg(&send_msg);
} else {
// Create and send FAPI P7 message
int len_FAPI = ((nfapi_vnf_p7_config_t *)vnf_p7)->pack_func(header,
FAPI_buffer,
sizeof(FAPI_buffer),
&vnf_p7->_public.codec_config);
return aerial_send_P7_msg(FAPI_buffer, len_FAPI, header) == 0;
send_msg.data_len = 0;
send_msg.data_buf = NULL;
// Allocate the message
if (!allocate_msg(&send_msg)) {
LOG_E(NFAPI_VNF, "Error in allocating nvipc message\n");
return false;
}
// Pack directly into it
nfapi_vnf_p7_config_t* p7_config = (nfapi_vnf_p7_config_t *)vnf_p7;
int len_FAPI = p7_config->pack_func(header, send_msg.msg_buf, get_cpu_msg_buf_size(), &vnf_p7->_public.codec_config);
if (len_FAPI <= 0) {
LOG_E(NFAPI_VNF, "Problem packing message 0x%02x\n", header->message_id);
release_msg(&send_msg);
return false;
}
// Set the length
send_msg.msg_len = len_FAPI + 8; // adding 8 to account for the size of the FAPI header
// Send
return send_nvipc_msg(&send_msg);
}
}

View File

@@ -228,7 +228,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
free_and_zero(meas->n0_subband_power);
free_and_zero(meas->n0_subband_power_dB);
for (int id = 0; id < gNB->max_nb_srs; id++) {
for(int i=0; i<MAX_NUM_NR_SRS_AP; i++) {

View File

@@ -105,36 +105,47 @@ void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
max_idx);
}
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
int min_I0=1000,max_I0=0;
int amin=0,amax=0;
fprintf(fd,"Blacklisted PRBs %d/%d\n",gNB->num_ulprbbl,gNB->frame_parms.N_RB_UL);
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
if (gNB->ulprbbl[i] > 0) continue;
if (gNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
if (gNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
void dump_nr_I0_stats(FILE *fd, PHY_VARS_gNB *gNB)
{
int min_I0 = 1000, max_I0 = 0;
int amin = 0, amax = 0;
fprintf(fd, "Blacklisted PRBs %d/%d\n", gNB->num_ulprbbl, gNB->frame_parms.N_RB_UL);
for (int i = 0; i < gNB->frame_parms.N_RB_UL; i++) {
if (gNB->ulprbbl[i] > 0)
continue;
if (gNB->measurements.n0_subband_power_tot_dB[i] < min_I0) {
min_I0 = gNB->measurements.n0_subband_power_tot_dB[i];
amin = i;
}
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
if (gNB->ulprbbl[i] ==0) fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
else fprintf(fd," X.");
if (i%25 == 24) fprintf(fd,"\n");
if (gNB->measurements.n0_subband_power_tot_dB[i] > max_I0) {
max_I0 = gNB->measurements.n0_subband_power_tot_dB[i];
amax = i;
}
fprintf(fd,"\n");
fprintf(fd,"max_IO = %d (%d), min_I0 = %d (%d), avg_I0 = %d dB",max_I0,amax,min_I0,amin,gNB->measurements.n0_subband_power_avg_dB);
if (gNB->frame_parms.nb_antennas_rx>1) {
fprintf(fd,"(");
for (int aarx=0;aarx<gNB->frame_parms.nb_antennas_rx;aarx++)
fprintf(fd,"%d.",gNB->measurements.n0_subband_power_avg_perANT_dB[aarx]);
fprintf(fd,")");
}
fprintf(fd,"\nPRACH I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
}
for (int i = 0; i < gNB->frame_parms.N_RB_UL; i++) {
if (gNB->ulprbbl[i] == 0)
fprintf(fd, "%2d.", gNB->measurements.n0_subband_power_tot_dB[i] - gNB->measurements.n0_subband_power_avg_dB);
else
fprintf(fd, " X.");
if (i % 25 == 24)
fprintf(fd, "\n");
}
fprintf(fd, "\n");
fprintf(fd,
"max_IO = %d (%d), min_I0 = %d (%d), avg_I0 = %d dB",
max_I0,
amax,
min_I0,
amin,
gNB->measurements.n0_subband_power_avg_dB);
if (gNB->frame_parms.nb_antennas_rx > 1) {
fprintf(fd, "(");
for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++)
fprintf(fd, "%d.", gNB->measurements.n0_subband_power_avg_perANT_dB[aarx]);
fprintf(fd, ")");
}
fprintf(fd, "\nPRACH I0 = %d.%d dB\n", gNB->measurements.prach_I0 / 10, gNB->measurements.prach_I0 % 10);
}
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9])
@@ -144,19 +155,8 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
int nb_symb[275]={0};
allocCast2D(n0_subband_power,
unsigned int,
gNB->measurements.n0_subband_power,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
clearArray(gNB->measurements.n0_subband_power, unsigned int);
allocCast2D(n0_subband_power_dB,
unsigned int,
gNB->measurements.n0_subband_power_dB,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
unsigned int tmp_n0_subband[frame_parms->nb_antennas_rx][frame_parms->N_RB_UL];
memset(tmp_n0_subband, 0, sizeof(tmp_n0_subband));
// TODO modify the measurements to take into account concurrent beams
for (int s = first_symb; s < first_symb + num_symb; s++) {
@@ -176,39 +176,46 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
} else {
signal_energy = signal_energy_nodc(ul_ch, 12);
}
n0_subband_power[aarx][rb] += signal_energy;
// noise power per antenna/RB, symbols summed up
tmp_n0_subband[aarx][rb] += signal_energy;
LOG_D(NR_PHY,"slot %d symbol %d RB %d aarx %d n0_subband_power %d\n", slot, s, rb, aarx, signal_energy);
} //antenna
}
} //rb
} // symb
int nb_rb=0;
int64_t n0_subband_tot=0;
int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT));
allocCast2D(n0_subband_power,
unsigned int,
measurements->n0_subband_power,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
for (int rb = 0 ; rb<frame_parms->N_RB_UL;rb++) {
int32_t n0_subband_tot_perPRB=0;
if (nb_symb[rb] > 0) {
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
n0_subband_power[aarx][rb] /= nb_symb[rb];
n0_subband_power_dB[aarx][rb] = dB_fixed(n0_subband_power[aarx][rb]);
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
tmp_n0_subband[aarx][rb] /= nb_symb[rb];
// apply exponential moving average to smooth noise measurements
n0_subband_power[aarx][rb] = 0.9 * n0_subband_power[aarx][rb] + 0.1 * tmp_n0_subband[aarx][rb];
n0_subband_tot_perPRB += n0_subband_power[aarx][rb];
n0_subband_tot_perANT[aarx] += n0_subband_power[aarx][rb];
}
n0_subband_tot_perPRB/=frame_parms->nb_antennas_rx;
n0_subband_tot_perPRB /= frame_parms->nb_antennas_rx;
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_subband_tot_perPRB);
measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
LOG_D(NR_PHY,"n0_subband_power_tot_dB[%d] => %d, over %d symbols\n",rb,measurements->n0_subband_power_tot_dB[rb],nb_symb[rb]);
n0_subband_tot += n0_subband_tot_perPRB;
nb_rb++;
}
}
if (nb_rb>0) {
measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot/nb_rb);
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
measurements->n0_subband_power_avg_perANT_dB[aarx] = dB_fixed(n0_subband_tot_perANT[aarx]/nb_rb);
}
int64_t n0_subband_tot = 0;
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
measurements->n0_subband_power_avg_perANT_dB[aarx] = dB_fixed(n0_subband_tot_perANT[aarx] / nb_rb);
n0_subband_tot += n0_subband_tot_perANT[aarx];
}
measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot / nb_rb);
}
}

View File

@@ -74,8 +74,6 @@ void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, ui
void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
#endif /* NR_ULSCH_H_ */

View File

@@ -1164,12 +1164,11 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
int max_ch = 0;
uint32_t nvar = 0;
int end_symbol = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols;
for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < end_symbol; symbol++) {
for (uint8_t symbol = rel15_ul->start_symbol_index; symbol < end_symbol; symbol++) {
uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag);
if (dmrs_symbol_flag == 1) {
if (dmrs_symbol_flag == 1) {
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++) {
uint32_t nvar_tmp = 0;
nr_pusch_channel_estimation(gNB,
@@ -1187,56 +1186,54 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
pusch_ch_est_dmrs_pos_slot_mem);
nvar += nvar_tmp;
}
allocCast2D(n0_subband_power,
unsigned int,
gNB->measurements.n0_subband_power,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
if (symbol == rel15_ul->start_symbol_index) {
pusch_vars->ulsch_power[aarx] = 0;
pusch_vars->ulsch_noise_power[aarx] = 0;
}
int64_t symb_energy = 0;
int start_sc = (rel15_ul->bwp_start + rel15_ul->rb_start) * NR_NB_SC_PER_RB;
int middle_sc = frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset;
int end_sc = (start_sc + rel15_ul->rb_size * NR_NB_SC_PER_RB - 1) % frame_parms->ofdm_symbol_size;
for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) {
int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size;
c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset];
if (end_sc < start_sc) {
int64_t symb_energy_aux = signal_energy_nodc(ul_ch, middle_sc - start_sc) * (middle_sc - start_sc);
ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset0];
symb_energy_aux += (signal_energy_nodc(ul_ch, end_sc + 1) * (end_sc + 1));
symb_energy += symb_energy_aux / (rel15_ul->rb_size * NR_NB_SC_PER_RB);
} else {
symb_energy += signal_energy_nodc(ul_ch, rel15_ul->rb_size * NR_NB_SC_PER_RB);
}
}
pusch_vars->ulsch_power[aarx] += (symb_energy / rel15_ul->nr_of_symbols);
pusch_vars->ulsch_noise_power[aarx] +=
average_u32(&n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start], rel15_ul->rb_size);
LOG_D(PHY,
"aa %d, bwp_start%d, rb_start %d, rb_size %d: ulsch_power %d, ulsch_noise_power %d\n",
aarx,
rel15_ul->bwp_start,
rel15_ul->rb_start,
rel15_ul->rb_size,
pusch_vars->ulsch_power[aarx],
pusch_vars->ulsch_noise_power[aarx]);
}
}
}
nvar /= (rel15_ul->nr_of_symbols * rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx);
allocCast2D(n0_subband_power,
unsigned int,
gNB->measurements.n0_subband_power,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
int start_sc = (rel15_ul->bwp_start + rel15_ul->rb_start) * NR_NB_SC_PER_RB;
int middle_sc = frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset;
int end_sc = (start_sc + rel15_ul->rb_size * NR_NB_SC_PER_RB - 1) % frame_parms->ofdm_symbol_size;
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
pusch_vars->ulsch_power[aarx] = 0;
pusch_vars->ulsch_noise_power[aarx] = 0;
int64_t symb_energy = 0;
for (uint8_t symbol = rel15_ul->start_symbol_index; symbol < end_symbol; symbol++) {
int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + symbol) * frame_parms->ofdm_symbol_size;
int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size;
c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset];
if (end_sc < start_sc) {
int64_t symb_energy_aux = signal_energy_nodc(ul_ch, middle_sc - start_sc) * (middle_sc - start_sc);
ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset0];
symb_energy_aux += (signal_energy_nodc(ul_ch, end_sc + 1) * (end_sc + 1));
symb_energy += symb_energy_aux / (rel15_ul->rb_size * NR_NB_SC_PER_RB);
} else {
symb_energy += signal_energy_nodc(ul_ch, rel15_ul->rb_size * NR_NB_SC_PER_RB);
}
}
pusch_vars->ulsch_power[aarx] += (symb_energy / rel15_ul->nr_of_symbols);
pusch_vars->ulsch_noise_power[aarx] +=
average_u32(&n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start], rel15_ul->rb_size);
LOG_D(PHY,
"aa %d, bwp_start%d, rb_start %d, rb_size %d: ulsch_power %d, ulsch_noise_power %d\n",
aarx,
rel15_ul->bwp_start,
rel15_ul->rb_start,
rel15_ul->rb_size,
pusch_vars->ulsch_power[aarx],
pusch_vars->ulsch_noise_power[aarx]);
}
// averaging time domain channel estimates
if (gNB->chest_time == 1)
nr_chest_time_domain_avg(frame_parms,

View File

@@ -41,7 +41,8 @@ extern "C" void imscope_autoinit(void *dataptr)
if (IS_SOFTMODEM_GNB) {
scopeParms_t *scope_params = (scopeParms_t *)dataptr;
scope_params->gNB->scopeData = scope;
scope_params->ru->scopeData = scope;
if (scope_params->ru)
scope_params->ru->scopeData = scope;
} else {
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)dataptr;
ue->scopeData = scope;

View File

@@ -340,16 +340,12 @@ typedef struct {
unsigned int n0_power_tot_dB;
//! estimated avg noise power per RB per RX ant (lin)
fourDimArray_t *n0_subband_power;
//! estimated avg noise power per RB per RX ant (dB)
fourDimArray_t *n0_subband_power_dB;
//! estimated avg subband noise power (dB)
unsigned int n0_subband_power_avg_dB;
//! estimated avg subband noise power per antenna (dB)
unsigned int n0_subband_power_avg_perANT_dB[MAX_ANT];
//! estimated avg noise power per RB (dB)
int n0_subband_power_tot_dB[275];
//! estimated avg noise power per RB (dBm)
int n0_subband_power_tot_dBm[275];
/// PRACH background noise level
int prach_I0;
} PHY_MEASUREMENTS_gNB;

View File

@@ -1083,8 +1083,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
if (!(ulsch->active && ulsch->frame == frame_rx && ulsch->slot == slot_rx && !ulsch->handled))
continue;
LOG_D(PHY, "PUSCH ID %d with RNTI %x detection started in frame %d slot %d\n", ULSCH_id, ulsch->rnti, frame_rx, slot_rx);
nfapi_nr_pusch_pdu_t *pdu = &ulsch_harq->ulsch_pdu;
int num_dmrs = count_bits64_with_mask(pdu->ul_dmrs_symb_pos, 0, NR_NUMBER_OF_SYMBOLS_PER_SLOT);
#ifdef DEBUG_RXDATA
RU_t *ru = gNB->RU_list[0];
@@ -1124,9 +1122,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
pusch_vars->ulsch_power_tot = 0;
pusch_vars->ulsch_noise_power_tot = 0;
for (int aarx = 0; aarx < nb_antennas_rx; aarx++) {
pusch_vars->ulsch_power[aarx] /= num_dmrs;
pusch_vars->ulsch_power_tot += pusch_vars->ulsch_power[aarx];
pusch_vars->ulsch_noise_power[aarx] /= num_dmrs;
pusch_vars->ulsch_noise_power_tot += pusch_vars->ulsch_noise_power[aarx];
}
if (dB_fixed_x10(pusch_vars->ulsch_power_tot) < dB_fixed_x10(pusch_vars->ulsch_noise_power_tot) + gNB->pusch_thres) {

View File

@@ -17,7 +17,7 @@ add_library(oran_fhlib_5g MODULE
)
set(E_VERSION 5.1.6)
set(F_VERSION 6.1.7)
set(F_VERSION 6.1.8)
find_package(xran REQUIRED)
if(xran_VERSION VERSION_EQUAL E_VERSION)

View File

@@ -22,6 +22,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdatomic.h>
#include "xran_fh_o_du.h"
#include "xran_compression.h"
#include "armral_bfp_compression.h"
@@ -56,6 +57,7 @@ int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id);
#ifndef USE_POLLING
extern notifiedFIFO_t oran_sync_fifo;
atomic_int xran_queue_length = 0;
#else
volatile oran_sync_info_t oran_sync_info = {0};
#endif
@@ -137,6 +139,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
info->sl = slot2;
info->f = frame;
LOG_D(HW, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot);
atomic_fetch_add(&xran_queue_length, 1);
pushNotifiedFIFO(&oran_sync_fifo, req);
#else
LOG_D(HW, "Writing %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
@@ -320,20 +323,29 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
struct xran_common_counters x_counters[XRAN_PORTS_NUM];
static int outcnt = 0;
#ifndef USE_POLLING
// pull next even from oran_sync_fifo
// pull next event from oran_sync_fifo
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo);
notifiedFIFO_elt_t *f;
while ((f = pollNotifiedFIFO(&oran_sync_fifo)) != NULL) {
oran_sync_info_t *old_info = NotifiedFifoData(res);
oran_sync_info_t *new_info = NotifiedFifoData(f);
LOG_E(HW, "Detected double sync message %d.%d => %d.%d\n", old_info->f, old_info->sl, new_info->f, new_info->sl);
delNotifiedFIFO_elt(res);
res = f;
}
atomic_fetch_sub(&xran_queue_length, 1);
oran_sync_info_t *info = NotifiedFifoData(res);
#define MAX_QUEUE_LENGTH_NO_JUMP 3
if (xran_queue_length > 0 && xran_queue_length < MAX_QUEUE_LENGTH_NO_JUMP) {
LOG_D(HW, "%4d.%2d TTI processing delay detected\n", info->f, info->sl);
} else if (xran_queue_length >= MAX_QUEUE_LENGTH_NO_JUMP) {
uint32_t old_f = info->f;
uint32_t old_sl = info->sl;
// set the frame/slot info to what is in the last message
notifiedFIFO_elt_t *f;
while ((f = pollNotifiedFIFO(&oran_sync_fifo)) != NULL) {
atomic_fetch_sub(&xran_queue_length, 1);
delNotifiedFIFO_elt(res);
res = f;
}
info = NotifiedFifoData(res);
LOG_W(HW, "TTI processing delay detected, skipping %4d.%2d => %4d.%2d\n", old_f, old_sl, info->f, info->sl);
DevAssert(xran_queue_length == 0);
}
*slot = info->sl;
*frame = info->f;
delNotifiedFIFO_elt(res);

View File

@@ -0,0 +1,274 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe01;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ( { sst = 1; }); });
nr_cellid = 1;
# min_rxtxtime = 4;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 1;
pusch_AntennaPorts = 1;
do_CSIRS = 0;
do_SRS = 0;
force_256qam_off = 0;
force_UL256qam_off = 0;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
#n_TimingAdvanceOffset = 1;
# downlinkConfigCommon
#frequencyInfoDL
# center frequency = 3420.48MHz
# selected SSB frequency = 3349.92 MHz
absoluteFrequencySSB = 627456;
dl_frequencyBand = 78;
# frequency point A = 3401.40 MHz
dl_absoluteFrequencyPointA = 626760;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
initialDLBWPlocationAndBandwidth = 28875; #38.101-1 Table 5.3.2-1
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
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 = 106;
pMax = 23;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 159;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 0;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 7;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 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 = 4;
p0_NominalWithGrant = -24;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 0;
p0_nominal = -24;
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 = 10;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 2;
ssPBCH_BlockPower = 0;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "172.22.0.10"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.26.190.95";
GNB_IPV4_ADDRESS_FOR_NGU = "172.26.190.95";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 250;
pucch_TargetSNRx10 = 200;
#dl_bler_target_upper = .35;
#dl_bler_target_lower = .15;
#ul_bler_target_upper = .35;
#ul_bler_target_lower = .15;
pusch_FailureThres = 1000;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
pucch0_dtx_threshold = 100;
pusch_dtx_threshold = 10;
max_ldpc_iterations = 15;
tx_amp_backoff_dB = 9; # 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 = 1;
nb_rx = 1;
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 = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "no";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
nr_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:70:11.0"); # one VF can be used as well
system_core = 0;
io_core = 1;
worker_cores = (2);
ru_addr = ("50:7c:6f:45:f3:04");
mtu = 9216;
fh_config = ({
T1a_cp_dl = (2566, 2585);
T1a_cp_ul = (2566, 2585);
T1a_up = (2200, 2300);
Ta4 = (1500, 1990);
ru_config = {
iq_width = 9;
iq_width_prach = 9;
};
prach_config = {
eAxC_offset = 4;
};
});
};