From 003d72c8591018acdbbb78355b52ee8dfd516f31 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Tue, 28 Oct 2025 16:35:59 +0800 Subject: [PATCH 1/4] fhi7.2: introduce support for T1a and Ta4 values larger than TTI interval In xRAN, it appears that T1a/Ta4 values are assumed to be within a TTI. When T1a/Ta4 values with 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 this 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. --- .../F/oaioran_F.patch | 304 +++++++++++++----- radio/fhi_72/CMakeLists.txt | 2 +- 2 files changed, 226 insertions(+), 80 deletions(-) diff --git a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch index ba10bf38af..c30c6bd8fa 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch @@ -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 -#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 #include #include +@@ -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, ¶ms, 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, ¶ms, 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; idssPeriod; 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 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 #include -@@ -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. */ diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index c0546aaca8..e7e87560f9 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -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) From 0388bf0e67d70b5fb96bb983d96bb3da2cd9f872 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Thu, 6 Nov 2025 06:16:43 +0000 Subject: [PATCH 2/4] protoru: add docs and sample config --- doc/ORAN_FHI7.2_Tutorial.md | 32 +- ...b.sa.band78.106prb.fhi72.1x1-proto-ru.conf | 278 ++++++++++++++++++ 2 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index e3bb8e44c1..ca10c768ce 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -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 +``` + +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 diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf new file mode 100644 index 0000000000..4027673ff3 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf @@ -0,0 +1,278 @@ +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; + sib1_tda = 15; + 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; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#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 = 20; + } + ); + + + # ------- 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 = 9600; + fh_config = ({ + T1a_cp_dl = (2450, 2635); + T1a_cp_ul = (2450, 2635); + T1a_up = (2350, 2550); + Ta4 = (1500, 1990); + ru_config = { + iq_width = 9; + iq_width_prach = 9; + }; + prach_config = { + eAxC_offset = 4; + }; + }); +}; + From 34c001d488cef8ee5beea0914efb40a92eb288f2 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Mon, 2 Feb 2026 15:07:42 +0000 Subject: [PATCH 3/4] protoru: sample config update --- .../gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf index 4027673ff3..0308d2aac7 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf @@ -21,7 +21,6 @@ gNBs = pusch_AntennaPorts = 1; do_CSIRS = 0; do_SRS = 0; - sib1_tda = 15; force_256qam_off = 0; force_UL256qam_off = 0; @@ -86,9 +85,6 @@ gNBs = #powerRampingStep # 0=dB0,1=dB2,2=dB4,3=dB6 powerRampingStep = 3; -#ra_ReponseWindow -#1,2,4,8,10,20,40,80 - ra_ResponseWindow = 5; #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; @@ -148,7 +144,7 @@ gNBs = nrofUplinkSlots = 1; nrofUplinkSymbols = 2; - ssPBCH_BlockPower = 20; + ssPBCH_BlockPower = 0; } ); @@ -260,11 +256,11 @@ fhi_72 = { io_core = 1; worker_cores = (2); ru_addr = ("50:7c:6f:45:f3:04"); - mtu = 9600; + mtu = 9216; fh_config = ({ - T1a_cp_dl = (2450, 2635); - T1a_cp_ul = (2450, 2635); - T1a_up = (2350, 2550); + T1a_cp_dl = (2566, 2585); + T1a_cp_ul = (2566, 2585); + T1a_up = (2200, 2300); Ta4 = (1500, 1990); ru_config = { iq_width = 9; From 95df8b174ec73fc59218dfae825f14102320f51a Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Mon, 2 Feb 2026 15:28:06 +0000 Subject: [PATCH 4/4] protoru: fix doc indent --- doc/ORAN_FHI7.2_Tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index ca10c768ce..a241fbb3f5 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -719,7 +719,7 @@ 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. -### ProtO-RU +#### 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. @@ -731,7 +731,7 @@ The OAI configuration file [`gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf`](../t - MTU 9216 - 1T1R -#### RU configuration +##### 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.