Merge remote-tracking branch 'origin/fhi-f-release' into integration_2024_w49 (!3147)
Fronthaul xran library update to F release (2. and final step towards M-plane integration) - xran library support -> both E and F releases - RU delay profile removed -> not used in neither of the releases - DU delay profile updated - one-way delay measurements support is improved/fixed in the F release. However, not implemented here as it depends on the RU capabilities
This commit is contained in:
@@ -9,12 +9,6 @@ endif()
|
||||
pkg_check_modules(dpdk REQUIRED libdpdk)
|
||||
pkg_check_modules(numa REQUIRED numa)
|
||||
|
||||
find_package(xran 5.1.4 EXACT REQUIRED) # E release -> 5
|
||||
|
||||
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
|
||||
# alignment 1 of 'struct XYZ' is less than 2
|
||||
add_compile_options(-Wno-packed-not-aligned)
|
||||
|
||||
add_library(oran_fhlib_5g MODULE
|
||||
oran_isolate.c
|
||||
oaioran.c
|
||||
@@ -22,6 +16,19 @@ add_library(oran_fhlib_5g MODULE
|
||||
oran-init.c
|
||||
)
|
||||
|
||||
find_package(xran REQUIRED)
|
||||
if(xran_VERSION VERSION_EQUAL 5.1.4)
|
||||
target_compile_definitions(oran_fhlib_5g PRIVATE E_RELEASE)
|
||||
elseif(xran_VERSION VERSION_EQUAL 6.1.1)
|
||||
target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE)
|
||||
else()
|
||||
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.4 (E release) or 6.1.1 (F release)")
|
||||
endif()
|
||||
|
||||
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
|
||||
# alignment 1 of 'struct XYZ' is less than 2
|
||||
add_compile_options(-Wno-packed-not-aligned)
|
||||
|
||||
set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native")
|
||||
target_link_libraries(oran_fhlib_5g PRIVATE xran::xran)
|
||||
target_link_libraries(oran_fhlib_5g PRIVATE ${dpdk_LINK_LIBRARIES})
|
||||
|
||||
+28
-5
@@ -90,7 +90,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
|
||||
|
||||
tti = xran_get_slot_idx_from_tti(rx_tti, &frame, &subframe, &slot, &second);
|
||||
|
||||
rx_sym = callback_tag->symbol;
|
||||
rx_sym = callback_tag->symbol & 0xFF;
|
||||
uint32_t ru_id = callback_tag->oXuId;
|
||||
|
||||
LOG_D(NR_PHY,
|
||||
@@ -101,7 +101,23 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
|
||||
(unsigned long long)second,
|
||||
rx_sym,
|
||||
ru_id);
|
||||
if (rx_sym == 7) {
|
||||
if (rx_sym == 7) { // in F release this value is defined as XRAN_FULL_CB_SYM (full slot (offset + 7))
|
||||
#ifdef F_RELEASE
|
||||
int32_t nCellIdx = callback_tag->cellId;
|
||||
int32_t ntti = (rx_tti + XRAN_N_FE_BUF_LEN - 1) % XRAN_N_FE_BUF_LEN;
|
||||
|
||||
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
|
||||
struct xran_prb_map *pRbMap = (struct xran_prb_map *)xran_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[ntti][nCellIdx][ant_id].sBufferList.pBuffers->pData;
|
||||
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", nCellIdx, ntti, ant_id);
|
||||
|
||||
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
|
||||
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>
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (first_call_set) {
|
||||
if (!first_rx_set) {
|
||||
LOG_I(NR_PHY, "first_rx is set (num_ports %d), first_read_set %d\n", num_ports, first_read_set);
|
||||
@@ -332,7 +348,11 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
|
||||
|
||||
struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0];
|
||||
#ifdef E_RELEASE
|
||||
struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[sym_idx][0];
|
||||
#elif defined F_RELEASE
|
||||
struct xran_section_desc *p_sec_desc = &pRbElm->sec_desc[sym_idx][0];
|
||||
#endif
|
||||
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)
|
||||
@@ -486,9 +506,12 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
|
||||
struct xran_section_desc *p_sec_desc = NULL;
|
||||
p_prbMapElm = &pRbMap->prbMap[idxElm];
|
||||
p_sec_desc =
|
||||
// assumes one fragment per symbol
|
||||
p_prbMapElm->p_sec_desc[sym_id][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);
|
||||
|
||||
|
||||
+101
-93
@@ -59,55 +59,6 @@ static void print_fh_eowd_cmn(unsigned index, const struct xran_ecpri_del_meas_c
|
||||
eowd_cmn->owdm_PlLength);
|
||||
}
|
||||
|
||||
static void print_fh_eowd_port(unsigned index, unsigned vf, const struct xran_ecpri_del_meas_port *eowd_port)
|
||||
{
|
||||
printf("\
|
||||
eowd_port[%u][%u]:\n\
|
||||
t1 %ld\n\
|
||||
t2 %ld\n\
|
||||
tr %ld\n\
|
||||
delta %ld\n\
|
||||
portid %d\n\
|
||||
runMeas %d\n\
|
||||
currentMeasID %d\n\
|
||||
msState %d\n\
|
||||
numMeas %d\n\
|
||||
txDone %d\n\
|
||||
rspTimerIdx %ld\n\
|
||||
delaySamples [%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld]\n\
|
||||
delayAvg %ld\n",
|
||||
index,
|
||||
vf,
|
||||
eowd_port->t1,
|
||||
eowd_port->t2,
|
||||
eowd_port->tr,
|
||||
eowd_port->delta,
|
||||
eowd_port->portid,
|
||||
eowd_port->runMeas,
|
||||
eowd_port->currentMeasID,
|
||||
eowd_port->msState,
|
||||
eowd_port->numMeas,
|
||||
eowd_port->txDone,
|
||||
eowd_port->rspTimerIdx,
|
||||
eowd_port->delaySamples[0],
|
||||
eowd_port->delaySamples[1],
|
||||
eowd_port->delaySamples[2],
|
||||
eowd_port->delaySamples[3],
|
||||
eowd_port->delaySamples[4],
|
||||
eowd_port->delaySamples[5],
|
||||
eowd_port->delaySamples[6],
|
||||
eowd_port->delaySamples[7],
|
||||
eowd_port->delaySamples[8],
|
||||
eowd_port->delaySamples[9],
|
||||
eowd_port->delaySamples[10],
|
||||
eowd_port->delaySamples[11],
|
||||
eowd_port->delaySamples[12],
|
||||
eowd_port->delaySamples[13],
|
||||
eowd_port->delaySamples[14],
|
||||
eowd_port->delaySamples[15],
|
||||
eowd_port->delayAvg);
|
||||
}
|
||||
|
||||
static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
|
||||
{
|
||||
printf("\
|
||||
@@ -152,7 +103,7 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
|
||||
pkt_proc_core_64_127 %016lx\n\
|
||||
pkt_aux_core %d\n\
|
||||
timing_core %d\n\
|
||||
port [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ]\n\
|
||||
port (filled within xran library)\n\
|
||||
io_sleep %d\n\
|
||||
nEthLinePerPort %d\n\
|
||||
nEthLineSpeed %d\n\
|
||||
@@ -163,31 +114,17 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
|
||||
io_cfg->pkt_proc_core_64_127,
|
||||
io_cfg->pkt_aux_core,
|
||||
io_cfg->timing_core,
|
||||
io_cfg->port[XRAN_UP_VF],
|
||||
io_cfg->port[XRAN_CP_VF],
|
||||
io_cfg->port[XRAN_UP_VF1],
|
||||
io_cfg->port[XRAN_CP_VF1],
|
||||
io_cfg->port[XRAN_UP_VF2],
|
||||
io_cfg->port[XRAN_CP_VF2],
|
||||
io_cfg->port[XRAN_UP_VF3],
|
||||
io_cfg->port[XRAN_CP_VF3],
|
||||
io_cfg->port[XRAN_UP_VF4],
|
||||
io_cfg->port[XRAN_CP_VF4],
|
||||
io_cfg->port[XRAN_UP_VF5],
|
||||
io_cfg->port[XRAN_CP_VF5],
|
||||
io_cfg->port[XRAN_UP_VF6],
|
||||
io_cfg->port[XRAN_CP_VF6],
|
||||
io_cfg->port[XRAN_UP_VF7],
|
||||
io_cfg->port[XRAN_CP_VF7],
|
||||
io_cfg->io_sleep,
|
||||
io_cfg->nEthLinePerPort,
|
||||
io_cfg->nEthLineSpeed,
|
||||
io_cfg->one_vf_cu_plane);
|
||||
print_fh_eowd_cmn(0, &io_cfg->eowd_cmn[0]);
|
||||
print_fh_eowd_cmn(1, &io_cfg->eowd_cmn[1]);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
for (int v = 0; v < io_cfg->num_vfs; ++v)
|
||||
print_fh_eowd_port(i, v, &io_cfg->eowd_port[i][v]);
|
||||
print_fh_eowd_cmn(io_cfg->id, &io_cfg->eowd_cmn[io_cfg->id]);
|
||||
printf("eowd_port (filled within xran library)\n");
|
||||
#ifdef F_RELEASE
|
||||
printf("\
|
||||
bbu_offload %d\n",
|
||||
io_cfg->bbu_offload);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_fh_init_eaxcid_conf(const struct xran_eaxcid_config *eaxcid_conf)
|
||||
@@ -247,6 +184,13 @@ void print_fh_init(const struct xran_fh_init *fh_init)
|
||||
printf("\
|
||||
totalBfWeights %d\n",
|
||||
fh_init->totalBfWeights);
|
||||
#ifdef F_RELEASE
|
||||
printf("\
|
||||
mlogxranenable %d\n\
|
||||
dlCpProcBurst %d\n",
|
||||
fh_init->mlogxranenable,
|
||||
fh_init->dlCpProcBurst);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_prach_config(const struct xran_prach_config *prach_conf)
|
||||
@@ -283,6 +227,11 @@ static void print_prach_config(const struct xran_prach_config *prach_conf)
|
||||
prach_conf->timeOffset,
|
||||
prach_conf->freqOffset,
|
||||
prach_conf->eAxC_offset);
|
||||
#ifdef F_RELEASE
|
||||
printf("\
|
||||
nPrachConfIdxLTE %d\n",
|
||||
prach_conf->nPrachConfIdxLTE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_srs_config(const struct xran_srs_config *srs_conf)
|
||||
@@ -442,6 +391,14 @@ void print_fh_config(const struct xran_fh_config *fh_config)
|
||||
fh_config->GPS_Alpha,
|
||||
fh_config->GPS_Beta);
|
||||
|
||||
#ifdef F_RELEASE
|
||||
printf("\
|
||||
srsEnableCp %d\n\
|
||||
SrsDelaySym %d\n",
|
||||
fh_config->srsEnableCp,
|
||||
fh_config->SrsDelaySym);
|
||||
#endif
|
||||
|
||||
print_prach_config(&fh_config->prach_conf);
|
||||
print_srs_config(&fh_config->srs_conf);
|
||||
print_frame_config(&fh_config->frame_conf);
|
||||
@@ -466,6 +423,17 @@ void print_fh_config(const struct xran_fh_config *fh_config)
|
||||
fh_config->log_level,
|
||||
fh_config->max_sections_per_slot,
|
||||
fh_config->max_sections_per_symbol);
|
||||
|
||||
#ifdef F_RELEASE
|
||||
printf("\
|
||||
RunSlotPrbMapBySymbolEnable %d\n\
|
||||
dssEnable %d\n\
|
||||
dssPeriod %d\n\
|
||||
technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n",
|
||||
fh_config->RunSlotPrbMapBySymbolEnable,
|
||||
fh_config->dssEnable,
|
||||
fh_config->dssPeriod);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const paramdef_t *gpd(const paramdef_t *pd, int num, const char *name)
|
||||
@@ -522,9 +490,32 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in
|
||||
io_cfg->nEthLineSpeed = *gpd(fhip, nump, ORAN_CONFIG_NETHSPEED)->uptr; // 10G,25G,40G,100G speed of Physical connection on O-RU
|
||||
io_cfg->one_vf_cu_plane = (io_cfg->num_vfs == num_rus); // C-plane and U-plane use one VF
|
||||
|
||||
/* use owdm to calculate T12 and T34 -> CUS specification, section 2.3.3.3 */
|
||||
// io_cfg->eowd_cmn[2] // ecpri one-way delay measurements common settings for O-DU and O-RU
|
||||
// io_cfg->eowd_port[2][XRAN_VF_MAX] // ecpri owd measurements per port variables for O-DU and O-RU
|
||||
/* eCPRI One-Way Delay Measurements common settings for O-DU and O-RU;
|
||||
use owdm to calculate T12 and T34 -> CUS specification, section 2.3.3.3;
|
||||
this is an optional feature that RU might or might not support;
|
||||
to verify if RU supports, please check in the official RU documentation or
|
||||
via M-plane the o-ran-ecpri-delay@<version>.yang capability;
|
||||
this functionality is improved in F release */
|
||||
/* if RU does support, io_cfg->eowd_cmn[0] should only be filled as id = O_DU; io_cfg->eowd_cmn[1] only used if id = O_RU */
|
||||
const uint16_t owdm_enable = *gpd(fhip, nump, ORAN_CONFIG_ECPRI_OWDM)->uptr;
|
||||
if (owdm_enable) {
|
||||
io_cfg->eowd_cmn[0].initiator_en = 1; // 1 -> initiator (always O-DU), 0 -> recipient (always O-RU)
|
||||
io_cfg->eowd_cmn[0].numberOfSamples = 8; // total number of samples to be collected and averaged per port
|
||||
io_cfg->eowd_cmn[0].filterType = 0; // 0 -> simple average based on number of measurements; not used in xran in both E and F releases
|
||||
io_cfg->eowd_cmn[0].responseTo = 10000000; // response timeout in [ns]
|
||||
io_cfg->eowd_cmn[0].measVf = 0; // VF using the OWD transmitter; within xran, the measurements are calculated per each supported VF, but starts from measVf
|
||||
io_cfg->eowd_cmn[0].measState = 0; // the state of the OWD transmitter; 0 -> OWDMTX_INIT (enum xran_owdm_tx_state)
|
||||
io_cfg->eowd_cmn[0].measId = 0; // measurement ID to be used by the transmitter
|
||||
io_cfg->eowd_cmn[0].measMethod = 0; // measurement method; 0 -> XRAN_REQUEST (enum xran_owd_meas_method)
|
||||
io_cfg->eowd_cmn[0].owdm_enable = 1; // 1 -> enabled; 0 -> disabled
|
||||
io_cfg->eowd_cmn[0].owdm_PlLength = 40; // payload in the measurement packet; 40 <= PlLength <= 1400
|
||||
}
|
||||
/* eCPRI OWDM per port variables for O-DU; this parameter is filled within xran library */
|
||||
// eowd_port[0][XRAN_VF_MAX]
|
||||
|
||||
#ifdef F_RELEASE
|
||||
io_cfg->bbu_offload = 0; // enable packet handling on BBU cores
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -620,7 +611,7 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
|
||||
fh_init->dpdkBasebandFecMode = 0; // DPDK Baseband FEC device mode (0-SW, 1-HW); not used in xran
|
||||
fh_init->dpdkBasebandDevice = NULL; // DPDK Baseband device address; not used in xran
|
||||
/* used to specify a unique prefix for shared memory, and files created by multiple DPDK processes;
|
||||
is it necessary */
|
||||
it is necessary */
|
||||
fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr);
|
||||
/* maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be
|
||||
communicated in a single xRAN network layer transaction. Supported 1500 bytes and 9600 bytes (Jumbo Frame);
|
||||
@@ -643,6 +634,12 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca
|
||||
|
||||
fh_init->totalBfWeights = 0; // only used if id = O_RU (for emulation); C-plane extension types; section 5.4.6 of CUS spec
|
||||
|
||||
#ifdef F_RELEASE
|
||||
fh_init->mlogxranenable = 0; // enable mlog; 0 -> disabled
|
||||
fh_init->dlCpProcBurst = 0; /* 1 -> DL CP processing will be done on single symbol,
|
||||
0 -> DL CP processing will be spread across all allowed symbols and multiple cores to reduce burstiness */
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -680,10 +677,15 @@ static bool set_fh_prach_config(const openair0_config_t *oai0,
|
||||
prach_config->numPrbc = 0;
|
||||
prach_config->timeOffset = 0;
|
||||
prach_config->freqOffset = 0;
|
||||
#ifdef F_RELEASE
|
||||
prach_config->nPrachConfIdxLTE = 0; // used only if DSS enabled and technology is XRAN_RAN_LTE
|
||||
#endif
|
||||
|
||||
/* xran defines PDSCH eAxC IDs as [0...Ntx-1];
|
||||
xran defines PUSCH eAxC IDs as [0...Nrx-1];
|
||||
PRACH offset must be >= max(Ntx, Nrx) */
|
||||
xran assumes PRACH offset >= max(Ntx, Nrx). However, we made a workaround that xran supports PRACH eAxC IDs same as PUSCH eAxC IDs.
|
||||
This is achieved with is_prach and filter_id parameters in the patch.
|
||||
Please note that this approach only applies to the RUs that support this functionality, e.g. LITEON RU. */
|
||||
uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
|
||||
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
|
||||
|
||||
@@ -804,41 +806,39 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
|
||||
fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B
|
||||
fh_config->nDLFftSize = 0; // DL FFT size; not used in xran
|
||||
fh_config->nULFftSize = 0; // UL FFT size; not used in xran
|
||||
fh_config->nDLRBs = oai0->num_rb_dl; // DL PRB
|
||||
fh_config->nULRBs = oai0->num_rb_dl; // UL PRB; in xran not used as id = O_DU, but used in oaioran.c/oran-init.c
|
||||
fh_config->nDLRBs = oai0->num_rb_dl; // DL PRB; used in oaioran.c/oran-init.c; not used in xran, neither in E nor in F release
|
||||
fh_config->nULRBs = oai0->num_rb_dl; // UL PRB; used in oaioran.c/oran-init.c; in xran E release not used so the patch fixes it, but in xran F release this value is properly used
|
||||
fh_config->nDLAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
|
||||
fh_config->nULAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
|
||||
fh_config->nDLCenterFreqARFCN = 0; // center frequency for DL in NR-ARFCN; not used in xran
|
||||
fh_config->nULCenterFreqARFCN = 0; // center frequency for UL in NR-ARFCN; not used in xran
|
||||
fh_config->ttiCb = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
|
||||
fh_config->ttiCbParam = NULL; // check tti_to_phy_cb(), tx_cp_dl_cb() and tx_cp_ul_cb => first_call
|
||||
fh_config->Tadv_cp_dl = *gpd(fhp, nfh, ORAN_FH_CONFIG_TADV_CP_DL)->uptr; // not used in xran
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_CP_DL, &fh_config->T2a_min_cp_dl, &fh_config->T2a_max_cp_dl)) // not used in xran
|
||||
|
||||
/* DU delay profile */
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &fh_config->T1a_min_cp_dl, &fh_config->T1a_max_cp_dl)) // E - min not used in xran, max yes; F - both min and max are used in xran
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_CP_UL, &fh_config->T2a_min_cp_ul, &fh_config->T2a_max_cp_ul)) // not used in xran
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_UL, &fh_config->T1a_min_cp_ul, &fh_config->T1a_max_cp_ul)) // both E and F - min not used in xran, max yes
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T2A_UP, &fh_config->T2a_min_up, &fh_config->T2a_max_up)) // not used in xran
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_UP, &fh_config->T1a_min_up, &fh_config->T1a_max_up)) // both E and F - min not used in xran, max yes
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA3, &fh_config->Ta3_min, &fh_config->Ta3_max)) // not used in xran
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_DL, &fh_config->T1a_min_cp_dl, &fh_config->T1a_max_cp_dl))
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_CP_UL, &fh_config->T1a_min_cp_ul, &fh_config->T1a_max_cp_ul))
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_T1A_UP, &fh_config->T1a_min_up, &fh_config->T1a_max_up))
|
||||
return false;
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &fh_config->Ta4_min, &fh_config->Ta4_max))
|
||||
if (!set_maxmin_pd(fhp, nfh, ORAN_FH_CONFIG_TA4, &fh_config->Ta4_min, &fh_config->Ta4_max)) // both E and F - min not used in xran, max yes
|
||||
return false;
|
||||
|
||||
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
|
||||
#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
|
||||
#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
|
||||
fh_config->cp_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_CP_VLAN_TAG)->uptr; // C-plane VLAN tag; not used in xran; needed for M-plane
|
||||
fh_config->up_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_UP_VLAN_TAG)->uptr; // U-plane VLAN tag; not used in xran; needed for M-plane
|
||||
fh_config->debugStop = 0; // enable auto stop; not used in xran
|
||||
fh_config->debugStop = 0; // enable auto stop; only used if id = O_RU
|
||||
fh_config->debugStopCount = 0; // enable auto stop after number of Tx packets; not used in xran
|
||||
fh_config->DynamicSectionEna = 0; // enable dynamic C-Plane section allocation; not used in xran
|
||||
fh_config->DynamicSectionEna = 0; // enable dynamic C-Plane section allocation
|
||||
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
|
||||
|
||||
@@ -873,6 +873,14 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
|
||||
fh_config->max_sections_per_slot = 0; // not used in xran
|
||||
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
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+56
-14
@@ -29,6 +29,7 @@
|
||||
#include "oaioran.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common_lib.h"
|
||||
|
||||
/* PRACH data samples are 32 bits wide (16bits for I/Q). Each packet contains
|
||||
@@ -140,10 +141,10 @@ static uint32_t oran_allocate_uplane_buffers(
|
||||
{
|
||||
xran_status_t status;
|
||||
uint32_t pool;
|
||||
// we need at least XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT
|
||||
// buffers, but xran_bm_init() uses rte_pktmbuf_pool_create() which
|
||||
// recommends to use a power of two for the buffers
|
||||
uint32_t numBufs = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT);
|
||||
/* xran_bm_init() uses rte_pktmbuf_pool_create() which recommends to use a power of two for the buffers;
|
||||
the E release sample app didn't take this into account, but we introduced it ourselves;
|
||||
the F release sample app took this into account, so we can proudly say we assumed correctly */
|
||||
uint32_t numBufs = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT) - 1;
|
||||
status = xran_bm_init(instHandle, &pool, numBufs, bufSize);
|
||||
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
|
||||
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, pool, numBufs, bufSize);
|
||||
@@ -217,26 +218,33 @@ static void oran_allocate_cplane_buffers(void *instHandle,
|
||||
struct xran_flat_buffer buf[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
|
||||
uint32_t ant,
|
||||
uint32_t sect,
|
||||
#ifdef F_RELEASE
|
||||
uint32_t mtu,
|
||||
const struct xran_fh_config *fh_config,
|
||||
#endif
|
||||
uint32_t size_of_prb_map,
|
||||
const oran_cplane_prb_config *prb_conf)
|
||||
oran_cplane_prb_config *prb_conf)
|
||||
{
|
||||
xran_status_t status;
|
||||
uint32_t count1 = 0;
|
||||
|
||||
#ifdef E_RELEASE
|
||||
uint32_t count2 = 0;
|
||||
uint32_t poolSec;
|
||||
uint32_t numBufsSec = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT * sect * XRAN_MAX_FRAGMENT);
|
||||
uint32_t bufSizeSec = sizeof(struct xran_section_desc);
|
||||
status = xran_bm_init(instHandle, &poolSec, numBufsSec, bufSizeSec);
|
||||
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
|
||||
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolSec, numBufsSec, bufSizeSec);
|
||||
#endif
|
||||
|
||||
uint32_t poolPrb;
|
||||
uint32_t numBufsPrb = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT);
|
||||
uint32_t numBufsPrb = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT) - 1;
|
||||
uint32_t bufSizePrb = size_of_prb_map;
|
||||
status = xran_bm_init(instHandle, &poolPrb, numBufsPrb, bufSizePrb);
|
||||
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
|
||||
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolPrb, numBufsPrb, bufSizePrb);
|
||||
|
||||
uint32_t count1 = 0;
|
||||
uint32_t count2 = 0;
|
||||
for (uint32_t a = 0; a < ant; a++) {
|
||||
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
|
||||
list[a][j].pBuffers = &buf[a][j];
|
||||
@@ -254,13 +262,15 @@ static void oran_allocate_cplane_buffers(void *instHandle,
|
||||
fb->pData = ptr;
|
||||
fb->pCtrl = mb;
|
||||
|
||||
// the original sample app code copies up to size_of_prb_map, but I think
|
||||
// this is wrong because the way it is computed leads to a number larger
|
||||
// than sizeof(map)
|
||||
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
|
||||
const struct xran_prb_map *src = &prb_conf->slotMap;
|
||||
struct xran_prb_map *src = &prb_conf->slotMap;
|
||||
if ((j % prb_conf->nTddPeriod) == prb_conf->mixed_slot_index)
|
||||
src = &prb_conf->mixedSlotMap;
|
||||
#ifdef E_RELEASE
|
||||
/* as per E release sample app, the memory is copied up to size_of_prb_map
|
||||
which translates to >= sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm)*5,
|
||||
but we assume that RB allocation is done as 1 RE/UE so the total memory size is sizeof(struct xran_prb_map);
|
||||
this is improved in F release */
|
||||
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
|
||||
memcpy(p_rb_map, src, sizeof(*src));
|
||||
|
||||
for (uint32_t elm_id = 0; elm_id < p_rb_map->nPrbElm; ++elm_id) {
|
||||
@@ -282,10 +292,19 @@ static void oran_allocate_cplane_buffers(void *instHandle,
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined F_RELEASE
|
||||
if (fh_config->RunSlotPrbMapBySymbolEnable) {
|
||||
xran_init_PrbMap_by_symbol_from_cfg(src, ptr, mtu, fh_config->nDLRBs);
|
||||
} else {
|
||||
xran_init_PrbMap_from_cfg(src, ptr, mtu);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %u\n", instHandle, poolPrb, count1);
|
||||
#ifdef E_RELEASE
|
||||
printf("xran_bm_allocate_buffer() hInstance %p poolIdx %u count %u\n", instHandle, poolSec, count2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* callback not actively used */
|
||||
@@ -298,6 +317,9 @@ static void oran_allocate_buffers(void *handle,
|
||||
int xran_inst,
|
||||
int num_sectors,
|
||||
oran_port_instance_t *portInstances,
|
||||
#ifdef F_RELEASE
|
||||
uint32_t mtu,
|
||||
#endif
|
||||
const struct xran_fh_config *fh_config)
|
||||
{
|
||||
AssertFatal(num_sectors == 1, "only support one sector at the moment\n");
|
||||
@@ -305,7 +327,6 @@ static void oran_allocate_buffers(void *handle,
|
||||
AssertFatal(handle != NULL, "no handle provided\n");
|
||||
uint32_t xran_max_antenna_nr = RTE_MAX(fh_config->neAxc, fh_config->neAxcUl);
|
||||
uint32_t xran_max_sections_per_slot = RTE_MAX(fh_config->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT);
|
||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
|
||||
|
||||
pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256);
|
||||
AssertFatal(pi->buf_list != NULL, "out of memory\n");
|
||||
@@ -331,11 +352,23 @@ static void oran_allocate_buffers(void *handle,
|
||||
.slotMap = dlPm,
|
||||
.mixedSlotMap = dlPmMixed,
|
||||
};
|
||||
|
||||
#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(&dlPmMixed, mtu);
|
||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||
#endif
|
||||
|
||||
oran_allocate_cplane_buffers(pi->instanceHandle,
|
||||
bl->srccp,
|
||||
bl->bufs.tx_prbmap,
|
||||
xran_max_antenna_nr,
|
||||
xran_max_sections_per_slot,
|
||||
#ifdef F_RELEASE
|
||||
mtu,
|
||||
fh_config,
|
||||
#endif
|
||||
size_of_prb_map,
|
||||
&dlConf);
|
||||
|
||||
@@ -357,6 +390,10 @@ static void oran_allocate_buffers(void *handle,
|
||||
bl->bufs.rx_prbmap,
|
||||
xran_max_antenna_nr,
|
||||
xran_max_sections_per_slot,
|
||||
#ifdef F_RELEASE
|
||||
mtu,
|
||||
fh_config,
|
||||
#endif
|
||||
size_of_prb_map,
|
||||
&ulConf);
|
||||
|
||||
@@ -422,7 +459,12 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi
|
||||
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
|
||||
pi->prach_tag = tag;
|
||||
pi->pusch_tag = tag;
|
||||
#ifdef E_RELEASE
|
||||
LOG_W(PHY, "Please be aware that E release support will be removed by the end of January 2025. Instead, F release will be mandatory.\n");
|
||||
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, &xran_fh_config[o_xu_id]);
|
||||
#elif defined F_RELEASE
|
||||
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
|
||||
#endif
|
||||
|
||||
if ((xret = xran_reg_physide_cb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
|
||||
printf("xran_reg_physide_cb failed %d\n", xret);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define ORAN_CONFIG_NETHPERPORT "eth_lines"
|
||||
#define ORAN_CONFIG_NETHSPEED "eth_speed"
|
||||
#define ORAN_CONFIG_DPDK_MEM_SIZE "dpdk_mem_size"
|
||||
#define ORAN_CONFIG_ECPRI_OWDM "owdm_enable"
|
||||
|
||||
// clang-format off
|
||||
// TODO: PCI addr check
|
||||
@@ -52,16 +53,12 @@
|
||||
{ORAN_CONFIG_NETHPERPORT, "number of links per port\n", 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0}, \
|
||||
{ORAN_CONFIG_NETHSPEED, "ethernet speed link\n", 0, .uptr=NULL, .defuintval=10, TYPE_UINT, 0}, \
|
||||
{ORAN_CONFIG_DPDK_MEM_SIZE, "DPDK huge page pre-allocation in MiB\n", 0, .uptr=NULL, .defuintval=8192, TYPE_UINT, 0}, \
|
||||
{ORAN_CONFIG_ECPRI_OWDM, "eCPRI One-Way Delay Measurements\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#define CONFIG_STRING_ORAN_FH "fh_config"
|
||||
|
||||
#define ORAN_FH_CONFIG_TADV_CP_DL "Tadv_cp_dl"
|
||||
#define ORAN_FH_CONFIG_T2A_CP_DL "T2a_cp_dl"
|
||||
#define ORAN_FH_CONFIG_T2A_CP_UL "T2a_cp_ul"
|
||||
#define ORAN_FH_CONFIG_T2A_UP "T2a_up"
|
||||
#define ORAN_FH_CONFIG_TA3 "Ta3"
|
||||
#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"
|
||||
@@ -73,11 +70,6 @@
|
||||
|
||||
// clang-format off
|
||||
#define ORAN_FH_DESC { \
|
||||
{ORAN_FH_CONFIG_TADV_CP_DL, "Tadv parameter of RU\n", PARAMFLAG_MANDATORY, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
|
||||
{ORAN_FH_CONFIG_T2A_CP_DL, "T2a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
{ORAN_FH_CONFIG_T2A_CP_UL, "T2a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
{ORAN_FH_CONFIG_T2A_UP, "T2a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
{ORAN_FH_CONFIG_TA3, "Ta3" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 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}, \
|
||||
|
||||
Reference in New Issue
Block a user