Merge remote-tracking branch 'origin/liteon_develop_F' into integration_2026_w03 (!3668)
Support beam index for LiteON FR2 RU that needs per symbol section in CP packets This branch supports beam index for LiteOn FR2 RU and others. It adds the support of beam index for LiteOn RU that uses per-symbol CP packet and is a sequel of MR !3605 (merged) that supports beam index for RU that uses per-slot CP packets. A. To support LiteOn FR2 RU, the following are needed. a. Per symbol beamforming. Need separate section for each symbol on CP packet. b. Handle these two bugs: - section ID on UP packet is set wrongly to 13 for all sections - prach eAxC offset starts from 0 instead of from last antenna port number used by other channels. B. Implementation a. set fh_config->RunSlotPrbMapBySymbolEnable based on the setting in the configuration file - if disable, the existing per-slot scheme is run on xran. - if enable, RunSlotPrbMapBySymbolEnable mode is on in xran so that xran will generate PrbElm per symbol (aka total of 14)and perform per-symbol processing on the corresponding PrbElm. b. set fh_config->LiteOnIgnoreUPSectionIdEnable based on the setting in the configuration file if enable, handle 2 "features" of Liteon: - To handle the section_id = 13 issue on Liteon where section ID is set wrongly to 13 for all sections - To handle the prach eAxC offset issue on Liteon where it starts from 0 instead of from the end of last antenna port number c. if fh_config->RunSlotPrbMapBySymbolEnable, OAI FHI - invoke xran_fh_rx_read_slot_BySymbol() instead of xran_fh_rx_read_slot() - invoke xran_fh_tx_send_slot_BySymbol() instead of xran_fh_tx_send_slot() C. Testing a. Command to test benetel RU sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band77.273prb.fhi72.4x4-benetel550_c0.conf --thread-pool 21,22,23,24,25,26,27,28 Results: iperf UDP uplink [ 5] 0.00-10.22 sec 87.3 MBytes 71.6 Mbits/sec 0.100 ms 370/63081 (0.59%) receiver iperf UDP downlink [ 5] 0.00-10.00 sec 796 MBytes 668 Mbits/sec 0.017 ms 1824/586404 (0.31%) receiver b. Command to test LiteOn FR2 RU sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf--thread-pool 21,22,23,24,25,26,27,28 Result: iperf UDP uplink [ 5] 0.00-10.20 sec 89.9 MBytes 73.9 Mbits/sec 0.156 ms 212/64848 (0.33%) receiver iperf UDP downlink [ 5] 0.00-10.00 sec 361 MBytes 303 Mbits/sec 0.077 ms 277662/542891 (51%) receiver D. Difference between LiteOn FR2 E release configuration file and that for F release is diff gnb.sa.band78.66prb.fhi72.2x2-liteon-KB.conf gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf 39d38 < beam_weights = [1, 1]; 225a225 > beam_weights = [1]; 312c312,313 < mtu = 1500; # check if xran uses this properly --- > #mtu = 1500; # check if xran uses this properly > mtu = 9000; # check if xran uses this properly 313a315,316 > RunSlotPrbMapBySymbol = 1; > LiteOnIgnoreUPSectionId = 1;
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h
|
||||
index ac5f471..b0f7ed1 100644
|
||||
index ac5f471..94c2d7c 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..b0f7ed1 100644
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
-#define VERSIONX "oran_f_release_v1.0"
|
||||
+#define VERSIONX "oran_f_release_v1.5"
|
||||
+#define VERSIONX "oran_f_release_v1.6"
|
||||
|
||||
#define APP_O_DU 0
|
||||
#define APP_O_RU 1
|
||||
@@ -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..1b88013 100644
|
||||
--- a/fhi_lib/lib/src/xran_common.c
|
||||
+++ b/fhi_lib/lib/src/xran_common.c
|
||||
@@ -31,7 +31,10 @@
|
||||
@@ -549,7 +559,110 @@ 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,30 @@ 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[i];
|
||||
+ } else {
|
||||
+ 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
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
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 +566,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 +637,30 @@ 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[i];
|
||||
+ } else {
|
||||
+ 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
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
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 +669,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 +753,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 +677,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 +775,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 +689,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 +823,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
|
||||
else
|
||||
{
|
||||
@@ -590,7 +703,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 +848,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
PrachCfg = &(p_dev_ctx->PrachCPConfig);
|
||||
}
|
||||
|
||||
@@ -600,7 +713,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 +1452,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 +722,7 @@ index dc40ad9..5968d01 100644
|
||||
timeOffset += 16;
|
||||
}
|
||||
else
|
||||
@@ -1547,8 +1551,7 @@ int32_t ring_processing_func(void* args)
|
||||
@@ -1547,8 +1587,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 +1031,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..7c7cf91 100644
|
||||
--- a/fhi_lib/lib/src/xran_main.c
|
||||
+++ b/fhi_lib/lib/src/xran_main.c
|
||||
@@ -35,7 +35,11 @@
|
||||
@@ -974,7 +1137,7 @@ index 7c472d7..9da3621 100644
|
||||
|
||||
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
|
||||
+ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList);
|
||||
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
|
||||
+ struct xran_prb_map *prbMap = (struct xran_prb_map *)pBufList->pBuffers->pData;
|
||||
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
|
||||
+ beam_id = pPrbElm->nBeamIndex;
|
||||
ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx,
|
||||
@@ -985,7 +1148,7 @@ index 7c472d7..9da3621 100644
|
||||
|
||||
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
|
||||
+ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList);
|
||||
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
|
||||
+ struct xran_prb_map *prbMap = (struct xran_prb_map *)pBufList->pBuffers->pData;
|
||||
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
|
||||
+ beam_id = pPrbElm->nBeamIndex;
|
||||
ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx,
|
||||
@@ -1550,7 +1713,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 +1746,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 +1846,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..34b6d3b 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 +1861,127 @@ index e7056f4..0d3d8ac 100644
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_eal.h>
|
||||
@@ -339,13 +343,33 @@ 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 */
|
||||
+ 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
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
+ 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 +421,25 @@ 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 {
|
||||
+ 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
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
+ 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 +579,33 @@ 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 */
|
||||
+ 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
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
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 +614,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 +658,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
|
||||
|
||||
@@ -17,7 +17,7 @@ add_library(oran_fhlib_5g MODULE
|
||||
)
|
||||
|
||||
set(E_VERSION 5.1.6)
|
||||
set(F_VERSION 6.1.5)
|
||||
set(F_VERSION 6.1.6)
|
||||
|
||||
find_package(xran REQUIRED)
|
||||
if(xran_VERSION VERSION_EQUAL E_VERSION)
|
||||
|
||||
@@ -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>
|
||||
@@ -265,6 +266,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)
|
||||
@@ -678,3 +701,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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -754,7 +756,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;
|
||||
|
||||
@@ -791,6 +794,9 @@ 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;
|
||||
if (liteon_prach_eAxC_offset)
|
||||
prach_config->eAxC_offset = offset;
|
||||
else
|
||||
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
|
||||
#endif
|
||||
|
||||
@@ -937,9 +943,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
|
||||
@@ -951,7 +962,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 */
|
||||
@@ -983,8 +994,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
|
||||
|
||||
@@ -333,6 +333,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);
|
||||
@@ -357,8 +358,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 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);
|
||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||
}
|
||||
#endif
|
||||
|
||||
// PDSCH
|
||||
|
||||
@@ -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,6 +106,8 @@
|
||||
|
||||
// clang-format off
|
||||
#define ORAN_FH_DESC { \
|
||||
{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}, \
|
||||
|
||||
@@ -228,7 +228,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) {
|
||||
@@ -283,7 +288,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");
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user