Commit 574b3eb3 authored by Teodora's avatar Teodora

Fronthaul xran library F release support

Major improvements:
  1) bbu_offload - enable packet handling on BBU cores
  2) dlCpProcBurst - DL CP processing on one or more symbols
  3) SRS CP processing - depends on the RU capabilities that can be
    retreived via M-plane (if RU is CAT B)
  4) nSecDesc - the number of section descriptors per symbol; it was hardcoded to 0 in E release;
    depends on the RU capabilities that can be retreived via M-plane
  5) RunSlotPrbMapBySymbolEnable - enable PRB mapping by symbol with multisection;
    depends on the RU capabilities that can be retreived via M-plane
  6) DSS (Dynamic Spectrum Sharing) support - depends on the RU capabilities that can be retreived via M-plane

Minor fixes in F that exist in E:
  1) prach_config->nPrachFilterIdx - explained in commit ID f3045396
  2) T1a_min_cp_dl - explained in the commit under title "Clarification on DU delay profile"
  3) fh_config->nULRBs - explained in commit under title "Further clarification on xran E release parameters"

Removed const for prb_conf argument in oran_allocate_cplane_buffers()
function, as F release requires the not const struct for
xran_init_PrbMap_by_symbol_from_cfg() and xran_init_PrbMap_from_cfg()
even though the struct is not modified inside of these functions.
parent 197db6a6
......@@ -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})
......
......@@ -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);
......
......@@ -120,6 +120,11 @@ static void print_fh_init_io_cfg(const struct xran_io_cfg *io_cfg)
io_cfg->one_vf_cu_plane);
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)
......@@ -179,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)
......@@ -215,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)
......@@ -374,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);
......@@ -398,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)
......@@ -477,6 +513,10 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in
/* 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;
}
......@@ -594,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;
}
......@@ -631,6 +677,9 @@ 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];
......@@ -779,6 +828,10 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
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
......@@ -820,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;
}
......
......@@ -140,10 +140,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 +217,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 +261,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 +291,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 +316,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 +326,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 +351,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 +389,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 +458,11 @@ 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
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment