Compare commits

...

2 Commits

7 changed files with 920 additions and 27 deletions

View File

@@ -173,18 +173,20 @@ index eccc4ae..a97fdc6 100644
CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF)
CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF)
diff --git a/fhi_lib/lib/api/xran_fh_o_du.h b/fhi_lib/lib/api/xran_fh_o_du.h
index bacf597..1dd6d66 100644
index bacf597..2aeaaae 100644
--- a/fhi_lib/lib/api/xran_fh_o_du.h
+++ b/fhi_lib/lib/api/xran_fh_o_du.h
@@ -141,7 +141,7 @@ extern "C" {
@@ -141,8 +141,8 @@ extern "C" {
#define XRAN_MAX_SECTIONS_PER_SYM (XRAN_MAX_SECTIONS_PER_SLOT) /**< Max number of different sections in single slot (section may be equal to RB allocation for UE) */
#define XRAN_MIN_SECTIONS_PER_SYM (XRAN_MIN_SECTIONS_PER_SLOT) /**< Min number of different sections in single slot (section may be equal to RB allocation for UE) */
-#define XRAN_MAX_FRAGMENT (4) /**< Max number of fragmentations in single symbol */
-#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
+#define XRAN_MAX_FRAGMENT (6) /**< Max number of fragmentations in single symbol */
#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
+#define XRAN_MAX_SET_BFWS (1) //(64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
#define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */
#define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */
@@ -419,6 +419,7 @@ struct xran_io_cfg {
uint16_t num_rxq; /**< number of RX queues per VF */
char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */
@@ -193,7 +195,15 @@ index bacf597..1dd6d66 100644
int32_t bbdev_mode; /**< DPDK for BBDev */
uint32_t dpdkIoVaMode; /**< IOVA Mode */
uint32_t dpdkMemorySize; /**< DPDK max memory allocation */
@@ -1193,6 +1194,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb,
@@ -713,6 +714,7 @@ struct xran_fh_config {
uint16_t max_sections_per_slot; /**< M-Plane settings for section */
uint16_t max_sections_per_symbol; /**< M-Plane settings for section */
int32_t RunSlotPrbMapBySymbolEnable; /**< enable prb mapping by symbol with multisection*/
+ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */
uint8_t dssEnable; /**< enable DSS (extension-9) */
uint8_t dssPeriod; /**< DSS pattern period for LTE/NR */
@@ -1193,6 +1195,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb,
*/
int32_t xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond);
@@ -535,7 +545,7 @@ index 08660f3..2bb5187 100644
#include <rte_eal.h>
#include <rte_errno.h>
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index dc40ad9..5968d01 100644
index dc40ad9..2208cd1 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -31,7 +31,10 @@
@@ -549,7 +559,114 @@ index dc40ad9..5968d01 100644
#include <rte_mbuf.h>
#include <stdio.h>
#include <stdbool.h>
@@ -714,11 +717,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
@@ -49,6 +52,8 @@
#include "xran_printf.h"
#include "xran_mlog_lnx.h"
+#include "xran_frame_struct.h"
+
static struct timespec sleeptime = {.tv_nsec = 1E3 }; /* 1 us */
extern int32_t first_call;
@@ -529,13 +534,32 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
if (pRbMap)
{
/** Get the prb_elem_id */
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
+ section_id_tmp = prb_elem_id_tmp = sect_id;
+ } else {
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 20 ? symb_id[i] - 10: symb_id[i]; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t prb_elem_id_tmp = 2*section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 10 ? symb_id[i] - 10: symb_id[i]; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //u_int8_t prb_elem_id_tmp = section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //if (start_prbu !=0) // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ // prb_elem_id_tmp++; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ u_int8_t mixed_ul_sym_start = 0;
+ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) {
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti);
+ }
+ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ u_int8_t prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ }
+
total_sections=0;
if(pRbMap->prbMap[0].bf_weight.extType == 1)
{
for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
{
total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
- if(total_sections >= (sect_id[i] + 1))
+ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1))
{
prb_elem_id[i] = idxElm;
break;
@@ -544,12 +568,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
}
else
{
- prb_elem_id[i] = sect_id[i];
+ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/
}
if (prb_elem_id[i] >= pRbMap->nPrbElm)
{
- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
+ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm);
ret_data[i] = MBUF_FREE;
continue;
}
@@ -615,13 +639,32 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
if (pRbMap)
{
/** Get the prb_elem_id */
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
+ section_id_tmp = prb_elem_id_tmp = sect_id;
+ } else {
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 20 ? symb_id[i] - 10: symb_id[i]; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t prb_elem_id_tmp = 2*section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 10 ? symb_id[i] - 10: symb_id[i]; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //u_int8_t prb_elem_id_tmp = section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //if (start_prbu !=0) // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ // prb_elem_id_tmp++; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ u_int8_t mixed_ul_sym_start = 0;
+ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) {
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti);
+ }
+ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ u_int8_t prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ }
+
total_sections=0;
if(pRbMap->prbMap[0].bf_weight.extType == 1)
{
for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
{
total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
- if(total_sections >= (sect_id[i] + 1))
+ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1))
{
prb_elem_id[i] = idxElm;
break;
@@ -630,12 +673,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
}
else
{
- prb_elem_id[i] = sect_id[i];
+ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/
}
if (prb_elem_id[i] >= pRbMap->nPrbElm)
{
- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
+ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm);
ret_data[i] = MBUF_FREE;
continue;
}
@@ -714,11 +757,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
uint8_t compMeth = 0;
uint8_t iqWidth = 0;
@@ -564,7 +681,7 @@ index dc40ad9..5968d01 100644
if(first_call == 0)
return ret;
@@ -733,9 +739,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
@@ -733,9 +779,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
return MBUF_FREE;
num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf,
@@ -576,7 +693,7 @@ index dc40ad9..5968d01 100644
if (num_bytes <= 0)
{
print_err("num_bytes is wrong [%d]\n", num_bytes);
@@ -781,10 +787,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
@@ -781,10 +827,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
else
{
@@ -590,7 +707,7 @@ index dc40ad9..5968d01 100644
#ifndef FCN_ADAPT
if(valid_res != 0)
{
@@ -807,8 +812,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
@@ -807,8 +852,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
PrachCfg = &(p_dev_ctx->PrachCPConfig);
}
@@ -600,7 +717,7 @@ index dc40ad9..5968d01 100644
/* PRACH packet has ruportid = num_eAxc + ant_id */
Ant_ID -= PrachCfg->eAxC_offset;
symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
@@ -1412,7 +1416,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
@@ -1412,7 +1456,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx)
{
timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
@@ -609,7 +726,7 @@ index dc40ad9..5968d01 100644
timeOffset += 16;
}
else
@@ -1547,8 +1551,7 @@ int32_t ring_processing_func(void* args)
@@ -1547,8 +1591,7 @@ int32_t ring_processing_func(void* args)
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){
for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) {
@@ -918,8 +1035,58 @@ index 4acade1..c939edc 100644
if(pCtx){
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
--- 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
int32_t DynamicSectionEna;
int32_t RunSlotPrbMapBySymbolEnable;
+ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */
int64_t offset_sec;
int64_t offset_nsec; //offset to GPS time calcuated based on alpha and beta
uint32_t interval_us_local;
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
+++ b/fhi_lib/lib/src/xran_frame_struct.c
@@ -519,4 +519,20 @@ int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlot
return xran_fs_slot_symb_type[PortId][nCellIdx][nSfIdxMod][nSymbIdx];
}
+uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx)
+{
+ int32_t nSfIdxMod;
+
+ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1);
+
+ return xran_fs_num_dl_sym_sp[PortId][nCellIdx][nSfIdxMod];
+}
+uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx)
+{
+ int32_t nSfIdxMod;
+
+ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1);
+
+ return xran_fs_num_ul_sym_sp[PortId][nCellIdx][nSfIdxMod];
+}
diff --git a/fhi_lib/lib/src/xran_frame_struct.h b/fhi_lib/lib/src/xran_frame_struct.h
index 7ed0a3a..8e66945 100644
--- a/fhi_lib/lib/src/xran_frame_struct.h
+++ b/fhi_lib/lib/src/xran_frame_struct.h
@@ -75,6 +75,8 @@ uint32_t xran_fs_slot_limit_init(uint32_t PortId, int32_t tti_interval_us);
uint32_t xran_fs_get_max_slot(uint32_t PortId);
uint32_t xran_fs_get_max_slot_SFN(uint32_t PortId);
int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx);
+uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx);
+uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx);
#ifdef __cplusplus
}
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 7c472d7..9da3621 100644
index 7c472d7..6866521 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -35,7 +35,11 @@
@@ -1550,7 +1717,15 @@ index 7c472d7..9da3621 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -4034,6 +4062,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
@@ -3754,6 +3782,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;
+ p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable = pConf->LiteOnIgnoreUPSectionIdEnable;
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,
return tti;
}
@@ -1575,6 +1750,73 @@ index 7c472d7..9da3621 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
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;
- struct xran_prb_elm prbMapTemp[XRAN_NUM_OF_SYMBOL_PER_SLOT];
+ struct xran_prb_elm prbMapTemp[XRAN_NUM_OF_SYMBOL_PER_SLOT] = {0} ; // Need to initialize to zero for field sec_desc.
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
if (mtu==9600)
nmaxRB--; //for some reason when mtu is 9600, only 195 RB can be sent, not 196
-
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
for(; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++)
{
- if((nRBStart == prbMapTemp[i].nRBStart) && (nRBSize == prbMapTemp[i].nRBSize))
- {
- prbMapTemp[nPrbElm].numSymb++;
- }
- else
+ if((prbMapTemp[i].nRBSize != 0))
{
- nPrbElm++;
- prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb;
- prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart;
- prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize;
- prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex;
- prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update;
- prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod;
- prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth;
- prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor;
- prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask;
- prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType;
-
- nRBStart = prbMapTemp[i].nRBStart;
- nRBSize = prbMapTemp[i].nRBSize;
+ if (false) // Force it to generate multiple prbMapElm, one for each symbol even if they are of the same RBs
+ //if((nRBStart == prbMapTemp[i].nRBStart) && (nRBSize == prbMapTemp[i].nRBSize))
+ {
+ prbMapTemp[nPrbElm].numSymb++;
+ }
+ else
+ {
+ nPrbElm++;
+ prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb;
+ prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart;
+ prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize;
+ prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex;
+ prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update;
+ prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod;
+ prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth;
+ prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor;
+ prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask;
+ prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType;
+
+ nRBStart = prbMapTemp[i].nRBStart;
+ nRBSize = prbMapTemp[i].nRBSize;
+ }
}
}
diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c
index e1dcb6c..b3c3fae 100644
--- a/fhi_lib/lib/src/xran_mem_mgr.c
@@ -1608,7 +1850,7 @@ index 7d4a5d0..b9b44ac 100644
#endif
}
diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c
index e7056f4..0d3d8ac 100644
index e7056f4..81216bf 100644
--- a/fhi_lib/lib/src/xran_rx_proc.c
+++ b/fhi_lib/lib/src/xran_rx_proc.c
@@ -35,7 +35,11 @@
@@ -1623,6 +1865,133 @@ index e7056f4..0d3d8ac 100644
#include <rte_common.h>
#include <rte_eal.h>
@@ -339,13 +343,35 @@ int32_t xran_process_srs_sym(void *arg,
pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFHSrsRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData;
if(pRbMap)
{
- prbMapElm = &pRbMap->prbMap[sect_id];
- if(sect_id >= pRbMap->nPrbElm)
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
+ section_id_tmp = prb_elem_id_tmp = sect_id;
+ } else {
+ /** Get the prb_elem_id */
+ //u_int8_tsection_id_tmp = pRbMap->nPrbElm < 20 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_tprb_elem_id_tmp = 2*section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 10 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //u_int8_t prb_elem_id_tmp = section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //if (start_prbu !=0) // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ // prb_elem_id_tmp++; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
+ u_int8_t mixed_ul_sym_start = 0;
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
+ }
+
+ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ }
+
+ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/];
+ if(/*sect_id*/ prb_elem_id_tmp >= pRbMap->nPrbElm)
{
- print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm);
- *mb_free = MBUF_FREE;
- return size;
- }
+ print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm);
+ *mb_free = MBUF_FREE;
+ return size;
+ }
}
else
{
@@ -397,7 +423,27 @@ int32_t xran_process_srs_sym(void *arg,
else */
{
struct xran_section_desc *p_sec_desc = NULL;
- prbMapElm = &pRbMap->prbMap[sect_id];
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
+ section_id_tmp = prb_elem_id_tmp = sect_id;
+ } else {
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 20 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t prb_elem_id_tmp = 2*section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 10 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //u_int8_t prb_elem_id_tmp = section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //if (start_prbu !=0) // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ // prb_elem_id_tmp++; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
+ u_int8_t mixed_ul_sym_start = 0;
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
+ }
+ u_int8_t section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ u_int8_t prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ }
+
+ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/];
// sec_desc_idx = 0;//prbMapElm->nSecDesc[symb_id];
sec_desc_idx = prbMapElm->nSecDesc[symb_id];
@@ -537,14 +583,35 @@ int32_t xran_process_rx_sym(void *arg,
pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData;
if(pRbMap){
- /** Get the prb_elem_id */
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
+ section_id_tmp = prb_elem_id_tmp = sect_id;
+ } else {
+ /** Get the prb_elem_id */
+ //u_int8_tsection_id_tmp = pRbMap->nPrbElm < 20 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_tprb_elem_id_tmp = 2*section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ //u_int8_t section_id_tmp = pRbMap->nPrbElm < 10 ? symb_id - 10: symb_id; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //u_int8_t prb_elem_id_tmp = section_id_tmp; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ //if (start_prbu !=0) // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ // prb_elem_id_tmp++; // Temporary hack for LiteON FR2 : receive UP section ID = 13, MTU 1500
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
+ u_int8_t mixed_ul_sym_start = 0;
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
+ }
+
+ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
+ }
+
total_sections=0;
if(pRbMap->prbMap[0].bf_weight.extType == 1)
{
for(i=0 ; i < pRbMap->nPrbElm ; i++)
{
total_sections += pRbMap->prbMap[i].bf_weight.numSetBFWs;
- if(total_sections >= (sect_id + 1))
+ if(total_sections >= (/*sect_id*/ section_id_tmp + 1))
{
prb_elem_id = i;
break;
@@ -553,7 +620,7 @@ int32_t xran_process_rx_sym(void *arg,
}
else
{
- prb_elem_id = sect_id;
+ prb_elem_id = prb_elem_id_tmp; /*sect_id*/;
}
prbMapElm = &pRbMap->prbMap[prb_elem_id];
@@ -597,7 +664,7 @@ int32_t xran_process_rx_sym(void *arg,
if(p_sec_desc){
mb = p_sec_desc->pCtrl;
if(mb){
- rte_pktmbuf_free(mb);
+ rte_pktmbuf_free(mb);
}
p_sec_desc->pData = iq_data_start;
p_sec_desc->pCtrl = mbuf;
diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c
index 14a6a41..55182d8 100644
--- a/fhi_lib/lib/src/xran_timer.c

View File

@@ -102,6 +102,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
LOG_D(HW, "cb pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) {
struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm];
pRbElm->nSecDesc[sym_id] = 0; // number of section descriptors per symbol; M-plane info <supported-section-types>
@@ -260,6 +261,28 @@ static bool is_tdd_ul_symbol(const struct xran_frame_config *frame_conf, int slo
return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 1 /* UL */;
}
/** @brief Check if symbol in slot is DL.
*
* @param frame_conf xran frame configuration
* @param slot the current (absolute) slot (number)
* @param sym_idx the current symbol index */
static bool is_tdd_dl_symbol(const struct xran_frame_config *frame_conf, int slot, int sym_idx)
{
/* in FDD, every symbol is also UL */
if (frame_conf->nFrameDuplexType == XRAN_FDD)
return true;
int tdd_period = frame_conf->nTddPeriod;
int slot_in_period = slot % tdd_period;
/* check if symbol is UL */
return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 0 /* DL */;
}
/** @brief Check if current slot is guard/mixed */
static bool is_tdd_guard_slot(const struct xran_frame_config *frame_conf, int slot)
{
return (is_tdd_dl_symbol(frame_conf, slot, 0) && is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1));
}
/** @brief Check if current slot is DL or guard/mixed without UL (i.e., current
* slot is not UL). */
static bool is_tdd_dl_guard_slot(const struct xran_frame_config *frame_conf, int slot)
@@ -673,3 +696,470 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
}
return (0);
}
/** @details Read PRACH and PUSCH data from xran buffers. If
* I/Q compression (bitwidth < 16 bits) is configured, deccompresses the data
* before writing. Prints ON TIME counters every 128 frames.
*
* Function is blocking and waits for next frame/slot combination. It is unblocked
* by oai_xran_fh_rx_callback(). It writes the current slot into parameters
* frame/slot. */
int xran_fh_rx_read_slot_BySymbol(ru_info_t *ru, int *frame, int *slot)
{
void *ptr = NULL;
int32_t *pos = NULL;
int idx = 0;
static int64_t old_rx_counter[XRAN_PORTS_NUM] = {0};
static int64_t old_tx_counter[XRAN_PORTS_NUM] = {0};
struct xran_common_counters x_counters[XRAN_PORTS_NUM];
static int outcnt = 0;
#ifndef USE_POLLING
// pull next even 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;
}
oran_sync_info_t *info = NotifiedFifoData(res);
*slot = info->sl;
*frame = info->f;
delNotifiedFIFO_elt(res);
#else
*slot = oran_sync_info.sl;
*frame = oran_sync_info.f;
uint32_t tti_in = oran_sync_info.tti;
static int last_slot = -1;
LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot);
int cnt = 0;
// while (*slot == last_slot) {
while (tti_in == oran_sync_info.tti) {
//*slot = oran_sync_info.sl;
cnt++;
}
LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot);
last_slot = *slot;
#endif
// return(0);
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology;
int tti = slots_per_frame * (*frame) + (*slot);
read_prach_data(ru, *frame, *slot);
const struct xran_fh_init *fh_init = get_xran_fh_init();
int nPRBs = fh_cfg->nULRBs;
int fftsize = 1 << fh_cfg->ru_conf.fftSize;
int slot_offset_rxdata = 3 & (*slot);
uint32_t slot_size = 4 * 14 * fftsize;
uint8_t *rx_data = (uint8_t *)ru->rxdataF[0];
uint8_t *start_ptr = NULL;
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) {
rx_data = (uint8_t *)ru->rxdataF[ant_id];
start_ptr = rx_data + (slot_size * slot_offset_rxdata);
const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf;
// skip processing this slot is TX (no RX in this slot)
if (!is_tdd_ul_guard_slot(frame_conf, *slot))
continue;
bool sym_start_found = false;
int32_t sym_start = 0;
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
/* the callback is for mixed and UL slots. In mixed, we have to
* skip DL and guard symbols. */
if (!is_tdd_ul_symbol(frame_conf, *slot, sym_idx))
continue;
if (!sym_start_found) {
sym_start = sym_idx;
sym_start_found = true;
}
uint8_t *pData;
oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru);
uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
struct xran_prb_map *pRbMap = pPrbMap;
for (int idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm];
#ifdef E_RELEASE
struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[sym_idx][0];
uint32_t one_rb_size =
(((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1));
if (fh_init->mtu < pRbElm->nRBSize * one_rb_size)
pData = bufs->dst[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN]
.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT]
.pData;
else
pData = p_sec_desc->pData;
#elif defined F_RELEASE
struct xran_section_desc *p_sec_desc = &pRbElm->sec_desc[sym_idx][0];
pData = p_sec_desc->pData;
#endif
ptr = pData;
pos = (int32_t *)(start_ptr + (4 * sym_idx * fftsize));
if (ptr == NULL || pos == NULL)
continue;
uint8_t *src = (uint8_t *)ptr;
LOG_D(HW, "rx pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx.
u_int8_t section_id_tmp = pPrbMap->nPrbElm < XRAN_NUM_OF_SYMBOL_PER_SLOT ? sym_idx - sym_start: sym_idx;
if (section_id_tmp != pRbElm->nSectId) {
LOG_D(HW,
"rx prbMap[%d] : PRBstart %d nPRBs %d nSectId %d != sym_idx %d:%d\n",
idxElm,
pRbMap->prbMap[idxElm].nRBStart,
pRbMap->prbMap[idxElm].nRBSize,
pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp
);
continue;
}
LOG_D(HW,
"rx prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d sym_idx %d:%d\n",
idxElm,
pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart,
pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize,
pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp
);
int pos_len = 0;
int neg_len = 0;
int num_prbu = p_sec_desc->num_prbu;
int start_prbu = p_sec_desc->start_prbu;
if (start_prbu < (nPRBs >> 1)) // there are PRBs left of DC
neg_len = min((nPRBs * 6) - (start_prbu * 12), num_prbu * N_SC_PER_PRB);
pos_len = (num_prbu * N_SC_PER_PRB) - neg_len;
src = pData;
// Calculation of the pointer for the section in the buffer.
// positive half
uint8_t *dst1 = (uint8_t *)(pos + (neg_len == 0 ? ((start_prbu * N_SC_PER_PRB) - (nPRBs * 6)) : 0));
// negative half
uint8_t *dst2 = (uint8_t *)(pos + (start_prbu * N_SC_PER_PRB) + fftsize - (nPRBs * 6));
int32_t local_dst[num_prbu * N_SC_PER_PRB] __attribute__((aligned(64)));
if (pRbElm->compMethod == XRAN_COMPMETHOD_NONE) {
// NOTE: gcc 11 knows how to generate AVX2 for this!
for (idx = 0; idx < num_prbu * N_SC_PER_PRB * 2; idx++)
((int16_t *)local_dst)[idx] = ((int16_t)ntohs(((uint16_t *)src)[idx])) >> 2;
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
} else if (pRbElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
#if defined(__i386__) || defined(__x86_64__)
struct xranlib_decompress_request bfp_decom_req = {};
struct xranlib_decompress_response bfp_decom_rsp = {};
int16_t payload_len = (3 * pRbElm->iqWidth + 1) * num_prbu;
bfp_decom_req.data_in = (int8_t *)src;
bfp_decom_req.numRBs = num_prbu;
bfp_decom_req.len = payload_len;
bfp_decom_req.compMethod = pRbElm->compMethod;
bfp_decom_req.iqWidth = pRbElm->iqWidth;
bfp_decom_rsp.data_out = (int16_t *)local_dst;
bfp_decom_rsp.len = 0;
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
#elif defined(__arm__) || defined(__aarch64__)
armral_bfp_decompression(pRbElm->iqWidth, num_prbu, (int8_t *)src, (int16_t *)local_dst);
#else
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
#endif
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
outcnt++;
} else {
printf("pRbElm->compMethod == %d is not supported\n", pRbElm->compMethod);
exit(-1);
}
}
} // sym_ind
} // ant_ind
} // vv_inf
if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) {
for (int o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) {
LOG_I(HW,
"[%s%d][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld][Total Msgs_Rcvd %ld]\n",
"o-du ",
o_xu_id,
x_counters[o_xu_id].rx_counter,
x_counters[o_xu_id].rx_counter - old_rx_counter[o_xu_id],
x_counters[o_xu_id].rx_bytes_per_sec * 8 / 1000L,
x_counters[o_xu_id].tx_counter,
x_counters[o_xu_id].tx_counter - old_tx_counter[o_xu_id],
x_counters[o_xu_id].tx_bytes_per_sec * 8 / 1000L,
x_counters[o_xu_id].Total_msgs_rcvd);
for (int rxant = 0; rxant < ru->nb_rx / fh_init->xran_ports; rxant++)
LOG_I(HW,
"[%s%d][pusch%d %7ld prach%d %7ld]\n",
"o_du",
o_xu_id,
rxant,
x_counters[o_xu_id].rx_pusch_packets[rxant],
rxant,
x_counters[o_xu_id].rx_prach_packets[rxant]);
if (x_counters[o_xu_id].rx_counter > old_rx_counter[o_xu_id])
old_rx_counter[o_xu_id] = x_counters[o_xu_id].rx_counter;
if (x_counters[o_xu_id].tx_counter > old_tx_counter[o_xu_id])
old_tx_counter[o_xu_id] = x_counters[o_xu_id].tx_counter;
}
}
return (0);
}
/** @details Write PDSCH IQ-data from OAI txdataF_BF buffer to xran buffers. If
* I/Q compression (bitwidth < 16 bits) is configured, compresses the data
* before writing. */
int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
{
int tti = /*frame*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME+*/ 20 * frame
+ slot; // commented out temporarily to check that compilation of oran 5g is working.
void *ptr = NULL;
int32_t *pos = NULL;
int idx = 0;
const struct xran_fh_init *fh_init = get_xran_fh_init();
const struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
int nPRBs = fh_cfg->nDLRBs;
int fftsize = 1 << fh_cfg->ru_conf.fftSize;
int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports;
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
// Handle CP UL packet here instead of at xran_fh_rx_read_slot() as oran_fh_if4p5_south_in() lags behind
// oran_fh_if4p5_south_out() (which is invoked at the right time slot) by 4 slots.
// Need to use --continuous-tx so that this routine will be triggered in RX slot.
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) {
const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf;
// skip processing this slot is TX (no RX in this slot)
if (!is_tdd_ul_guard_slot(frame_conf, slot)) {
continue;
}
bool sym_start_found = false;
int32_t sym_start = 0;
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
/* the callback is for mixed and UL slots. In mixed, we have to
* skip DL and guard symbols. */
if (!is_tdd_ul_symbol(frame_conf, slot, sym_idx)) {
continue;
}
if (!sym_start_found) {
sym_start = sym_idx;
sym_start_found = true;
}
oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru);
uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0];
struct xran_prb_map *pRbMap = pPrbMap;
uint32_t idxElm = 0;
LOG_D(HW, "tx0 pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
LOG_D(HW, "prbMap[%d] : PRBstart %d nPRBs %d\n", idxElm, pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].nRBSize);
pRbElm = &pRbMap->prbMap[idxElm];
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx.
u_int8_t section_id_tmp = pPrbMap->nPrbElm < XRAN_NUM_OF_SYMBOL_PER_SLOT ? sym_idx - sym_start: sym_idx;
if (section_id_tmp != pRbElm->nSectId) {
LOG_D(HW,
"tx0 prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d != sym_idx %d:%d\n",
idxElm,
pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart,
pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize,
pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp
);
continue;
}
LOG_D(HW,
"tx0 prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d sym_idx %d:%d\n",
idxElm,
pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart,
pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize,
pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp
);
// ant_id / no of antenna per beam gives the beam_nb
pRbElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_rx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx];
// In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly.
if (pRbElm->nBeamIndex == -1)
pRbElm->nBeamIndex = 0;
}
}
}
}
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < ru->nb_tx; ant_id++) {
oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_tx_per_ru);
const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_tx_per_ru)->frame_conf;
// skip processing this slot is TX (no TX in this slot)
if (!is_tdd_dl_guard_slot(frame_conf, slot)) {
continue;
}
// Set nPrbElm if beam_id = -1 for all downlink symbols
bool beam_used = false;
uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
struct xran_prb_map *pRbMap = pPrbMap;
int32_t dl_sym_end = 0;
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
if (is_tdd_dl_symbol(frame_conf, slot, sym_idx)) {
if (ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT+ sym_idx] != -1)
beam_used |= true;
}
else {
dl_sym_end = sym_idx;
break;
}
}
if (is_tdd_guard_slot(frame_conf, slot))
pRbMap->nPrbElm = dl_sym_end;
else
pRbMap->nPrbElm = XRAN_NUM_OF_SYMBOL_PER_SLOT;
if (!beam_used) {
pRbMap->nPrbElm = 0;
continue;
}
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
/* the callback is for mixed and UL slots. In mixed, we have to
* skip UL and guard symbols. */
if (is_tdd_ul_symbol(frame_conf, slot, sym_idx)) {
continue;
}
uint8_t *pData =
bufs->src[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData;
uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
ptr = pData;
pos = &ru->txdataF_BF[ant_id][sym_idx * fftsize];
uint8_t *u8dptr;
struct xran_prb_map *pRbMap = pPrbMap;
int32_t sym_id = sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT;
if (ptr && pos) {
uint32_t idxElm = 0;
u8dptr = (uint8_t *)ptr;
int16_t payload_len = 0;
uint8_t *dst = (uint8_t *)u8dptr;
struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm];
LOG_D(HW, "tx1 pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx.
struct xran_section_desc *p_sec_desc = NULL;
p_prbMapElm = &pRbMap->prbMap[idxElm];
if (sym_idx != p_prbMapElm->nSectId)
continue;
// ant_id / no of antenna per beam gives the beam_nb
p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT+ sym_idx];
// In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly.
if (p_prbMapElm->nBeamIndex == -1)
p_prbMapElm->nBeamIndex = 0;
// assumes one fragment per symbol
#ifdef E_RELEASE
p_sec_desc = p_prbMapElm->p_sec_desc[sym_id][0];
#elif F_RELEASE
p_sec_desc = &p_prbMapElm->sec_desc[sym_id][0];
#endif
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
uint16_t *dst16 = (uint16_t *)dst;
int pos_len = 0;
int neg_len = 0;
if (p_prbMapElm->UP_nRBStart < (nPRBs >> 1)) // there are PRBs left of DC
neg_len = min((nPRBs * 6) - (p_prbMapElm->UP_nRBStart * 12), p_prbMapElm->UP_nRBSize * N_SC_PER_PRB);
pos_len = (p_prbMapElm->UP_nRBSize * N_SC_PER_PRB) - neg_len;
// Calculation of the pointer for the section in the buffer.
// start of positive frequency component
uint16_t *src1 = (uint16_t *)&pos[(neg_len == 0) ? ((p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) - (nPRBs * 6)) : 0];
// start of negative frequency component
uint16_t *src2 = (uint16_t *)&pos[(p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) + fftsize - (nPRBs * 6)];
uint32_t local_src[p_prbMapElm->UP_nRBSize * N_SC_PER_PRB] __attribute__((aligned(64)));
memcpy((void *)local_src, (void *)src2, neg_len * 4);
memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4);
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = p_prbMapElm->UP_nRBSize * N_SC_PER_PRB * 4L;
/* convert to Network order */
// NOTE: ggc 11 knows how to generate AVX2 for this!
for (idx = 0; idx < (pos_len + neg_len) * 2; idx++)
((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]);
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->UP_nRBSize;
#if defined(__i386__) || defined(__x86_64__)
struct xranlib_compress_request bfp_com_req = {};
struct xranlib_compress_response bfp_com_rsp = {};
bfp_com_req.data_in = (int16_t *)local_src;
bfp_com_req.numRBs = p_prbMapElm->UP_nRBSize;
bfp_com_req.len = payload_len;
bfp_com_req.compMethod = p_prbMapElm->compMethod;
bfp_com_req.iqWidth = p_prbMapElm->iqWidth;
bfp_com_rsp.data_out = (int8_t *)dst;
bfp_com_rsp.len = 0;
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
#elif defined(__arm__) || defined(__aarch64__)
armral_bfp_compression(p_prbMapElm->iqWidth, p_prbMapElm->UP_nRBSize, (int16_t *)local_src, (int8_t *)dst);
#else
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
#endif
} else {
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
exit(-1);
}
p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr);
p_sec_desc->iq_buffer_len = payload_len;
dst += payload_len;
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
}
// The tti should be updated as it increased.
pRbMap->tti_id = tti;
} else {
printf("ptr ==NULL\n");
exit(-1); // fails here??
}
}
}
}
return (0);
}

View File

@@ -431,10 +431,12 @@ void print_fh_config(const struct xran_fh_config *fh_config)
#ifdef F_RELEASE
printf("\
RunSlotPrbMapBySymbolEnable %d\n\
LiteOnIgnoreUPSectionIdEnable %d\n\
dssEnable %d\n\
dssPeriod %d\n\
technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n",
fh_config->RunSlotPrbMapBySymbolEnable,
fh_config->LiteOnIgnoreUPSectionIdEnable,
fh_config->dssEnable,
fh_config->dssPeriod);
#endif
@@ -762,7 +764,8 @@ static bool set_fh_prach_config(void *mplane_api,
const uint32_t max_num_ant,
const paramdef_t *prachp,
int nprach,
struct xran_prach_config *prach_config)
struct xran_prach_config *prach_config,
bool liteon_prach_eAxC_offset)
{
const split7_config_t *s7cfg = &oai0->split7;
@@ -799,7 +802,10 @@ static bool set_fh_prach_config(void *mplane_api,
prach_config->eAxC_offset = xran_mplane->prach_offset;
#else
uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
if (liteon_prach_eAxC_offset)
prach_config->eAxC_offset = offset;
else
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
#endif
g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr;
@@ -945,9 +951,14 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->enableCP = 1; // enable C-plane
fh_config->prachEnable = 1; // enable PRACH
fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B
// For LiteOn E release, no need to take care of prach eAxC_offset. xran lib is hacked to handle it.
bool liteon_prach_eAxC_offset = false;
#ifdef F_RELEASE
fh_config->srsEnableCp = 0; // enable SRS CP; used only if XRAN_CATEGORY_B
fh_config->SrsDelaySym = 0; // number of SRS delay symbols; used only if XRAN_CATEGORY_B
fh_config->RunSlotPrbMapBySymbolEnable = *gpd(fhp, nfh, ORAN_CONFIG_RunSlotPrbMapBySymbol)->uptr; // enable RunSlotPrbMapBySymbol
fh_config->LiteOnIgnoreUPSectionIdEnable = *gpd(fhp, nfh, ORAN_CONFIG_LiteOnIgnoreUPSectionId)->uptr; // enable LiteOnIgnoreUPSectionId
liteon_prach_eAxC_offset = fh_config->LiteOnIgnoreUPSectionIdEnable;
#endif
fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU
fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU
@@ -959,7 +970,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha
fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100
if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf))
if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf, liteon_prach_eAxC_offset))
return false;
/* SRS only used if XRAN_CATEGORY_B
Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */
@@ -991,8 +1002,6 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
fh_config->max_sections_per_symbol = 0; // not used in xran
#ifdef F_RELEASE
fh_config->RunSlotPrbMapBySymbolEnable = 0; // enable PRB mapping by symbol with multisection
fh_config->dssEnable = 0; // enable DSS (extension-9)
fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR
// fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled

View File

@@ -335,6 +335,7 @@ static void oran_allocate_buffers(void *handle,
struct xran_prb_map dlPmMixed = {0};
struct xran_prb_map ulPmMixed = {0};
uint32_t idx = 0;
if (fh_config->frame_conf.nFrameDuplexType == XRAN_TDD) {
oran_mixed_slot_t info = get_mixed_slot_info(&fh_config->frame_conf);
dlPmMixed = get_xran_prb_map(fh_config, XRAN_DIR_DL, 0, info.num_dlsym);
@@ -359,8 +360,16 @@ static void oran_allocate_buffers(void *handle,
#ifdef E_RELEASE
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
#elif defined F_RELEASE
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu);
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
uint32_t size_of_prb_map;
if (fh_config->RunSlotPrbMapBySymbolEnable) {
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[14]
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (XRAN_NUM_OF_SYMBOL_PER_SLOT);
}
else {
// For non-Liteon w/o RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[1]
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu);
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
}
#endif
// PDSCH

View File

@@ -95,6 +95,8 @@
#define CONFIG_STRING_ORAN_FH "fh_config"
#define ORAN_CONFIG_RunSlotPrbMapBySymbol "RunSlotPrbMapBySymbol"
#define ORAN_CONFIG_LiteOnIgnoreUPSectionId "LiteOnIgnoreUPSectionId"
#define ORAN_FH_CONFIG_T1A_CP_DL "T1a_cp_dl"
#define ORAN_FH_CONFIG_T1A_CP_UL "T1a_cp_ul"
#define ORAN_FH_CONFIG_T1A_UP "T1a_up"
@@ -104,10 +106,12 @@
// clang-format off
#define ORAN_FH_DESC { \
{ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_CONFIG_RunSlotPrbMapBySymbol, "RunSlotPrbMapBySymbol\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{ORAN_CONFIG_LiteOnIgnoreUPSectionId, "Liteon Ignore Section Id\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
{ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
{ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
}
// clang-format on

View File

@@ -227,7 +227,12 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
int f, sl;
LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
start_meas(&ru->rx_fhaul);
int ret = xran_fh_rx_read_slot(&ru_info, &f, &sl);
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
int ret = 0;
if (fh_cfg->RunSlotPrbMapBySymbolEnable)
ret = xran_fh_rx_read_slot_BySymbol(&ru_info, &f, &sl);
else
ret = xran_fh_rx_read_slot(&ru_info, &f, &sl);
stop_meas(&ru->rx_fhaul);
LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]);
if (ret != 0) {
@@ -282,7 +287,12 @@ void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
// printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp);
int ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp);
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
int ret = 0;
if (fh_cfg->RunSlotPrbMapBySymbolEnable)
ret = xran_fh_tx_send_slot_BySymbol(&ru_info, frame, slot, timestamp);
else
ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp);
if (ret != 0) {
printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n");
}

View File

@@ -60,7 +60,9 @@ typedef struct ru_info_s {
* @param frame output of the frame which has been read.
* @param slot output of the slot which has been read. */
int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot);
int xran_fh_rx_read_slot_BySymbol(ru_info_t *ru, int *frame, int *slot);
/** @brief Writes TX data (PDSCH) of given slot. */
int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp);
int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t timestamp);
#endif /* _ORAN_ISOLATE_H_ */