Merge remote-tracking branch 'origin/xran-large-delay-profile' into 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

This MR does the following:
- we patch xRAN to support large DU delay profiles (i.e., T1a/Ta4 values larger
  than a TTI)
- we update the FHI72 docs to introduce ProtO-RU, a software implementation of a
  Split-7.2 O-RU with large delay profile
- we provide an example configuration for ProtO-RU

Details on the xRAN patch:
In xRAN, it appears that T1a/Ta4 values are assumed to be within a TTI. When
T1a/Ta4 values larger than a TTI are used, this causes two issues:
(1) C-plane packets to be generated later than expected, and
(2) oai_xran_fh_rx_callback() receives the wrong timing information, resulting
    in potentially empty/stale PUSCH/PRACH data to be read.
In the xRAN patch, we modify xRAN to make it handle large T1a/Ta4 values properly.
The changes include:
(1) three additional variables in offset_num_slots_* (xran_dev.h),
(2) modify "xran_timing_create_cbs" and "xran_timer_arm_for_deadline"
    (xran_cb_proc.c), and
(3) revise "tx_cp_dl_cb" and "tx_cp_ul_cb" (xran_main.c).
Additionally, we add additional guard conditions to prevent xran_tx_proc.c from
sending U-plane packets when it is not a downlink slot.
This commit is contained in:
Jaroslava Fiedlerova
2026-02-03 08:07:56 +01:00
4 changed files with 531 additions and 81 deletions

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

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

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

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